GeographicLib  1.50.1
NormalGravity.hpp
Go to the documentation of this file.
1 /**
2  * \file NormalGravity.hpp
3  * \brief Header for GeographicLib::NormalGravity class
4  *
5  * Copyright (c) Charles Karney (2011-2019) <charles@karney.com> and licensed
6  * under the MIT/X11 License. For more information, see
7  * https://geographiclib.sourceforge.io/
8  **********************************************************************/
9 
10 #if !defined(GEOGRAPHICLIB_NORMALGRAVITY_HPP)
11 #define GEOGRAPHICLIB_NORMALGRAVITY_HPP 1
12 
15 
16 namespace GeographicLib {
17 
18  /**
19  * \brief The normal gravity of the earth
20  *
21  * "Normal" gravity refers to an idealization of the earth which is modeled
22  * as an rotating ellipsoid. The eccentricity of the ellipsoid, the rotation
23  * speed, and the distribution of mass within the ellipsoid are such that the
24  * ellipsoid is a "level ellipoid", a surface of constant potential
25  * (gravitational plus centrifugal). The acceleration due to gravity is
26  * therefore perpendicular to the surface of the ellipsoid.
27  *
28  * Because the distribution of mass within the ellipsoid is unspecified, only
29  * the potential exterior to the ellipsoid is well defined. In this class,
30  * the mass is assumed to be to concentrated on a "focal disc" of radius,
31  * (<i>a</i><sup>2</sup> &minus; <i>b</i><sup>2</sup>)<sup>1/2</sup>, where
32  * \e a is the equatorial radius of the ellipsoid and \e b is its polar
33  * semi-axis. In the case of an oblate ellipsoid, the mass is concentrated
34  * on a "focal rod" of length 2(<i>b</i><sup>2</sup> &minus;
35  * <i>a</i><sup>2</sup>)<sup>1/2</sup>. As a result the potential is well
36  * defined everywhere.
37  *
38  * There is a closed solution to this problem which is implemented here.
39  * Series "approximations" are only used to evaluate certain combinations of
40  * elementary functions where use of the closed expression results in a loss
41  * of accuracy for small arguments due to cancellation of the leading terms.
42  * However these series include sufficient terms to give full machine
43  * precision.
44  *
45  * Although the formulation used in this class applies to ellipsoids with
46  * arbitrary flattening, in practice, its use should be limited to about
47  * <i>b</i>/\e a &isin; [0.01, 100] or \e f &isin; [&minus;99, 0.99].
48  *
49  * Definitions:
50  * - <i>V</i><sub>0</sub>, the gravitational contribution to the normal
51  * potential;
52  * - &Phi;, the rotational contribution to the normal potential;
53  * - \e U = <i>V</i><sub>0</sub> + &Phi;, the total potential;
54  * - <b>&Gamma;</b> = &nabla;<i>V</i><sub>0</sub>, the acceleration due to
55  * mass of the earth;
56  * - <b>f</b> = &nabla;&Phi;, the centrifugal acceleration;
57  * - <b>&gamma;</b> = &nabla;\e U = <b>&Gamma;</b> + <b>f</b>, the normal
58  * acceleration;
59  * - \e X, \e Y, \e Z, geocentric coordinates;
60  * - \e x, \e y, \e z, local cartesian coordinates used to denote the east,
61  * north and up directions.
62  *
63  * References:
64  * - C. Somigliana, Teoria generale del campo gravitazionale dell'ellissoide
65  * di rotazione, Mem. Soc. Astron. Ital, <b>4</b>, 541--599 (1929).
66  * - W. A. Heiskanen and H. Moritz, Physical Geodesy (Freeman, San
67  * Francisco, 1967), Secs. 1-19, 2-7, 2-8 (2-9, 2-10), 6-2 (6-3).
68  * - B. Hofmann-Wellenhof, H. Moritz, Physical Geodesy (Second edition,
69  * Springer, 2006) https://doi.org/10.1007/978-3-211-33545-1
70  * - H. Moritz, Geodetic Reference System 1980, J. Geodesy 54(3), 395-405
71  * (1980) https://doi.org/10.1007/BF02521480
72  *
73  * For more information on normal gravity see \ref normalgravity.
74  *
75  * Example of use:
76  * \include example-NormalGravity.cpp
77  **********************************************************************/
78 
80  private:
81  static const int maxit_ = 20;
82  typedef Math::real real;
83  friend class GravityModel;
84  real _a, _GM, _omega, _f, _J2, _omega2, _aomega2;
85  real _e2, _ep2, _b, _E, _U0, _gammae, _gammap, _Q0, _k, _fstar;
86  Geocentric _earth;
87  static real atanzz(real x, bool alt) {
88  // This routine obeys the identity
89  // atanzz(x, alt) = atanzz(-x/(1+x), !alt)
90  //
91  // Require x >= -1. Best to call with alt, s.t. x >= 0; this results in
92  // a call to atan, instead of asin, or to asinh, instead of atanh.
93  using std::sqrt; using std::abs; using std::atan; using std::asin;
94  real z = sqrt(abs(x));
95  return x == 0 ? 1 :
96  (alt ?
97  (!(x < 0) ? Math::asinh(z) : asin(z)) / sqrt(abs(x) / (1 + x)) :
98  (!(x < 0) ? atan(z) : Math::atanh(z)) / z);
99  }
100  static real atan7series(real x);
101  static real atan5series(real x);
102  static real Qf(real x, bool alt);
103  static real Hf(real x, bool alt);
104  static real QH3f(real x, bool alt);
105  real Jn(int n) const;
106  void Initialize(real a, real GM, real omega, real f_J2, bool geometricp);
107  public:
108 
109  /** \name Setting up the normal gravity
110  **********************************************************************/
111  ///@{
112  /**
113  * Constructor for the normal gravity.
114  *
115  * @param[in] a equatorial radius (meters).
116  * @param[in] GM mass constant of the ellipsoid
117  * (meters<sup>3</sup>/seconds<sup>2</sup>); this is the product of \e G
118  * the gravitational constant and \e M the mass of the earth (usually
119  * including the mass of the earth's atmosphere).
120  * @param[in] omega the angular velocity (rad s<sup>&minus;1</sup>).
121  * @param[in] f_J2 either the flattening of the ellipsoid \e f or the
122  * the dynamical form factor \e J2.
123  * @param[out] geometricp if true (the default), then \e f_J2 denotes the
124  * flattening, else it denotes the dynamical form factor \e J2.
125  * @exception if \e a is not positive or if the other parameters do not
126  * obey the restrictions given below.
127  *
128  * The shape of the ellipsoid can be given in one of two ways:
129  * - geometrically (\e geomtricp = true), the ellipsoid is defined by the
130  * flattening \e f = (\e a &minus; \e b) / \e a, where \e a and \e b are
131  * the equatorial radius and the polar semi-axis. The parameters should
132  * obey \e a &gt; 0, \e f &lt; 1. There are no restrictions on \e GM or
133  * \e omega, in particular, \e GM need not be positive.
134  * - physically (\e geometricp = false), the ellipsoid is defined by the
135  * dynamical form factor <i>J</i><sub>2</sub> = (\e C &minus; \e A) /
136  * <i>Ma</i><sup>2</sup>, where \e A and \e C are the equatorial and
137  * polar moments of inertia and \e M is the mass of the earth. The
138  * parameters should obey \e a &gt; 0, \e GM &gt; 0 and \e J2 &lt; 1/3
139  * &minus; (<i>omega</i><sup>2</sup><i>a</i><sup>3</sup>/<i>GM</i>)
140  * 8/(45&pi;). There is no restriction on \e omega.
141  **********************************************************************/
142  NormalGravity(real a, real GM, real omega, real f_J2,
143  bool geometricp = true);
144 
145  /**
146  * A default constructor for the normal gravity. This sets up an
147  * uninitialized object and is used by GravityModel which constructs this
148  * object before it has read in the parameters for the reference ellipsoid.
149  **********************************************************************/
150  NormalGravity() : _a(-1) {}
151  ///@}
152 
153  /** \name Compute the gravity
154  **********************************************************************/
155  ///@{
156  /**
157  * Evaluate the gravity on the surface of the ellipsoid.
158  *
159  * @param[in] lat the geographic latitude (degrees).
160  * @return &gamma; the acceleration due to gravity, positive downwards
161  * (m s<sup>&minus;2</sup>).
162  *
163  * Due to the axial symmetry of the ellipsoid, the result is independent of
164  * the value of the longitude. This acceleration is perpendicular to the
165  * surface of the ellipsoid. It includes the effects of the earth's
166  * rotation.
167  **********************************************************************/
168  Math::real SurfaceGravity(real lat) const;
169 
170  /**
171  * Evaluate the gravity at an arbitrary point above (or below) the
172  * ellipsoid.
173  *
174  * @param[in] lat the geographic latitude (degrees).
175  * @param[in] h the height above the ellipsoid (meters).
176  * @param[out] gammay the northerly component of the acceleration
177  * (m s<sup>&minus;2</sup>).
178  * @param[out] gammaz the upward component of the acceleration
179  * (m s<sup>&minus;2</sup>); this is usually negative.
180  * @return \e U the corresponding normal potential
181  * (m<sup>2</sup> s<sup>&minus;2</sup>).
182  *
183  * Due to the axial symmetry of the ellipsoid, the result is independent of
184  * the value of the longitude and the easterly component of the
185  * acceleration vanishes, \e gammax = 0. The function includes the effects
186  * of the earth's rotation. When \e h = 0, this function gives \e gammay =
187  * 0 and the returned value matches that of NormalGravity::SurfaceGravity.
188  **********************************************************************/
189  Math::real Gravity(real lat, real h, real& gammay, real& gammaz)
190  const;
191 
192  /**
193  * Evaluate the components of the acceleration due to gravity and the
194  * centrifugal acceleration in geocentric coordinates.
195  *
196  * @param[in] X geocentric coordinate of point (meters).
197  * @param[in] Y geocentric coordinate of point (meters).
198  * @param[in] Z geocentric coordinate of point (meters).
199  * @param[out] gammaX the \e X component of the acceleration
200  * (m s<sup>&minus;2</sup>).
201  * @param[out] gammaY the \e Y component of the acceleration
202  * (m s<sup>&minus;2</sup>).
203  * @param[out] gammaZ the \e Z component of the acceleration
204  * (m s<sup>&minus;2</sup>).
205  * @return \e U = <i>V</i><sub>0</sub> + &Phi; the sum of the
206  * gravitational and centrifugal potentials
207  * (m<sup>2</sup> s<sup>&minus;2</sup>).
208  *
209  * The acceleration given by <b>&gamma;</b> = &nabla;\e U =
210  * &nabla;<i>V</i><sub>0</sub> + &nabla;&Phi; = <b>&Gamma;</b> + <b>f</b>.
211  **********************************************************************/
212  Math::real U(real X, real Y, real Z,
213  real& gammaX, real& gammaY, real& gammaZ) const;
214 
215  /**
216  * Evaluate the components of the acceleration due to the gravitational
217  * force in geocentric coordinates.
218  *
219  * @param[in] X geocentric coordinate of point (meters).
220  * @param[in] Y geocentric coordinate of point (meters).
221  * @param[in] Z geocentric coordinate of point (meters).
222  * @param[out] GammaX the \e X component of the acceleration due to the
223  * gravitational force (m s<sup>&minus;2</sup>).
224  * @param[out] GammaY the \e Y component of the acceleration due to the
225  * @param[out] GammaZ the \e Z component of the acceleration due to the
226  * gravitational force (m s<sup>&minus;2</sup>).
227  * @return <i>V</i><sub>0</sub> the gravitational potential
228  * (m<sup>2</sup> s<sup>&minus;2</sup>).
229  *
230  * This function excludes the centrifugal acceleration and is appropriate
231  * to use for space applications. In terrestrial applications, the
232  * function NormalGravity::U (which includes this effect) should usually be
233  * used.
234  **********************************************************************/
235  Math::real V0(real X, real Y, real Z,
236  real& GammaX, real& GammaY, real& GammaZ) const;
237 
238  /**
239  * Evaluate the centrifugal acceleration in geocentric coordinates.
240  *
241  * @param[in] X geocentric coordinate of point (meters).
242  * @param[in] Y geocentric coordinate of point (meters).
243  * @param[out] fX the \e X component of the centrifugal acceleration
244  * (m s<sup>&minus;2</sup>).
245  * @param[out] fY the \e Y component of the centrifugal acceleration
246  * (m s<sup>&minus;2</sup>).
247  * @return &Phi; the centrifugal potential (m<sup>2</sup>
248  * s<sup>&minus;2</sup>).
249  *
250  * &Phi; is independent of \e Z, thus \e fZ = 0. This function
251  * NormalGravity::U sums the results of NormalGravity::V0 and
252  * NormalGravity::Phi.
253  **********************************************************************/
254  Math::real Phi(real X, real Y, real& fX, real& fY) const;
255  ///@}
256 
257  /** \name Inspector functions
258  **********************************************************************/
259  ///@{
260  /**
261  * @return true if the object has been initialized.
262  **********************************************************************/
263  bool Init() const { return _a > 0; }
264 
265  /**
266  * @return \e a the equatorial radius of the ellipsoid (meters). This is
267  * the value used in the constructor.
268  **********************************************************************/
270  { return Init() ? _a : Math::NaN(); }
271 
272  /**
273  * @return \e GM the mass constant of the ellipsoid
274  * (m<sup>3</sup> s<sup>&minus;2</sup>). This is the value used in the
275  * constructor.
276  **********************************************************************/
278  { return Init() ? _GM : Math::NaN(); }
279 
280  /**
281  * @return <i>J</i><sub><i>n</i></sub> the dynamical form factors of the
282  * ellipsoid.
283  *
284  * If \e n = 2 (the default), this is the value of <i>J</i><sub>2</sub>
285  * used in the constructor. Otherwise it is the zonal coefficient of the
286  * Legendre harmonic sum of the normal gravitational potential. Note that
287  * <i>J</i><sub><i>n</i></sub> = 0 if \e n is odd. In most gravity
288  * applications, fully normalized Legendre functions are used and the
289  * corresponding coefficient is <i>C</i><sub><i>n</i>0</sub> =
290  * &minus;<i>J</i><sub><i>n</i></sub> / sqrt(2 \e n + 1).
291  **********************************************************************/
293  { return Init() ? ( n == 2 ? _J2 : Jn(n)) : Math::NaN(); }
294 
295  /**
296  * @return &omega; the angular velocity of the ellipsoid (rad
297  * s<sup>&minus;1</sup>). This is the value used in the constructor.
298  **********************************************************************/
300  { return Init() ? _omega : Math::NaN(); }
301 
302  /**
303  * @return <i>f</i> the flattening of the ellipsoid (\e a &minus; \e b)/\e
304  * a.
305  **********************************************************************/
307  { return Init() ? _f : Math::NaN(); }
308 
309  /**
310  * @return &gamma;<sub>e</sub> the normal gravity at equator (m
311  * s<sup>&minus;2</sup>).
312  **********************************************************************/
314  { return Init() ? _gammae : Math::NaN(); }
315 
316  /**
317  * @return &gamma;<sub>p</sub> the normal gravity at poles (m
318  * s<sup>&minus;2</sup>).
319  **********************************************************************/
321  { return Init() ? _gammap : Math::NaN(); }
322 
323  /**
324  * @return <i>f*</i> the gravity flattening (&gamma;<sub>p</sub> &minus;
325  * &gamma;<sub>e</sub>) / &gamma;<sub>e</sub>.
326  **********************************************************************/
328  { return Init() ? _fstar : Math::NaN(); }
329 
330  /**
331  * @return <i>U</i><sub>0</sub> the constant normal potential for the
332  * surface of the ellipsoid (m<sup>2</sup> s<sup>&minus;2</sup>).
333  **********************************************************************/
335  { return Init() ? _U0 : Math::NaN(); }
336 
337  /**
338  * @return the Geocentric object used by this instance.
339  **********************************************************************/
340  const Geocentric& Earth() const { return _earth; }
341 
342  /**
343  * \deprecated An old name for EquatorialRadius().
344  **********************************************************************/
345  // GEOGRAPHICLIB_DEPRECATED("Use EquatorialRadius()")
346  Math::real MajorRadius() const { return EquatorialRadius(); }
347  ///@}
348 
349  /**
350  * A global instantiation of NormalGravity for the WGS84 ellipsoid.
351  **********************************************************************/
352  static const NormalGravity& WGS84();
353 
354  /**
355  * A global instantiation of NormalGravity for the GRS80 ellipsoid.
356  **********************************************************************/
357  static const NormalGravity& GRS80();
358 
359  /**
360  * Compute the flattening from the dynamical form factor.
361  *
362  * @param[in] a equatorial radius (meters).
363  * @param[in] GM mass constant of the ellipsoid
364  * (meters<sup>3</sup>/seconds<sup>2</sup>); this is the product of \e G
365  * the gravitational constant and \e M the mass of the earth (usually
366  * including the mass of the earth's atmosphere).
367  * @param[in] omega the angular velocity (rad s<sup>&minus;1</sup>).
368  * @param[in] J2 the dynamical form factor.
369  * @return \e f the flattening of the ellipsoid.
370  *
371  * This routine requires \e a &gt; 0, \e GM &gt; 0, \e J2 &lt; 1/3 &minus;
372  * <i>omega</i><sup>2</sup><i>a</i><sup>3</sup>/<i>GM</i> 8/(45&pi;). A
373  * NaN is returned if these conditions do not hold. The restriction to
374  * positive \e GM is made because for negative \e GM two solutions are
375  * possible.
376  **********************************************************************/
377  static Math::real J2ToFlattening(real a, real GM, real omega, real J2);
378 
379  /**
380  * Compute the dynamical form factor from the flattening.
381  *
382  * @param[in] a equatorial radius (meters).
383  * @param[in] GM mass constant of the ellipsoid
384  * (meters<sup>3</sup>/seconds<sup>2</sup>); this is the product of \e G
385  * the gravitational constant and \e M the mass of the earth (usually
386  * including the mass of the earth's atmosphere).
387  * @param[in] omega the angular velocity (rad s<sup>&minus;1</sup>).
388  * @param[in] f the flattening of the ellipsoid.
389  * @return \e J2 the dynamical form factor.
390  *
391  * This routine requires \e a &gt; 0, \e GM &ne; 0, \e f &lt; 1. The
392  * values of these parameters are not checked.
393  **********************************************************************/
394  static Math::real FlatteningToJ2(real a, real GM, real omega, real f);
395  };
396 
397 } // namespace GeographicLib
398 
399 #endif // GEOGRAPHICLIB_NORMALGRAVITY_HPP
#define GEOGRAPHICLIB_EXPORT
Definition: Constants.hpp:92
GeographicLib::Math::real real
Definition: GeodSolve.cpp:31
The normal gravity of the earth.
Math::real Flattening() const
Mathematical functions needed by GeographicLib.
Definition: Math.hpp:98
Math::real SurfacePotential() const
Geocentric coordinates
Definition: Geocentric.hpp:67
Math::real MassConstant() const
Math::real GravityFlattening() const
Namespace for GeographicLib.
Definition: Accumulator.cpp:12
static T NaN()
Definition: Math.cpp:389
Header for GeographicLib::Geocentric class.
static T asinh(T x)
Definition: Math.cpp:102
Math::real EquatorialGravity() const
Model of the earth&#39;s gravity field.
Math::real AngularVelocity() const
Math::real EquatorialRadius() const
Header for GeographicLib::Constants class.
Math::real DynamicalFormFactor(int n=2) const
Math::real PolarGravity() const
const Geocentric & Earth() const
Math::real MajorRadius() const