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.
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
. Thecharm_shc.mu
,charm_shc.r
andcharm_shc.owner
members are set tomu
,r
and1
, respectively. The spherical harmonic coefficients are uninitialized, so their values are undefined.Note
r
must be greater than zero.Warning
The structure returned must be deallocated by calling
charm_shc_free()
. Thefree
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 byc
ands
(shallow copy). Thecharm_shc.mu
,charm_shc.r
andcharm_shc.owner
members are set tomu
,r
and0
, respectively.The
c
ands
pointers must have access to((nmax + 2) * (nmax + 1)) / 2
array elements. The ordering of coefficients inc
ands
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 by2
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 greater than zero.Warning
The structure returned must be deallocated by calling
charm_shc_free()
. Thefree
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 inputc
ands
arrays. The function does not perform a deep copy of the data. Therefore,charm_shc_free()
properly deallocates thecharm_shc
structure except for the spherical harmonic coefficients. The user allocatedc
ands
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 ifshcs
isNULL
.If
shcs>owner
is1
, the function releases all the memory that is associated withshcs
, including the arrays of spherical harmonic coefficients. Ifshcs>owner
is0
, 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 toshcs
from a binary file whose name is the string pointed to bypathname
. The spherical harmonic coefficients are loaded up to degreenmax
. The file is assumed to has been created bycharm_shc_write_bin()
on the same architecture. Error reported by the function (if any) is written toerr
.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 inpathname
, \(\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 degreen
and orderm
. It must hold thatnmax <= nmax_file
andshcs>nmax >= nmax
.Tip
If
nmax
isCHARM_SHC_NMAX_MODEL
andshcs
isNULL
, the function returns the maximum harmonic degree ofpathname
without reading the spherical harmonic coefficients.The rationale behind this behaviour is as follows. Sometimes, the maximum degree
nmax_file
frompathname
is not known when loading the file. In that case, the problem is that the inputshcs
structure needs to be initialized up to a maximum harmonic degreenmax_shcs >= nmax
before loading the coefficients frompathname
up to degreenmax <= nmax_file
. Withnmax = CHARM_SHC_NMAX_MODEL
andshcs = NULL
, the maximum degreesnmax_file
andnmax
can be determined before initializingshcs
. 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
andshcs>r
by the values from the input file, but it does not touchshcs>nmax
,shcs>nc
andshcs>ns
. Ifshcs>nmax > nmax
, the coefficients beyondnmax
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 througherr
.

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 toshcs
from the ICGEM’s gfc file whose name is the string pointed to bypathname
. The coefficients are loaded up to degreenmax
. If the file represents a time variable gravity field model, the coefficients are optionally transformed from the model’s default epoch intoepoch
. Error reported by the function (if any) is written toerr
. gfc is a format for gravity field models defined by ICGEM at http://icgem.gfzpotsdam.de/ICGEMFormat2023.pdf.The date string in
epoch
must follow either the patternyyyyMMdd
(e.g.,"20050217"
for Feb 17, 2005) oryyyyMMdd.hhmm
(e.g.,"20050217.1359"
for Feb 17, 2005, 13:59).For static models,
epoch
is ignored and can be eitherNULL
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 beNULL
. Ifepoch
isNULL
and the file represents a time variable gravity field model, the model’s default epoch is used. No specification of the format impliesicgem1.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
, wherenmax_file
is taken from themax_degree
keyword of the gfc file, andshcs>nmax >= nmax
.Tip
If
nmax
isCHARM_SHC_NMAX_MODEL
andshcs
isNULL
, the function returns the maximum harmonic degree ofpathname
without reading the spherical harmonic coefficients.For a usecase, 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 withcharm_shc_read_bin()
.Note
The function modifies
shcs>c
,shcs>s
,shcs>mu
andshcs>r
by the values from the input file, but it does not touchshcs>nmax
,shcs>nc
andshcs>ns
. Ifshcs>nmax > nmax
, the coefficients beyondnmax
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 througherr
.

unsigned long charm_shc_read_tbl(const char *pathname, unsigned long nmax, charm_shc *shcs, charm_err *err)#
Reads the
charm_shc
structure toshcs
from a text file whose name is the string pointed to bypathname
. The structure is loaded up to degreenmax
. The file is assumed to has been created bycharm_shc_write_tbl()
. Error reported by the function (if any) is written toerr
.The first line of the input file must specify the maximum harmonic degree
nmax_file
of the coefficients stored in the file, their scaling parametermu
and the radius of the reference spherer
. 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 orderm
. It must hold thatnmax <= nmax_file
andshcs>nmax >= nmax
. Lines specifying spherical harmonic coefficients (all lines after the first one) can be sorted arbitrarily. The nonexisting coefficients \(\bar{S}_{n,0}\) of order0
do not need to be present in the file.Tip
If
nmax
isCHARM_SHC_NMAX_MODEL
andshcs
isNULL
, the function returns the maximum harmonic degree ofpathname
without reading the spherical harmonic coefficients.For a usecase, see the tip from the documentation to
charm_shc_read_bin()
.Note
The function modifies
shcs>c
,shcs>s
,shcs>mu
andshcs>r
by the values from the input file, but it does not touchshcs>nmax
,shcs>nc
andshcs>ns
. Ifshcs>nmax > nmax
, the coefficients beyondnmax
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 througherr
.

unsigned long charm_shc_read_dov(const char *pathname, unsigned long nmax, charm_shc *shcs, charm_err *err)#
Reads the
charm_shc
structure toshcs
from a text file whose name is the string pointed to bypathname
. The structure is loaded up to degreenmax
. The file is assumed to has been created bycharm_shc_write_dov()
. Error reported by the function (if any) is written toerr
.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 parametermu
and the radius of the reference spherer
. 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 orderm
. It must hold thatnmax <= nmax_file
andshcs>nmax >= nmax
. Lines specifying spherical harmonic coefficients (all lines after the first one) can be sorted arbitrarily.Tip
If
nmax
isCHARM_SHC_NMAX_MODEL
andshcs
isNULL
, the function returns the maximum harmonic degree ofpathname
without reading the spherical harmonic coefficients.For a usecase, see the tip from the documentation to
charm_shc_read_bin()
.Note
The function modifies
shcs>c
,shcs>s
,shcs>mu
andshcs>r
by the values from the input file, but it does not touchshcs>nmax
,shcs>nc
andshcs>ns
. Ifshcs>nmax > nmax
, the coefficients beyondnmax
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 througherr
.

unsigned long charm_shc_read_mtx(const char *pathname, unsigned long nmax, charm_shc *shcs, charm_err *err)#
Reads the
charm_shc
structure toshcs
from a text file whose name is the string pointed to bypathname
. The structure is loaded up to degreenmax
. The file is assumed to has been created bycharm_shc_write_mtx()
. Error reported by the function (if any) is written toerr
.The first line of the input file must specify the maximum harmonic degree
nmax_file
of the coefficients stored in the file, their scaling parametermu
and the radius of the reference spherer
. 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 orderm
. It must hold thatnmax <= nmax_file
andshcs>nmax >= nmax
.Any empty line in the file (that is, containing only the new line character
\n
) is ignored.Tip
If
nmax
isCHARM_SHC_NMAX_MODEL
andshcs
isNULL
, the function returns the maximum harmonic degree ofpathname
without reading the spherical harmonic coefficients.For a usecase, see the tip from the documentation to
charm_shc_read_bin()
.Note
The function modifies
shcs>c
,shcs>s
,shcs>mu
andshcs>r
by the values from the input file, but it does not touchshcs>nmax
,shcs>nc
andshcs>ns
. Ifshcs>nmax > nmax
, the coefficients beyondnmax
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 througherr
.

void charm_shc_write_bin(const charm_shc *shcs, unsigned long nmax, const char *pathname, charm_err *err)#
Writes
shcs
up to degreenmax
to a binary file whose name is the string pointed to bypathname
. Error reported by the function (if any) is written toerr
.The output file is a binary representation of
shcs
up to degreenmax
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 orderm
. It must hold thatnmax <= 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 degreenmax
to a text file whose name is the string pointed to bypathname
using theformatting
specifier and theordering
scheme for ordering spherical harmonic coefficients. Error reported by the function (if any) is written toerr
.The
formatting
specifier is used for all floating point data ofshcs
. No extra characters before or after the formatting specifier are expected, not even the space (no internal check). Examples of validformatting
specifiers in double precision are%0.16e
,%24.16e
or%0.16f
. Theformatting
specifiers may vary with the precision of the library (single, double or quadruple).If
ordering
isCHARM_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
isCHARM_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 orderm
. It must hold thatnmax <= 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 theQ
letter to theformatting
specifier. Examples of validformatting
specifiers in quadruple precision are%0.34Qe
,%40.34Qe
or%0.34Qf
(see the documentation tolibquadmath
).

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 degreenmax
to a text file whose name is the string pointed to bypathname
using theformatting
specifier. Error reported by the function (if any) is written toerr
.dov
is an abbreviation for the degree, order, value formatting.The
formatting
specifier is used for all floating point data ofshcs
. No extra characters before or after the formatting specifier are expected, not even the space (no internal check). Examples of validformatting
specifiers in double precision are%0.16e
,%24.16e
or%0.16f
. Theformatting
specifiers may vary with the precision of the library (single, double or quadruple).If
ordering
isCHARM_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
isCHARM_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 orderm
. It must hold thatnmax <= 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 theQ
letter to theformatting
specifier. Examples of validformatting
specifiers in quadruple precision are%0.34Qe
,%40.34Qe
or%0.34Qf
(see the documentation tolibquadmath
).

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 degreenmax
to a text file whose name is the string pointed to bypathname
using theformatting
specifier. Error reported by the function (if any) is written toerr
.The
formatting
specifier is used for all floating point data ofshcs
. No extra characters before or after the formatting specifier are expected, not even the space (no internal check). Examples of validformatting
specifiers in double precision are%0.16e
,%24.16e
or%0.16f
. Theformatting
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 orderm
. It must hold thatnmax <= 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 theQ
letter to theformatting
specifier. Examples of validformatting
specifiers in quadruple precision are%0.34Qe
,%40.34Qe
or%0.34Qf
(see the documentation tolibquadmath
).
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 degreenmax
of a signal given by spherical harmonic coefficients inshcs
. Each array index ofdv
,n = 0
,1
, …,nmax
, corresponds to the degree variance of the respective degreen
. Error reported by the function (if any) is written toerr
.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
andshcs>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 degreenmax
of a signal given by spherical harmonic coefficients inshcs
. Each array index ofda
,n = 0
,1
, …,nmax
, corresponds to the degree amplitude of the respective degreen
. Error reported by the function (if any) is written toerr
.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
andshcs>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 degreenmax
between a signal given by spherical harmonic coefficients inshcs1
andshcs2
. Each array index ofddv
,n = 0
,1
, …,nmax
, corresponds to the difference degree variance of the respective degreen
. Error reported by the function (if any) is written toerr
.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
andshcs>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 ofmu
andr
inshcs1
andshcs2
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 degreenmax
between a signal given by spherical harmonic coefficients inshcs1
andshcs2
. Each array index ofdda
,n = 0
,1
, …,nmax
, corresponds to the difference degree amplitude of the respective degreen
. Error reported by the function (if any) is written toerr
.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
andshcs>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 ofmu
andr
inshcs1
andshcs2
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 parametermunew
and a new radius of the reference spherernew
:\[ \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
andshcs>r
are updated tomunew
andrnew
, 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()
andcharm_shc_write_dov()
.Values:

enumerator CHARM_SHC_WRITE_N#
Harmonic degree varies fastest.

enumerator CHARM_SHC_WRITE_M#
Harmonic order varies fastest.

enumerator CHARM_SHC_WRITE_N#

enum [anonymous]#
Special values for functions to read spherical harmonic harmonic coefficients:
charm_shc_read_dov()
,charm_shc_read_gfc()
,charm_shc_read_tbl()
,charm_shc_read_mtx()
,charm_shc_read_dov()
.Values:

enumerator CHARM_SHC_NMAX_MODEL = ULONG_MAX  1#
Special value of the
nmax
input parameter to all functions that read spherical harmonic coefficients. Ifnmax
isCHARM_SHC_NMAX_MODEL
andshcs
isNULL
, the functions return the maximum harmonic degree found inside the file and do not read the rest of the file (see the documentatino tocharm_shc_read_*
function). The value is platformdependent.

enumerator CHARM_SHC_NMAX_ERROR#
Harmonic degree signalizing that a function to read spherical harmonic coefficients encountered an error. The value is platformdependent.

enumerator CHARM_SHC_NMAX_MODEL = ULONG_MAX  1#

struct charm_shc#
Structure to store spherical harmonic coefficients and some associated data.
Public Members

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 to0.0
!).

double r#
Radius of the reference sphere \(R\), to which the spherical harmonic coefficients refer (are scaled). The value must be greater 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}\).

size_t ns#
Total number of spherical harmonic coefficients \(\bar{S}_{nm}\).

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:
Order
0
:charm_shc.c[0]
hascharm_shc.nmax + 1
columns for degrees0
,1
, …,charm_shc.nmax
(respectively),Order
1
:charm_shc.c[1]
hascharm_shc.nmax
columns for degrees1
,2
, …,charm_shc.nmax
(respectively),Order
2
:charm_shc.c[2]
hascharm_shc.nmax  1
columns for degrees2
,3
, …,charm_shc.nmax
(respectively),…
Order
charm_shc.nmax
:c[charm_shc.nmax]
has1
column for degreecharm_shc.nmax
.
Assuming the
charm_shc
structure was initialized up to some degreeunsigned long nmax
ascharm_shc *shcs = charm_shc_calloc(nmax, 1.0, 1.0);
harmonic coefficients of degree
n <= nmax
and orderm <= 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 degreedependent 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 tocharm_shc.s
, too.

_Bool owner#
If
1
, the spherical harmonic coefficients incharm_shc.c
andcharm_shc.s
were allocated by CHarm, socharm_shc_free()
deallocates them. Ifcharm_shc.owner
is0
, the coefficients incharm_shc.c
andcharm_shc.s
were allocated outside CHarm, socharm_shc_free()
does not deallocate them (the user allocated this memory outside CHarm, so the user should free the memory outside CHarm as well).charm_shc.owner
is set to1
forcharm_shc
returned bycharm_shc_malloc()
andcharm_shc_calloc()
.charm_shc_init()
returnscharm_shc
withcharm_shc.owner
set to0
.

unsigned long nmax#