charm_shc#
Module to work with spherical harmonic coefficients:
defines the
charm_shcstructure 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 - 1UL)#
 Special value of the
nmaxinput parameter to all functions that read spherical harmonic coefficients. IfnmaxisCHARM_SHC_NMAX_MODELandshcsisNULL, the functions return the maximum harmonic degree found inside the file and do not read the rest of the file (see the documentation tocharm_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. Thecharm_shc.mu,charm_shc.randcharm_shc.ownermembers are set tomu,rand1, respectively. The spherical harmonic coefficients are uninitialized, so their values are undefined.Note
rmust be larger than zero.Warning
The structure returned must be deallocated by calling
charm_shc_free(). Thefreefunction will not deallocate the memory and will lead to memory leaks.- Returns:
 On success, returned is a pointer to the
charm_shcstructure. On error,NULLis 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
nmaxfrom the arrays pointed to bycands(shallow copy). Thecharm_shc.mu,charm_shc.randcharm_shc.ownermembers are set tomu,rand0, respectively.The
candspointers must have access to((nmax + 2) * (nmax + 1)) / 2array elements. The ordering of coefficients incandsmust 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 by2as shown above.The rationale behind this function is to provide a means to create the
charm_shcstructure 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
rmust be larger than zero.Warning
The structure returned must be deallocated by calling
charm_shc_free(). Thefreefunction will not deallocate the memory and will lead to memory leaks.Warning
The spherical harmonic coefficients in the returned
charm_shcstructure share the memory space with the inputcandsarrays. The function does not perform a deep copy of the data. Therefore,charm_shc_free()properly deallocates thecharm_shcstructure except for the spherical harmonic coefficients. The user allocatedcandsoutside the scope of CHarm, so the user decides when to deallocate.- Returns:
 On success, returned is a pointer to the
charm_shcstructure. On error,NULLis returned.
- 
void charm_shc_free(charm_shc *shcs)#
 Frees the memory associated with
shcs. No operation is performed ifshcsisNULL.If
shcs->owneris1, the function releases all the memory that is associated withshcs, including the arrays of spherical harmonic coefficients. Ifshcs->owneris0, 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_shcstructure toshcsfrom 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_shcstructure 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_fileis 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 degreenand orderm. It must hold thatnmax <= nmax_fileandshcs->nmax >= nmax.Tip
If
nmaxisCHARM_SHC_NMAX_MODELandshcsisNULL, the function returns the maximum harmonic degree ofpathnamewithout reading the spherical harmonic coefficients.The rationale behind this behaviour is as follows. Sometimes, the maximum degree
nmax_filefrompathnameis not known when loading the file. In that case, the problem is that the inputshcsstructure needs to be initialized up to a maximum harmonic degreenmax_shcs >= nmaxbefore loading the coefficients frompathnameup to degreenmax <= nmax_file. Withnmax = CHARM_SHC_NMAX_MODELandshcs = NULL, the maximum degreesnmax_fileandnmaxcan 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->muandshcs->rby the values from the input file, but it does not touchshcs->nmax,shcs->ncandshcs->ns. Ifshcs->nmax > nmax, the coefficients beyondnmaxare set to zero.- Returns:
 Upon successful return, the function returns the maximum harmonic degree from
pathname. On error,CHARM_SHC_NMAX_ERRORis 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_shcstructure toshcsfrom 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 https://icgem.gfz-potsdam.de/docs/ICGEM-Format-2023.pdf.The date string in
epochmust 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,
epochis ignored and can be eitherNULLor a valid date string (which is still ignored though).If the format of the file is
icgem1.0or if the format is not specified,epochcan be either a valid date string or it can beNULL. IfepochisNULLand the file represents a time variable gravity field model, the model’s default epoch is used. No specification of the format impliesicgem1.0as per definition.If the format of the file is
icgem2.0,epochmust 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_fileis taken from themax_degreekeyword of the gfc file, andshcs->nmax >= nmax.Tip
If
nmaxisCHARM_SHC_NMAX_MODELandshcsisNULL, the function returns the maximum harmonic degree ofpathnamewithout 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 withcharm_shc_read_bin().Note
The function modifies
shcs->c,shcs->s,shcs->muandshcs->rby the values from the input file, but it does not touchshcs->nmax,shcs->ncandshcs->ns. Ifshcs->nmax > nmax, the coefficients beyondnmaxare set to zero.- Returns:
 Upon successful return, the function returns the maximum harmonic degree from
pathname. On error,CHARM_SHC_NMAX_ERRORis 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_shcstructure toshcsfrom 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_fileof the coefficients stored in the file, their scaling parametermuand 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
nand orderm. It must hold thatnmax <= nmax_fileandshcs->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 order0do not need to be present in the file.Tip
If
nmaxisCHARM_SHC_NMAX_MODELandshcsisNULL, the function returns the maximum harmonic degree ofpathnamewithout 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->muandshcs->rby the values from the input file, but it does not touchshcs->nmax,shcs->ncandshcs->ns. Ifshcs->nmax > nmax, the coefficients beyondnmaxare set to zero.- Returns:
 Upon successful return, the function returns the maximum harmonic degree from
pathname. On error,CHARM_SHC_NMAX_ERRORis 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_shcstructure toshcsfrom 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.dovis an abbreviation for the degree, order, value format.The first line of the input file must specify the maximum harmonic degree
nmax_fileof the coefficients stored in the file, their scaling parametermuand 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
nand orderm. It must hold thatnmax <= nmax_fileandshcs->nmax >= nmax. Lines specifying spherical harmonic coefficients (all lines after the first one) can be sorted arbitrarily.Tip
If
nmaxisCHARM_SHC_NMAX_MODELandshcsisNULL, the function returns the maximum harmonic degree ofpathnamewithout 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->muandshcs->rby the values from the input file, but it does not touchshcs->nmax,shcs->ncandshcs->ns. Ifshcs->nmax > nmax, the coefficients beyondnmaxare set to zero.- Returns:
 Upon successful return, the function returns the maximum harmonic degree from
pathname. On error,CHARM_SHC_NMAX_ERRORis 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_shcstructure toshcsfrom 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_fileof the coefficients stored in the file, their scaling parametermuand 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
nand orderm. It must hold thatnmax <= nmax_fileandshcs->nmax >= nmax.Any empty line in the file (that is, containing only the new line character
\n) is ignored.Tip
If
nmaxisCHARM_SHC_NMAX_MODELandshcsisNULL, the function returns the maximum harmonic degree ofpathnamewithout 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->muandshcs->rby the values from the input file, but it does not touchshcs->nmax,shcs->ncandshcs->ns. Ifshcs->nmax > nmax, the coefficients beyondnmaxare set to zero.- Returns:
 Upon successful return, the function returns the maximum harmonic degree from
pathname. On error,CHARM_SHC_NMAX_ERRORis 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
shcsup to degreenmaxto 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
shcsup to degreenmaxin 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
nand orderm. It must hold thatnmax <= shcs->nmax.The path to the output file in
pathnamemust already exist.Note
The output file is platform-dependent.
- 
void charm_shc_write_tbl(const charm_shc *shcs, unsigned long nmax, const char *formatting, int ordering, const char *pathname, charm_err *err)#
 Writes
shcsup to degreenmaxto a text file whose name is the string pointed to bypathnameusing theformattingspecifier and theorderingscheme for ordering spherical harmonic coefficients. Error reported by the function (if any) is written toerr.The
formattingspecifier 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 validformattingspecifiers in double precision are%0.16e,%24.16eor%0.16f. Theformattingspecifiers may vary with the precision of the library (single, double or quadruple).If
orderingisCHARM_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
orderingisCHARM_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
nand orderm. It must hold thatnmax <= shcs->nmax.The path to the output file in
pathnamemust already exist.Note
In the quadruple version of CHarm (
charmq_shc_write_tbl()), add theQletter to theformattingspecifier. Examples of validformattingspecifiers in quadruple precision are%0.34Qe,%40.34Qeor%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
shcsup to degreenmaxto a text file whose name is the string pointed to bypathnameusing theformattingspecifier. Error reported by the function (if any) is written toerr.dovis an abbreviation for the degree, order, value formatting.The
formattingspecifier 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 validformattingspecifiers in double precision are%0.16e,%24.16eor%0.16f. Theformattingspecifiers may vary with the precision of the library (single, double or quadruple).If
orderingisCHARM_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}\\ \vdots & \vdots & \vdots \\ \mathrm{nmax} & 0 & \bar{C}_{\mathrm{nmax},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}\\ 3 & 1 & \bar{C}_{3,1}\\ 3 & -1 & \bar{S}_{3,1}\\ \vdots & \vdots & \vdots \\ \mathrm{nmax} & -1 & \bar{S}_{\mathrm{nmax},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
orderingisCHARM_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
nand orderm. It must hold thatnmax <= shcs->nmax.The path to the output file in
pathnamemust already exist.Note
In the quadruple version of CHarm (
charmq_shc_write_dov()), add theQletter to theformattingspecifier. Examples of validformattingspecifiers in quadruple precision are%0.34Qe,%40.34Qeor%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
shcsup to degreenmaxto a text file whose name is the string pointed to bypathnameusing theformattingspecifier. Error reported by the function (if any) is written toerr.The
formattingspecifier 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 validformattingspecifiers in double precision are%0.16e,%24.16eor%0.16f. Theformattingspecifiers 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
nand orderm. It must hold thatnmax <= shcs->nmax.The path to the output file in
pathnamemust already exist.Note
In the quadruple version of CHarm (
charmq_shc_write_mtx()), add theQletter to theformattingspecifier. Examples of validformattingspecifiers in quadruple precision are%0.34Qe,%40.34Qeor%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)
dvup to degreenmaxof 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->muandshcs->rparameters 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)
daup to degreenmaxof 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->muandshcs->rparameters 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)
ddvup to degreenmaxbetween a signal given by spherical harmonic coefficients inshcs1andshcs2. 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->muandshcs->rparameters are not used to evaluate the differece degree variances, since this appears to be the most common way in practice. However, the values ofmuandrinshcs1andshcs2must 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)
ddaup to degreenmaxbetween a signal given by spherical harmonic coefficients inshcs1andshcs2. 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->muandshcs->rparameters are not used to evaluate the difference degree amplitudes, since this appears to be the most common way in practice. However, the values ofmuandrinshcs1andshcs2must 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
shcsto a new scaling parametermunewand 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->muandshcs->rare updated tomunewandrnew, 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#
 
- 
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 to0.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:
Order
0:charm_shc.c[0]hascharm_shc.nmax + 1columns for degrees0,1, …,charm_shc.nmax(respectively),Order
1:charm_shc.c[1]hascharm_shc.nmaxcolumns for degrees1,2, …,charm_shc.nmax(respectively),Order
2:charm_shc.c[2]hascharm_shc.nmax - 1columns for degrees2,3, …,charm_shc.nmax(respectively),…
Order
charm_shc.nmax:c[charm_shc.nmax]has1column for degreecharm_shc.nmax.
Assuming the
charm_shcstructure was initialized up to some degreeunsigned long nmaxascharm_shc *shcs = charm_shc_calloc(nmax, 1.0, 1.0);
harmonic coefficients of degree
n <= nmaxand orderm <= ncan be accessed as:shcs->c[m][n - m];
The coefficients in
charm_shc.care 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.cis not a 2D rectangular array.
- 
double **s#
 Spherical harmonic coefficients \(\bar{S}_{nm}\). The same comments as for
charm_shc.capply tocharm_shc.s, too.
- 
_Bool owner#
 If
1, the spherical harmonic coefficients incharm_shc.candcharm_shc.swere allocated by CHarm, socharm_shc_free()deallocates them. This is the case withcharm_shcreturned bycharm_shc_malloc()andcharm_shc_calloc().If
0, the coefficients incharm_shc.candcharm_shc.swere 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). This is the case withcharm_shcreturned bycharm_shc_init()andcharm_mpi_shc_init().
- 
_Bool distributed#
 If
0, the structure is not distributed, meaning that each process (be it an OpenMP or MPI process) accesses the same data throughcharm_shc.c,charm_shc.sand (if compiled with MPI support)charm_shc.local_order.If
1, the structure is distributed across MPI processes, that is, each MPI process accesses different data throughcharm_shc.c,charm_shc.sand (if compiled with MPI support)charm_shc.local_order.
Note
If CHarm was compiled without the MPI support (default),
charm_shc.distributedis always0.
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
NULLifcharm_shc.local_nchunkis0.Assume there is
k = charm_shc.local_nchunklocal chunks. The pointercharm_shc.local_orderpoints to an array of2 * kelements 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.candcharm_shc.s. The ordering of the coefficients incharm_shc.cis 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 bycharm_mpi_shc_local_ncs(). The same ordering and the number of coefficients applies to \(\bar{S}_{nm}\) incharm_shc.s.Note
Whenever creating
charm_shcthrough the CHarm’s API,charm_shc.local_orderis always a deep copy of the user’s original datalocal_order. Users can therefore safely free their originallocal_orderarray after creatingcharm_shc.
- 
MPI_Comm comm#
 MPI communicator defining the group of MPI processes to distribute the structure across.