File: griddedData2PotentialCoefficients.cpp

package info (click to toggle)
groops 0%2Bgit20250907%2Bds-1
  • links: PTS, VCS
  • area: non-free
  • in suites: forky, sid
  • size: 11,140 kB
  • sloc: cpp: 135,607; fortran: 1,603; makefile: 20
file content (139 lines) | stat: -rw-r--r-- 6,497 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/***********************************************/
/**
* @file griddedData2PotentialCoefficients.cpp
*
* @brief Estimate potential coefficients from gridded gravity field functionals.
* With quadrature formular or
* least squares adjustment with block diagonal normals (order by order).
*
* @author Annette Eicker
* @author Torsten Mayer-Guerr
* @date 2005-05-01
*/
/***********************************************/

// Latex documentation
#define DOCSTRING docstring
static const char *docstring = R"(
This program estimate potential coefficients from \configFile{inputfileGriddedData}{griddedData}
gravity field functionals. It used a simple quadrature formular
\begin{equation}
  c_{nm} = \frac{1}{4\pi}\frac{R}{GM} \sum_i f_i \left(\frac{r_i}{R}\right)^{n+1} k_n C_{nm}(\lambda_i,\vartheta_i)\,\Delta\Phi_i
\end{equation}
or a \config{leastSquares} adjustment with block diagonal normal matrix (order by order).
For the latter one the data must be regular distributed.

The \config{value}s $f_i$ and the \config{weight}s $\Delta\Phi_i$ are expressions
using the common data variables for grids, see \reference{dataVariables}{general.parser:dataVariables}.
Multiple \configFile{outputfilePotentialCoefficients}{potentialCoefficients} can be estimated in one step.
For each an indivdual \config{value} must be specified.
The type of the gridded data (e.g gravity anomalies or geoid heights)
must be set with \configClass{kernel}{kernelType} $k_n$.

The expansion is limited in the range between \config{minDegree}
and \config{maxDegree} inclusively. The coefficients are related
to the reference radius~\config{R} and the Earth gravitational constant \config{GM}.

For irregular distributed data and using the full variance covariance matrix use
\program{NormalsSolverVCE} together with \configClass{oberservation:terrestrial}{observationType:terrestrial}
and \configClass{parametrizationGravity:sphericalHarmonics}{parametrizationGravityType:sphericalHarmonics}.

See also \program{GriddedDataTimeSeries2PotentialCoefficients}.
)";

/***********************************************/

#include "programs/program.h"
#include "parser/dataVariables.h"
#include "files/fileSphericalHarmonics.h"
#include "files/fileGriddedData.h"
#include "classes/kernel/kernel.h"
#include "misc/miscGriddedData.h"

/***** CLASS ***********************************/

/** @brief Estimate potential coefficients from gridded gravity field functionals.
* With quadrature formular or
* least squares adjustment with block diagonal normals (order by order).
* @ingroup programsGroup */
class GriddedData2PotentialCoefficients
{
public:
  void run(Config &config, Parallel::CommunicatorPtr comm);
};

GROOPS_REGISTER_PROGRAM(GriddedData2PotentialCoefficients, PARALLEL, "Estimate potential coefficients from gridded gravity field functionals", Grid, PotentialCoefficients)

/***********************************************/

void GriddedData2PotentialCoefficients::run(Config &config, Parallel::CommunicatorPtr comm)
{
  try
  {
    std::vector<FileName> fileNameOut;
    FileName              fileNameGrid;
    std::vector<ExpressionVariablePtr> exprValue;
    ExpressionVariablePtr exprArea;
    KernelPtr             kernel;
    Double                GM, R;
    UInt                  minDegree, maxDegree;
    Bool                  useLeastSquares;

    readConfig(config, "outputfilePotentialCoefficients", fileNameOut,     Config::MUSTSET,  "",      "one file for each value expression");
    readConfig(config, "inputfileGriddedData",            fileNameGrid,    Config::MUSTSET,  "",      "");
    readConfig(config, "value",                           exprValue,       Config::MUSTSET,  "data0", "expression to compute values (input columns are named data0, data1, ...)");
    readConfig(config, "weight",                          exprArea,        Config::MUSTSET,  "area",  "expression to compute values (input columns are named data0, data1, ...)");
    readConfig(config, "kernel",                          kernel,          Config::MUSTSET,  "",      "data type of input values");
    readConfig(config, "minDegree",                       minDegree,       Config::DEFAULT,  "0",     "");
    readConfig(config, "maxDegree",                       maxDegree,       Config::MUSTSET,  "",      "");
    readConfig(config, "GM",                              GM,              Config::DEFAULT,  STRING_DEFAULT_GM, "Geocentric gravitational constant");
    readConfig(config, "R",                               R,               Config::DEFAULT,  STRING_DEFAULT_R,  "reference radius");
    readConfig(config, "leastSquares",                    useLeastSquares, Config::DEFAULT,  "0",     "false: quadrature formular, true: least squares adjustment order by order");
    if(isCreateSchema(config)) return;

    if(fileNameOut.size() != exprValue.size())
      throw(Exception("number of outputfilePotentialCoefficients must agree with number of value expressions"));

    // reading grids
    // -------------
    logStatus<<"read grid from file <"<<fileNameGrid<<">"<<Log::endl;
    GriddedData grid;
    readFileGriddedData(fileNameGrid, grid);
    MiscGriddedData::printStatistics(grid);

    // evaluate expressions
    // --------------------
    VariableList varList;
    addDataVariables(grid, varList);
    std::for_each(exprValue.begin(), exprValue.end(), [&](auto expr) {expr->simplify(varList);});
    exprArea ->simplify(varList);
    std::vector<std::vector<Double>> values(exprValue.size(), std::vector<Double>(grid.points.size()));
    for(UInt i=0; i<grid.points.size(); i++)
    {
      evaluateDataVariables(grid, i, varList);
      for(UInt k=0; k<exprValue.size(); k++)
        values.at(k).at(i) = exprValue.at(k)->evaluate(varList);
      grid.areas.at(i) = exprArea->evaluate(varList);
    }
    grid.values = values;

    // spherical harmonic analysis
    // ---------------------------
    std::vector<SphericalHarmonics> harmonics = MiscGriddedData::analysisSphericalHarmonics(grid, kernel, minDegree, maxDegree, GM, R, useLeastSquares, comm);

    // write potential coefficients
    // ----------------------------
    if(Parallel::isMaster(comm))
      for(UInt k=0; k<harmonics.size(); k++)
      {
        logStatus<<"write potential coefficients to file <"<<fileNameOut.at(k)<<">"<<Log::endl;
        writeFileSphericalHarmonics(fileNameOut.at(k), harmonics.at(k));
      }
  }
  catch(std::exception &e)
  {
    GROOPS_RETHROW(e)
  }
}

/***********************************************/