charm_shc#

Module to work with spherical harmonic coefficients:

  • defines the charm_shc structure to store spherical harmonic coefficients,

  • allocates, initializes and frees charm_shc,

  • reads/writes spherical harmonic coefficients from/to text and binary files,

  • computes (difference) degree variances and degree amplitudes.

  • rescales spherical harmonic coefficients,

Note

This documentation is written for double precision version of CHarm.

Special values for functions to read spherical harmonic coefficients

The values are used with charm_shc_read_dov(), charm_shc_read_gfc(), charm_shc_read_tbl(), charm_shc_read_mtx() and charm_shc_read_dov().

CHARM_SHC_NMAX_MODEL (ULONG_MAX - 1)#

Special value of the nmax input parameter to all functions that read spherical harmonic coefficients. If nmax is CHARM_SHC_NMAX_MODEL and shcs is NULL, the functions return the maximum harmonic degree found inside the file and do not read the rest of the file (see the documentation to charm_shc_read_* functions). The value is platform-dependent.

CHARM_SHC_NMAX_ERROR (ULONG_MAX)#

Special value signalizing that a function to read spherical harmonic coefficients encountered an error. The value is platform-dependent.

Allocate, initialize and free the charm_shc structure

These functions allocate, initialize and free the charm_shc structure, which is designed to store spherical harmonic coefficients and some associated data such as the maximum degree of the coefficients, scaling constant, etc.

charm_shc *charm_shc_malloc(unsigned long nmax, double mu, double r)#

Allocates spherical harmonic coefficients up to degree nmax. The charm_shc.mu, charm_shc.r and charm_shc.owner members are set to mu, r and 1, respectively. The spherical harmonic coefficients are uninitialized, so their values are undefined.

Note

r must be larger than zero.

Warning

The structure returned must be deallocated by calling charm_shc_free(). The free function will not deallocate the memory and will lead to memory leaks.

Returns:

On success, returned is a pointer to the charm_shc structure. On error, NULL is returned.

charm_shc *charm_shc_calloc(unsigned long nmax, double mu, double r)#

The same as charm_shc_malloc() but all spherical harmonic coefficients are initialized to zero.

charm_shc *charm_shc_init(unsigned long nmax, double mu, double r, double *c, double *s)#

Takes spherical harmonic coefficients up to degree nmax from the arrays pointed to by c and s (shallow copy). The charm_shc.mu, charm_shc.r and charm_shc.owner members are set to mu, r and 0, respectively.

The c and s pointers must have access to ((nmax + 2) * (nmax + 1)) / 2 array elements. The ordering of coefficients in c and s must follow the pattern:

\[\begin{split}&\bar{C}_{0,0}, \, \bar{C}_{1,0},\bar{C}_{2,0}, \, \cdots, \bar{C}_{\mathrm{nmax},0}, \bar{C}_{1,1},\, \bar{C}_{2,1}, \, \cdots,\\ &\bar{C}_{\mathrm{nmax},1}, \, \bar{C}_{2,2}, \bar{C}_{3,2},\, \cdots,\, \bar{C}_{\mathrm{nmax},\mathrm{nmax}},\end{split}\]

and

\[\begin{split}&\bar{S}_{0,0}, \, \bar{S}_{1,0},\bar{S}_{2,0}, \, \cdots, \bar{S}_{\mathrm{nmax},0}, \bar{S}_{1,1},\, \bar{S}_{2,1}, \, \cdots,\\ &\bar{S}_{\mathrm{nmax},1}, \, \bar{S}_{2,2}, \bar{S}_{3,2},\, \cdots,\, \bar{S}_{\mathrm{nmax},\mathrm{nmax}},\end{split}\]

respectively. Be careful here and always put the product (nmax + 2) * (nmax + 1) into brackets to ensure correct rounding when subsequently dividing by 2 as shown above.

The rationale behind this function is to provide a means to create the charm_shc structure from custom arrays of spherical harmonic coefficients without a deep copy of the data. The following code snippet illustrates this:

unsigned long nmax = 10;

size_t ncs = ((nmax + 2) * (nmax + 1)) / 2;

double *myc = (double *)malloc(ncs * sizeof(double));
double *mys = (double *)malloc(ncs * sizeof(double));

// Now fill "myc" and "mys" with your coefficients.
// [Here goes your code]

// Next, create the "charm_shc" structure from the "myc" and "mys"
// coefficients:
charm_shc *shcs = charm_shc_init(nmax, 1.0, 1.0, myc, mys);

// Do some cool things here with "shcs", but remember that
// "shcs->c" and "shcs->s" share the memory space with "myc" and
// "mys", respectively.
// [Here goes your code]

// At this point, we did everything we needed to do with "shcs", so
// let's release the memory associated with it.
charm_shc_free(shcs);
// The "shcs" structure is now properly released. But
// since "shcs" was created by "charm_shc_init", which does not
// perform a deep copy of the coefficients in "myc" and "mys", the
// memory associated with "myc" and "mys" was not freed.  At this
// point, you may therefore still use "myc" and "mys".
// [Here goes your code]

// Once you are done with "myc" and "mys", release the memory as
// usually with:
free(myc);
free(mys);

Note

r must be larger than zero.

Warning

The structure returned must be deallocated by calling charm_shc_free(). The free function will not deallocate the memory and will lead to memory leaks.

Warning

The spherical harmonic coefficients in the returned charm_shc structure share the memory space with the input c and s arrays. The function does not perform a deep copy of the data. Therefore, charm_shc_free() properly deallocates the charm_shc structure except for the spherical harmonic coefficients. The user allocated c and s outside the scope of CHarm, so the user decides when to deallocate.

Returns:

On success, returned is a pointer to the charm_shc structure. On error, NULL is returned.

void charm_shc_free(charm_shc *shcs)#

Frees the memory associated with shcs. No operation is performed if shcs is NULL.

If shcs->owner is 1, the function releases all the memory that is associated with shcs, including the arrays of spherical harmonic coefficients. If shcs->owner is 0, the coefficients are not released from the memory, because they were not allocated by CHarm.

Read and write the charm_shc structure

These functions read/write the charm_shc structure from/to various text and binary data files.

unsigned long charm_shc_read_bin(const char *pathname, unsigned long nmax, charm_shc *shcs, charm_err *err)#

Reads the charm_shc structure to shcs from a binary file whose name is the string pointed to by pathname. The spherical harmonic coefficients are loaded up to degree nmax. The file is assumed to has been created by charm_shc_write_bin() on the same architecture. Error reported by the function (if any) is written to err.

The input file is a binary representation of the charm_shc structure in the following order:

\[\begin{split}&\mathrm{nmax\_file}, \, \mu, \, R, \bar{C}_{0,0}, \, \bar{C}_{1,0},\bar{C}_{2,0}, \, \cdots, \bar{C}_{\mathrm{nmax\_file},0}, \bar{C}_{1,1},\, \bar{C}_{2,1}, \, \cdots,\\ &\bar{C}_{\mathrm{nmax\_file},1}, \, \bar{C}_{2,2}, \bar{C}_{3,2},\, \cdots,\, \bar{C}_{\mathrm{nmax\_file},\mathrm{nmax\_file}},\, \bar{S}_{0,0},\, \bar{S}_{1,0},\, \bar{S}_{2,0},\, \cdots,\\ &\bar{S}_{\mathrm{nmax\_file},0},\, \bar{S}_{1,1},\, \bar{S}_{2,1},\, \cdots, \bar{S}_{\mathrm{nmax\_file},1},\,\bar{S}_{2,2},\, \bar{S}_{3,2},\, \cdots, \bar{S}_{\mathrm{nmax\_file},\mathrm{nmax\_file}},\end{split}\]

where nmax_file is the maximum harmonic degree stored in pathname, \(\mu\) and \(R\) are the scaling parameter of the coefficients and the associated radius of the reference sphere and, finally, \(\bar{C}_{n,m}\) and \(\bar{S}_{n,m}\) are spherical harmonic coefficients of degree n and order m. It must hold that nmax <= nmax_file and shcs->nmax >= nmax.

Tip

If nmax is CHARM_SHC_NMAX_MODEL and shcs is NULL, the function returns the maximum harmonic degree of pathname without reading the spherical harmonic coefficients.

The rationale behind this behaviour is as follows. Sometimes, the maximum degree nmax_file from pathname is not known when loading the file. In that case, the problem is that the input shcs structure needs to be initialized up to a maximum harmonic degree nmax_shcs >= nmax before loading the coefficients from pathname up to degree nmax <= nmax_file. With nmax = CHARM_SHC_NMAX_MODEL and shcs = NULL, the maximum degrees nmax_file and nmax can be determined before initializing shcs. The following code snippet illustrates this:

charm_err *err = charm_err_init();
if (err == NULL)
    exit(CHARM_FAILURE);

char pathname[] = "/some/path/to/your/model";
unsigned long nmax_file, nmax_shcs, nmax;

// Get the maximum degree stored in "pathname" without reading
// its coefficients, that is, without the need to initialize
// a "charm_shc" structure.
nmax_file = charm_shc_read_bin(pathname, CHARM_SHC_NMAX_MODEL, NULL, err);
charm_err_handler(err, 1);

// Now set "nmax_shcs" to some value equal to or higher
// than "nmax_file"
// [Here goes your code]

// Initialize the "charm_shc" structure to "nmax_shcs"
charm_shc *shcs = charm_shc_malloc(nmax_shcs, 1.0, 1.0);
if (shcs == NULL)
    exit(CHARM_FAILURE);

// Set "nmax" to some value value equal to or smaller than
// "nmax_file"
// [Here goes your code]

// Finally, read the coefficients from "pathname" up to degree
// "nmax" to the structure "shcs"
charm_shc_read_bin(pathname, nmax, shcs, err);
charm_err_handler(err, 1);

Note

The function modifies shcs->c, shcs->s, shcs->mu and shcs->r by the values from the input file, but it does not touch shcs->nmax, shcs->nc and shcs->ns. If shcs->nmax > nmax, the coefficients beyond nmax are set to zero.

Returns:

Upon successful return, the function returns the maximum harmonic degree from pathname. On error, CHARM_SHC_NMAX_ERROR is returned in addition to the error reporting through err.

unsigned long charm_shc_read_gfc(const char *pathname, unsigned long nmax, const char *epoch, charm_shc *shcs, charm_err *err)#

Reads the charm_shc structure to shcs from the ICGEM’s gfc file whose name is the string pointed to by pathname. The coefficients are loaded up to degree nmax. If the file represents a time variable gravity field model, the coefficients are optionally transformed from the model’s default epoch into epoch. Error reported by the function (if any) is written to err. gfc is a format for gravity field models defined by ICGEM at https://icgem.gfz-potsdam.de/docs/ICGEM-Format-2023.pdf.

The date string in epoch must follow either the pattern yyyyMMdd (e.g., "20050217" for Feb 17, 2005) or yyyyMMdd.hhmm (e.g., "20050217.1359" for Feb 17, 2005, 13:59).

  • For static models, epoch is ignored and can be either NULL or a valid date string (which is still ignored though).

  • If the format of the file is icgem1.0 or if the format is not specified, epoch can be either a valid date string or it can be NULL. If epoch is NULL and the file represents a time variable gravity field model, the model’s default epoch is used. No specification of the format implies icgem1.0 as per definition.

  • If the format of the file is icgem2.0, epoch must be a valid date string.

In each leap year, the month of February has 29 days instead of 28 days. The date strings "20050217.2400", "20050218" and "20050218.0000" represent the same epoch. Similarly, "20050217.1360" and "20050217.1400" are equal epochs. Date strings having the format "yyyyMMdd.2460" are not allowed.

It must hold that nmax <= nmax_file, where nmax_file is taken from the max_degree keyword of the gfc file, and shcs->nmax >= nmax.

Tip

If nmax is CHARM_SHC_NMAX_MODEL and shcs is NULL, the function returns the maximum harmonic degree of pathname without reading the spherical harmonic coefficients.

For a use-case, see the tip from the documentation to charm_shc_read_bin(), but keep in mind that this function has one additional input parameter when compared with charm_shc_read_bin().

Note

The function modifies shcs->c, shcs->s, shcs->mu and shcs->r by the values from the input file, but it does not touch shcs->nmax, shcs->nc and shcs->ns. If shcs->nmax > nmax, the coefficients beyond nmax are set to zero.

Returns:

Upon successful return, the function returns the maximum harmonic degree from pathname. On error, CHARM_SHC_NMAX_ERROR is returned in addition to the error reporting through err.

unsigned long charm_shc_read_tbl(const char *pathname, unsigned long nmax, charm_shc *shcs, charm_err *err)#

Reads the charm_shc structure to shcs from a text file whose name is the string pointed to by pathname. The structure is loaded up to degree nmax. The file is assumed to has been created by charm_shc_write_tbl(). Error reported by the function (if any) is written to err.

The first line of the input file must specify the maximum harmonic degree nmax_file of the coefficients stored in the file, their scaling parameter mu and the radius of the reference sphere r. Then, starting at a new line, provided must be a harmonic degree, harmonic order and the respective pair of coefficients per each line of the file. The entire file structure can be summarized as:

\[\begin{split}\begin{matrix} \mathrm{nmax\_file} & \mu & R\\ 0 & 0 & \bar{C}_{0,0} & \bar{S}_{0,0}\\ 1 & 0 & \bar{C}_{1,0} & \bar{S}_{1,0}\\ 1 & 1 & \bar{C}_{1,1} & \bar{S}_{1,1}\\ 2 & 0 & \bar{C}_{2,0} & \bar{S}_{2,0}\\ 2 & 1 & \bar{C}_{2,1} & \bar{S}_{2,1}\\ 2 & 2 & \bar{C}_{2,2} & \bar{S}_{2,2}\\ \vdots & \vdots & \vdots & \vdots \\ \mathrm{nmax\_file} & \mathrm{nmax\_file} & \bar{C}_{\mathrm{nmax\_file},\mathrm{nmax\_file}} & \bar{S}_{\mathrm{nmax\_file},\mathrm{nmax\_file}}\\ \end{matrix}\end{split}\]

where \(\mu\) and \(R\) are the scaling parameter of the coefficients and the associated radius of the reference sphere and \(\bar{C}_{n,m}\) and \(\bar{S}_{n,m}\) are spherical harmonic coefficients of degree n and order m. It must hold that nmax <= nmax_file and shcs->nmax >= nmax. Lines specifying spherical harmonic coefficients (all lines after the first one) can be sorted arbitrarily. The non-existing coefficients \(\bar{S}_{n,0}\) of order 0 do not need to be present in the file.

Tip

If nmax is CHARM_SHC_NMAX_MODEL and shcs is NULL, the function returns the maximum harmonic degree of pathname without reading the spherical harmonic coefficients.

For a use-case, see the tip from the documentation to charm_shc_read_bin().

Note

The function modifies shcs->c, shcs->s, shcs->mu and shcs->r by the values from the input file, but it does not touch shcs->nmax, shcs->nc and shcs->ns. If shcs->nmax > nmax, the coefficients beyond nmax are set to zero.

Returns:

Upon successful return, the function returns the maximum harmonic degree from pathname. On error, CHARM_SHC_NMAX_ERROR is returned in addition to the error reporting through err.

unsigned long charm_shc_read_dov(const char *pathname, unsigned long nmax, charm_shc *shcs, charm_err *err)#

Reads the charm_shc structure to shcs from a text file whose name is the string pointed to by pathname. The structure is loaded up to degree nmax. The file is assumed to has been created by charm_shc_write_dov(). Error reported by the function (if any) is written to err. dov is an abbreviation for the degree, order, value format.

The first line of the input file must specify the maximum harmonic degree nmax_file of the coefficients stored in the file, their scaling parameter mu and the radius of the reference sphere r. Then, starting at a new line, each line must specify a harmonic degree, signed harmonic order (positive for \(\bar{C}_{nm}\), negative for \(\bar{S}_{nm}\)) and the respective coefficient (either \(\bar{C}_{nm}\) or \(\bar{S}_{nm}\), depending on the sign of the order). The entire file structure can be summarized as:

\[\begin{split}\begin{matrix} \mathrm{nmax\_file} & \mu & R\\ 0 & 0 & \bar{C}_{0,0}\\ 1 & 0 & \bar{C}_{1,0}\\ 1 & 1 & \bar{C}_{1,1}\\ 1 & -1 & \bar{S}_{1,1}\\ 2 & 0 & \bar{C}_{2,0}\\ 2 & 1 & \bar{C}_{2,1}\\ 2 & -1 & \bar{S}_{2,1}\\ 2 & 2 & \bar{C}_{2,2}\\ 2 & -2 & \bar{S}_{2,2}\\ \vdots & \vdots & \vdots \\ \mathrm{nmax\_file} & -\mathrm{nmax\_file} & \bar{S}_{\mathrm{nmax\_file},\mathrm{nmax\_file}}\\ \end{matrix}\end{split}\]

where \(\mu\) and \(R\) are the scaling parameter of the coefficients and the associated radius of the reference sphere and \(\bar{C}_{n,m}\) and \(\bar{S}_{n,m}\) are spherical harmonic coefficients of degree n and order m. It must hold that nmax <= nmax_file and shcs->nmax >= nmax. Lines specifying spherical harmonic coefficients (all lines after the first one) can be sorted arbitrarily.

Tip

If nmax is CHARM_SHC_NMAX_MODEL and shcs is NULL, the function returns the maximum harmonic degree of pathname without reading the spherical harmonic coefficients.

For a use-case, see the tip from the documentation to charm_shc_read_bin().

Note

The function modifies shcs->c, shcs->s, shcs->mu and shcs->r by the values from the input file, but it does not touch shcs->nmax, shcs->nc and shcs->ns. If shcs->nmax > nmax, the coefficients beyond nmax are set to zero.

Returns:

Upon successful return, the function returns the maximum harmonic degree from pathname. On error, CHARM_SHC_NMAX_ERROR is returned in addition to the error reporting through err.

unsigned long charm_shc_read_mtx(const char *pathname, unsigned long nmax, charm_shc *shcs, charm_err *err)#

Reads the charm_shc structure to shcs from a text file whose name is the string pointed to by pathname. The structure is loaded up to degree nmax. The file is assumed to has been created by charm_shc_write_mtx(). Error reported by the function (if any) is written to err.

The first line of the input file must specify the maximum harmonic degree nmax_file of the coefficients stored in the file, their scaling parameter mu and the radius of the reference sphere r. Then, starting at a new line, a matrix with a predefined structured specifying the coefficients must follow. The entire file structure can be summarized as:

\[\begin{split}\begin{matrix} \mathrm{nmax\_file} & \mu & R\\ \bar{C}_{00} & \bar{S}_{11} & \bar{S}_{21} & \bar{S}_{31} & \cdots &\bar{S}_{\mathrm{nmax\_file},1}\\ \bar{C}_{10} & \bar{C}_{11} & \bar{S}_{22} & \bar{S}_{32} & \cdots & \bar{S}_{\mathrm{nmax\_file},2}\\ \bar{C}_{20} & \bar{C}_{21} & \bar{C}_{22} & \bar{S}_{33} & \cdots & \bar{S}_{\mathrm{nmax\_file},3}\\ \bar{C}_{30} & \bar{C}_{31} & \bar{C}_{32} & \bar{C}_{33} & \cdots & \bar{S}_{\mathrm{nmax\_file},4}\\ \vdots& \vdots& \vdots& \vdots& \ddots & \vdots \\ \bar{C}_{\mathrm{nmax\_file},0} & \bar{C}_{\mathrm{nmax\_file},1} & \bar{C}_{\mathrm{nmax\_file},2} & \bar{C}_{\mathrm{nmax\_file},3} & \cdots & \bar{C}_{\mathrm{nmax\_file},\mathrm{nmax\_file}} \end{matrix}\end{split}\]

where \(\mu\) and \(R\) are the scaling parameter of the coefficients and the associated radius of the reference sphere and \(\bar{C}_{n,m}\) and \(\bar{S}_{n,m}\) are spherical harmonic coefficients of degree n and order m. It must hold that nmax <= nmax_file and shcs->nmax >= nmax.

Any empty line in the file (that is, containing only the new line character \n) is ignored.

Tip

If nmax is CHARM_SHC_NMAX_MODEL and shcs is NULL, the function returns the maximum harmonic degree of pathname without reading the spherical harmonic coefficients.

For a use-case, see the tip from the documentation to charm_shc_read_bin().

Note

The function modifies shcs->c, shcs->s, shcs->mu and shcs->r by the values from the input file, but it does not touch shcs->nmax, shcs->nc and shcs->ns. If shcs->nmax > nmax, the coefficients beyond nmax are set to zero.

Returns:

Upon successful return, the function returns the maximum harmonic degree from pathname. On error, CHARM_SHC_NMAX_ERROR is returned in addition to the error reporting through err.

void charm_shc_write_bin(const charm_shc *shcs, unsigned long nmax, const char *pathname, charm_err *err)#

Writes shcs up to degree nmax to a binary file whose name is the string pointed to by pathname. Error reported by the function (if any) is written to err.

The output file is a binary representation of shcs up to degree nmax in the following order:

\[\begin{split}&\mathrm{nmax}, \mu, \, R, \, \bar{C}_{0,0}, \, \bar{C}_{1,0}, \, \bar{C}_{2,0}, \, \cdots, \bar{C}_{\mathrm{nmax},0}, \bar{C}_{1,1},\, \bar{C}_{2,1}, \, \cdots,\\ &\bar{C}_{\mathrm{nmax},1}, \, \bar{C}_{2,2}, \bar{C}_{3,2},\, \cdots,\, \bar{C}_{\mathrm{nmax},\mathrm{nmax}},\, \bar{S}_{0,0},\, \bar{S}_{1,0},\, \bar{S}_{2,0},\, \cdots,\\ &\bar{S}_{\mathrm{nmax},0},\, \bar{S}_{1,1},\, \bar{S}_{2,1},\, \cdots, \bar{S}_{\mathrm{nmax},1},\,\bar{S}_{2,2},\, \bar{S}_{3,2},\, \cdots, \bar{S}_{\mathrm{nmax},\mathrm{nmax}},\end{split}\]

where \(\mu\) and \(R\) are the scaling parameter of the coefficients and the associated radius of the reference sphere and \(\bar{C}_{n,m}\) and \(\bar{S}_{n,m}\) are spherical harmonic coefficients of degree n and order m. It must hold that nmax <= shcs->nmax.

The path to the output file in pathname must already exist.

void charm_shc_write_tbl(const charm_shc *shcs, unsigned long nmax, const char *formatting, int ordering, const char *pathname, charm_err *err)#

Writes shcs up to degree nmax to a text file whose name is the string pointed to by pathname using the formatting specifier and the ordering scheme for ordering spherical harmonic coefficients. Error reported by the function (if any) is written to err.

The formatting specifier is used for all floating point data of shcs. No extra characters before or after the formatting specifier are expected, not even the space (no internal check). Examples of valid formatting specifiers in double precision are %0.16e, %24.16e or %0.16f. The formatting specifiers may vary with the precision of the library (single, double or quadruple).

If ordering is CHARM_SHC_WRITE_N, the output file has the following structure:

\[\begin{split}\begin{matrix} \mathrm{nmax} & \mu & R\\ 0 & 0 & \bar{C}_{0,0} & \bar{S}_{0,0}\\ 1 & 0 & \bar{C}_{1,0} & \bar{S}_{1,0}\\ \vdots & \vdots & \vdots & \vdots \\ \mathrm{nmax} & 0 & \bar{C}_{\mathrm{nmax},0} & \bar{S}_{\mathrm{nmax},0}\\ 1 & 1 & \bar{C}_{1,1} & \bar{S}_{1,1}\\ \vdots & \vdots & \vdots & \vdots \\ \mathrm{nmax} & 1 & \bar{C}_{\mathrm{nmax},1} & \bar{S}_{\mathrm{nmax},1}\\ 2 & 2 & \bar{C}_{2,2} & \bar{S}_{2,2}\\ \vdots & \vdots & \vdots & \vdots \\ \mathrm{nmax} & \mathrm{nmax} & \bar{C}_{\mathrm{nmax},\mathrm{nmax}} & \bar{S}_{\mathrm{nmax},\mathrm{nmax}}\\ \end{matrix}\end{split}\]

If ordering is CHARM_SHC_WRITE_M, the output file has the following structure:

\[\begin{split}\begin{matrix} \mathrm{nmax} & \mu & R\\ 0 & 0 & \bar{C}_{0,0} & \bar{S}_{0,0}\\ 1 & 0 & \bar{C}_{1,0} & \bar{S}_{1,0}\\ 1 & 1 & \bar{C}_{1,1} & \bar{S}_{1,1}\\ 2 & 0 & \bar{C}_{2,0} & \bar{S}_{2,0}\\ 2 & 1 & \bar{C}_{2,1} & \bar{S}_{2,1}\\ 2 & 2 & \bar{C}_{2,2} & \bar{S}_{2,2}\\ \vdots & \vdots & \vdots & \vdots \\ \mathrm{nmax} & \mathrm{nmax} & \bar{C}_{\mathrm{nmax},\mathrm{nmax}} & \bar{S}_{\mathrm{nmax},\mathrm{nmax}}\\ \end{matrix}\end{split}\]

In either case, \(\mu\) and \(R\) are the scaling parameter of the coefficients and the associated radius of the reference sphere and \(\bar{C}_{n,m}\) and \(\bar{S}_{n,m}\) are spherical harmonic coefficients of degree n and order m. It must hold that nmax <= shcs->nmax.

The path to the output file in pathname must already exist.

Note

In the quadruple version of CHarm (charmq_shc_write_tbl()), add the Q letter to the formatting specifier. Examples of valid formatting specifiers in quadruple precision are %0.34Qe, %40.34Qe or %0.34Qf (see the documentation to libquadmath).

void charm_shc_write_dov(const charm_shc *shcs, unsigned long nmax, const char *formatting, int ordering, const char *pathname, charm_err *err)#

Writes shcs up to degree nmax to a text file whose name is the string pointed to by pathname using the formatting specifier. Error reported by the function (if any) is written to err. dov is an abbreviation for the degree, order, value formatting.

The formatting specifier is used for all floating point data of shcs. No extra characters before or after the formatting specifier are expected, not even the space (no internal check). Examples of valid formatting specifiers in double precision are %0.16e, %24.16e or %0.16f. The formatting specifiers may vary with the precision of the library (single, double or quadruple).

If ordering is CHARM_SHC_WRITE_N, the output file has the following structure:

\[\begin{split}\begin{matrix} \mathrm{nmax} & \mu & R\\ 0 & 0 & \bar{C}_{0,0}\\ 1 & 0 & \bar{C}_{1,0}\\ 2 & 0 & \bar{C}_{2,0}\\ 1 & 1 & \bar{C}_{1,1}\\ 1 & -1 & \bar{S}_{1,1}\\ 2 & 1 & \bar{C}_{2,1}\\ 2 & -1 & \bar{S}_{2,1}\\ 2 & 2 & \bar{C}_{2,2}\\ 2 & -2 & \bar{S}_{2,2}\\ \vdots & \vdots & \vdots \\ \mathrm{nmax} & -\mathrm{nmax} & \bar{S}_{\mathrm{nmax},\mathrm{nmax}}\\ \end{matrix}\end{split}\]

If ordering is CHARM_SHC_WRITE_M, the output file has the following structure:

\[\begin{split}\begin{matrix} \mathrm{nmax} & \mu & R\\ 0 & 0 & \bar{C}_{0,0}\\ 1 & 0 & \bar{C}_{1,0}\\ 1 & 1 & \bar{C}_{1,1}\\ 1 & -1 & \bar{S}_{1,1}\\ 2 & 0 & \bar{C}_{2,0}\\ 2 & 1 & \bar{C}_{2,1}\\ 2 & -1 & \bar{S}_{2,1}\\ 2 & 2 & \bar{C}_{2,2}\\ 2 & -2 & \bar{S}_{2,2}\\ \vdots & \vdots & \vdots \\ \mathrm{nmax} & -\mathrm{nmax} & \bar{S}_{\mathrm{nmax},\mathrm{nmax}}\\ \end{matrix}\end{split}\]

In either case, \(\mu\) and \(R\) are the scaling parameter of the coefficients and the associated radius of the reference sphere and \(\bar{C}_{n,m}\) and \(\bar{S}_{n,m}\) are spherical harmonic coefficients of degree n and order m. It must hold that nmax <= shcs->nmax.

The path to the output file in pathname must already exist.

Note

In the quadruple version of CHarm (charmq_shc_write_dov()), add the Q letter to the formatting specifier. Examples of valid formatting specifiers in quadruple precision are %0.34Qe, %40.34Qe or %0.34Qf (see the documentation to libquadmath).

void charm_shc_write_mtx(const charm_shc *shcs, unsigned long nmax, const char *formatting, const char *pathname, charm_err *err)#

Writes shcs up to degree nmax to a text file whose name is the string pointed to by pathname using the formatting specifier. Error reported by the function (if any) is written to err.

The formatting specifier is used for all floating point data of shcs. No extra characters before or after the formatting specifier are expected, not even the space (no internal check). Examples of valid formatting specifiers in double precision are %0.16e, %24.16e or %0.16f. The formatting specifiers may vary with the precision of the library (single, double or quadruple).

The output file has the following structure:

\[\begin{split}\begin{matrix} \mathrm{nmax} & \mu & R\\ \bar{C}_{00} & \bar{S}_{11} & \bar{S}_{21} & \bar{S}_{31} & \cdots &\bar{S}_{\mathrm{nmax},1}\\ \bar{C}_{10} & \bar{C}_{11} & \bar{S}_{22} & \bar{S}_{32} & \cdots & \bar{S}_{\mathrm{nmax},2}\\ \bar{C}_{20} & \bar{C}_{21} & \bar{C}_{22} & \bar{S}_{33} & \cdots & \bar{S}_{\mathrm{nmax},3}\\ \bar{C}_{30} & \bar{C}_{31} & \bar{C}_{32} & \bar{C}_{33} & \cdots & \bar{S}_{\mathrm{nmax},4}\\ \vdots&\vdots &\vdots & \vdots& \ddots & \vdots \\ \bar{C}_{\mathrm{nmax},0} & \bar{C}_{\mathrm{nmax},1} & \bar{C}_{\mathrm{nmax},2} & \bar{C}_{\mathrm{nmax},3} & \cdots & \bar{C}_{\mathrm{nmax},\mathrm{nmax}} \end{matrix}\end{split}\]

where \(\mu\) and \(R\) are the scaling parameter of the coefficients and the associated radius of the reference sphere and \(\bar{C}_{n,m}\) and \(\bar{S}_{n,m}\) are spherical harmonic coefficients of degree n and order m. It must hold that nmax <= shcs->nmax.

The path to the output file in pathname must already exist.

Note

In the quadruple version of CHarm (charmq_shc_write_mtx()), add the Q letter to the formatting specifier. Examples of valid formatting specifiers in quadruple precision are %0.34Qe, %40.34Qe or %0.34Qf (see the documentation to libquadmath).

Spectrum from the charm_shc structure

These functions compute the spectrum from the charm_shc structure in the form of (difference) degree variances and (difference) degree amplitudes.

void charm_shc_dv(const charm_shc *shcs, unsigned long nmax, double *dv, charm_err *err)#

Computes degree variances (spectrum) dv up to degree nmax of a signal given by spherical harmonic coefficients in shcs. Each array index of dv, n = 0, 1, …, nmax, corresponds to the degree variance of the respective degree n. Error reported by the function (if any) is written to err.

The degree variances are given as

\[\mathrm{dv}_n = \sum_{m = 0}^{n}(\bar{C}_{nm}^2 + \bar{S}_{nm}^2) \,.\]

Note

The shcs->mu and shcs->r parameters are not used to evaluate the degree variances, since this appears to be the most common way in practice.

void charm_shc_da(const charm_shc *shcs, unsigned long nmax, double *da, charm_err *err)#

Computes degree amplitudes (square root of degree variances) da up to degree nmax of a signal given by spherical harmonic coefficients in shcs. Each array index of da, n = 0, 1, …, nmax, corresponds to the degree amplitude of the respective degree n. Error reported by the function (if any) is written to err.

The degree amplitudes are given as

\[\mathrm{da}_n = \sqrt{\sum_{m = 0}^{n}(\bar{C}_{nm}^2 + \bar{S}_{nm}^2)} \,.\]

Note

The shcs->mu and shcs->r parameters are not used to evaluate the degree amplitudes, since this appears to be the most common way in practice.

void charm_shc_ddv(const charm_shc *shcs1, const charm_shc *shcs2, unsigned long nmax, double *ddv, charm_err *err)#

Computes difference degree variances (difference spectrum) ddv up to degree nmax between a signal given by spherical harmonic coefficients in shcs1 and shcs2. Each array index of ddv, n = 0, 1, …, nmax, corresponds to the difference degree variance of the respective degree n. Error reported by the function (if any) is written to err.

The difference degree variances are given as

\[\mathrm{ddv}_n = \sum_{m = 0}^{n}\left(\left(\bar{C}_{nm}^{(1)} - \bar{C}_{nm}^{(2)}\right)^2 + \left(\bar{S}_{nm}^{(1)} - \bar{S}_{nm}^{(2)}\right)^2\right) \,.\]

Note

The shcs->mu and shcs->r parameters are not used to evaluate the differece degree variances, since this appears to be the most common way in practice. However, the values of mu and r in shcs1 and shcs2 must be equal (the function performs a check on this).

void charm_shc_dda(const charm_shc *shcs1, const charm_shc *shcs2, unsigned long nmax, double *da, charm_err *err)#

Computes difference degree amplitudes (square root of difference degree variances) dda up to degree nmax between a signal given by spherical harmonic coefficients in shcs1 and shcs2. Each array index of dda, n = 0, 1, …, nmax, corresponds to the difference degree amplitude of the respective degree n. Error reported by the function (if any) is written to err.

The difference degree amplitudes are given as

\[\mathrm{dda}_n = \sqrt{\sum_{m = 0}^{n}\left(\left(\bar{C}_{nm}^{(1)} - \bar{C}_{nm}^{(2)}\right)^2 + \left(\bar{S}_{nm}^{(1)} - \bar{S}_{nm}^{(2)}\right)^2\right)} \,.\]

Note

The shcs->mu and shcs->r parameters are not used to evaluate the difference degree amplitudes, since this appears to be the most common way in practice. However, the values of mu and r in shcs1 and shcs2 must be equal (the function performs a check on this).

Miscellaneous functions

void charm_shc_rescale(charm_shc *shcs, double munew, double rnew, charm_err *err)#

Rescales spherical harmonic coefficients in shcs to a new scaling parameter munew and a new radius of the reference sphere rnew:

\[ \begin{align}\begin{aligned}\begin{split}\bar{C}_{nm}^{\mathrm{new}} = \frac{\mu}{\mu_{\mathrm{new}}} \, \left( \frac{R}{R_{\mathrm{new}}} \right)^n \, \bar{C}_{nm}\,,\\\end{split}\\\bar{S}_{nm}^{\mathrm{new}} = \frac{\mu}{\mu_{\mathrm{new}}} \, \left( \frac{R}{R_{\mathrm{new}}} \right)^n \, \bar{S}_{nm}\,.\end{aligned}\end{align} \]

After the conversion, shcs->mu and shcs->r are updated to munew and rnew, respectively.

Error reported by the function (if any) is written to err.

Enums

enum [anonymous]#

Ordering scheme to write spherical harmonic coefficients with charm_shc_write_tbl() and charm_shc_write_dov().

Values:

enumerator CHARM_SHC_WRITE_N#

Harmonic degree varies fastest.

enumerator CHARM_SHC_WRITE_M#

Harmonic order varies fastest.

struct charm_shc#

Structure to store spherical harmonic coefficients and some associated data.

If CHarm is compiled with the MPI support, the data of the structure can be distributed across MPI processes. This is useful if your dataset is so large that it would not fit into the RAM of a single computing node. The members of the structure are therefore divided into two groups.

  • Members common to both non-distributed and distributed structures. These are always accessible.

  • Members specific to distributed structures only. These are accessible only when CHarm was compiled with the MPI support.

Members common to non-distributed and distributed structures

unsigned long nmax#

Maximum harmonic degree of the spherical harmonic coefficients.

double mu#

Scaling parameter \(\mu\) associated with the spherical harmonic coefficients, for instance, the geocentric gravitational constant. In case the coefficients are not associated with any scaling parameter (as it is, for instance, with planetary topographies), simply set this variable to 1.0 (not to 0.0!).

double r#

Radius of the reference sphere \(R\), to which the spherical harmonic coefficients refer (are scaled). The value must be larger than zero. To get the unit sphere, as needed, for instance, when working with planetary topographies, set this variable to 1.0.

size_t nc#

Total number of spherical harmonic coefficients \(\bar{C}_{nm}\). The value is always larger than zero.

size_t ns#

Total number of spherical harmonic coefficients \(\bar{S}_{nm}\). The value is always larger than zero.

double **c#

Spherical harmonic coefficients \(\bar{C}_{nm}\) stored as a 2D array. The first dimension is related to harmonic orders and the second one to harmonic degrees. Importantly, the number of columns varies for each row as follows:

Assuming the charm_shc structure was initialized up to some degree unsigned long nmax as

charm_shc *shcs = charm_shc_calloc(nmax, 1.0, 1.0);

harmonic coefficients of degree n <= nmax and order m <= n can be accessed as:

shcs->c[m][n - m];

The coefficients in charm_shc.c are stored in a contiguous block of memory. For fast sequential access, the loop over harmonic orders should always be the outer one, in which the degree-dependent loop is nested, such as:

charm_shc *shcs = charm_shc_calloc(nmax, 1.0, 1.0);
for (unsigned long m = 0; m <= nmax; m++)
    for (unsigned long n = m; n <= nmax; n++)
        shcs->c[m][n - m];

Warning

charm_shc.c is not a 2D rectangular array.

double **s#

Spherical harmonic coefficients \(\bar{S}_{nm}\). The same comments as for charm_shc.c apply to charm_shc.s, too.

_Bool owner#

_Bool distributed#

Note

If CHarm was compiled without the MPI support (default), charm_shc.distributed is always 0.

Members available to distributed structures only

Note

The members that follow are available only when CHarm is compiled with the MPI support (--enable-mpi, refer to charm_mpi for further details).

size_t local_nc#

Total number of spherical harmonic coefficients \(\bar{C}_{nm}\) locally accessible to an MPI process. If 0, no coefficients are stored locally.

size_t local_ns#

Total number of spherical harmonic coefficients \(\bar{S}_{nm}\) locally accessible to an MPI process. If 0, no coefficients are stored locally.

size_t local_nchunk#

Total number of chunks of spherical harmonic orders that are stored locally. If 0, no chunks are stored locally.

unsigned long *local_order#

Spherical harmonic orders specifying chunks of spherical harmonic coefficients that are locally available to an MPI process. The pointer is NULL if charm_shc.local_nchunk is 0.

Assume there is k = charm_shc.local_nchunk local chunks. The pointer charm_shc.local_order points to an array of 2 * k elements having the structure:

\[\underbrace{m_0, m_1}_{\textrm{chunk 0}} | \underbrace{m_2, m_3}_{\textrm{chunk 1}} | \underbrace{...}_{\textrm{chunks 2 to }k - 2} | \underbrace{m_{2k - 2}, m_{2k - 1}}_{\textrm{chunk }k - 1}{,}\]

where \(m_{2j}\) and \(m_{2j + 1}\), \(j = 0, 1, ..., k - 1\), denote the minimum and the maximum orders of the chunks, respectively. Spherical harmonic coefficients \(\bar{C}_{nm}\) and \(\bar{S}_{nm}\) of all degrees \(n = m, m + 1, ..., n_{\textrm{max}}\) and orders \(m = m_{2j}, ..., m_{2j + 1}\), \(j = 0, 1, ..., k - 1\), are accessible to an MPI process through charm_shc.c and charm_shc.s. The ordering of the coefficients in charm_shc.c is then as follows:

\[\underbrace{\bar{C}_{m_0, m_0}, \bar{C}_{m_0 + 1, m_0}, ..., \bar{C}_{\mathrm{nmax}, m_0}, \bar{C}_{m_0 + 1, m_0 + 1}, ... ,\bar{C}_{\mathrm{nmax}, m_0 + 1}, ..., \bar{C}_{\mathrm{nmax}, m_1}}_{\textrm{chunk 0}} | \underbrace{\bar{C}_{m_2, m_2}, ..., \bar{C}_{\mathrm{nmax}, m_3}}_{\textrm{chunk 1}} | \underbrace{...}_{\textrm{chunks 2 to }k - 2} | \underbrace{\bar{C}_{m_{2k - 2}, m_{2k - 2}}, ..., \bar{C}_{\mathrm{nmax}}, m_{2k - 1}}_{\textrm{chunk }k - 1}{.}\]

The total number of these coefficients is stored in charm_shc.local_nc. It can also be determined a priori by charm_mpi_shc_local_ncs(). The same ordering and the number of coefficients applies to \(\bar{S}_{nm}\) in charm_shc.s.

Note

Whenever creating charm_shc through the CHarm’s API, charm_shc.local_order is always a deep copy of the user’s original data local_order. Users can therefore safely free their original local_order array after creating charm_shc.

Note

Sounds complicated? It isn’t! Have a look at the charm_mpi module and the cookbook.

MPI_Comm comm#

MPI communicator defining the group of MPI processes to distribute the structure across.