示例#1
0
        /// <summary>
        /// Evaluate the components of the gravity anomaly vector using the spherical approximation.
        /// </summary>
        /// <param name="lat">the geographic latitude (degrees).</param>
        /// <param name="lon">the geographic longitude (degrees).</param>
        /// <param name="h">the height above the ellipsoid (meters).</param>
        /// <returns>
        /// <list type="bullet">
        /// <item><i>Dg01</i>, the gravity anomaly (m s^−2).</item>
        /// <item><i>xi</i>, the northerly component of the deflection of the vertical (degrees).</item>
        /// <item><i>eta</i>, the easterly component of the deflection of the vertical (degrees).</item>
        /// </list>
        /// </returns>
        /// <remarks>
        /// The spherical approximation (see Heiskanen and Moritz, Sec 2-14) is used so that the results of
        /// the NGA codes are reproduced accurately. approximations used here.
        /// Details are given in
        /// <a href="https://geographiclib.sourceforge.io/html/gravity.html#gravitygeoid">Details of the geoid height and anomaly calculations</a>.
        /// </remarks>
        public (double Dg01, double xi, double eta) SphericalAnomaly(double lat, double lon, double h)
        {
            Span <double> M = stackalloc double[Geocentric.dim2_];

            var(X, Y, Z) = _earth.Earth.IntForward(lat, lon, h, M);
            double
                T = InternalT(X, Y, Z, out var deltax, out var deltay, out var deltaz, true, false),
                clam = M[3], slam = -M[0],
                P = Hypot(X, Y),
                R = Hypot(P, Z),
            // psi is geocentric latitude
                cpsi = R != 0 ? P / R : M[7],
                spsi = R != 0 ? Z / R : M[8];
            // Rotate cartesian into spherical coordinates
            Span <double> MC = stackalloc double[Geocentric.dim2_];

            Geocentric.Rotation(spsi, cpsi, slam, clam, MC);
            Geocentric.Unrotate(MC, deltax, deltay, deltaz, out deltax, out deltay, out deltaz);
            // H+M, Eq 2-151c
            var Dg01 = -deltaz - 2 * T / R;

            var(_, gammaX, gammaY, gammaZ) = _earth.U(X, Y, Z);
            var gamma = Hypot(Hypot(gammaX, gammaY), gammaZ);
            var xi    = -(deltay / gamma) / Degree;
            var eta   = -(deltax / gamma) / Degree;

            return(Dg01, xi, eta);
        }
示例#2
0
        /// <summary>
        /// Evaluate the gravity at an arbitrary point above (or below) the ellipsoid.
        /// </summary>
        /// <param name="lat">the geographic latitude (degrees).</param>
        /// <param name="lon">the geographic longitude (degrees).</param>
        /// <param name="h">the height above the ellipsoid (meters).</param>
        /// <returns>
        /// <list type="bullet">
        /// <item><i>W</i>, the sum of the gravitational and centrifugal potentials (m^2 s^−2).</item>
        /// <item><i>gx</i>, the easterly component of the acceleration (m s^−2).</item>
        /// <item><i>gy</i>, the northerly component of the acceleration (m s^−2).</item>
        /// <item><i>gz</i>, the upward component of the acceleration (m s^−2); this is usually negative.</item>
        /// </list>
        /// </returns>
        /// <remarks>
        /// The function includes the effects of the earth's rotation.
        /// </remarks>
        public (double W, double gx, double gy, double gz) Gravity(double lat, double lon, double h)
        {
            Span <double> M = stackalloc double[Geocentric.dim2_];

            var(X, Y, Z)          = _earth.Earth.IntForward(lat, lon, h, M);
            var(Wres, gx, gy, gz) = W(X, Y, Z);
            Geocentric.Unrotate(M, gx, gy, gz, out gx, out gy, out gz);
            return(Wres, gx, gy, gz);
        }
示例#3
0
        /// <summary>
        /// Evaluate the gravity disturbance vector at an arbitrary point above (or below) the ellipsoid.
        /// </summary>
        /// <param name="lat">the geographic latitude (degrees).</param>
        /// <param name="lon">the geographic longitude (degrees).</param>
        /// <param name="h">the height above the ellipsoid (meters).</param>
        /// <returns>
        /// <list type="bullet">
        /// <item><i>T</i>, the corresponding disturbing potential (m2 s−2).</item>
        /// <item><i>deltax</i>, the easterly component of the disturbance vector (m s^−2).</item>
        /// <item><i>deltay</i>, the northerly component of the disturbance vector (m s^−2).</item>
        /// <item><i>deltaz</i>, the upward component of the disturbance vector (m s^−2).</item>
        /// </list>
        /// </returns>
        public (double T, double deltax, double deltay, double deltaz) Disturbance(double lat, double lon, double h)
        {
            Span <double> M = stackalloc double[Geocentric.dim2_];

            var(X, Y, Z) = _earth.Earth.IntForward(lat, lon, h, M);
            var Tres = InternalT(X, Y, Z, out var deltax, out var deltay, out var deltaz, true, true);

            Geocentric.Unrotate(M, deltax, deltay, deltaz, out deltax, out deltay, out deltaz);
            return(Tres, deltax, deltay, deltaz);
        }
示例#4
0
        /// <summary>
        /// Evaluate the gravity.
        /// </summary>
        /// <param name="lon">the geographic longitude (degrees).</param>
        /// <returns>
        /// <list type="bullet">
        /// <item><i>W</i>, the sum of the gravitational and centrifugal potentials (m^2 s^−2).</item>
        /// <item><i>gx</i>, the easterly component of the acceleration (m s^−2).</item>
        /// <item><i>gy</i>, the northerly component of the acceleration (m s^−2).</item>
        /// <item><i>gz</i>, the upward component of the acceleration (m s^−2); this is usually negative.</item>
        /// </list>
        /// </returns>
        /// <remarks>The function includes the effects of the earth's rotation.</remarks>
        public (double W, double gx, double gy, double gz) Gravity(double lon)
        {
            Span <double> M = stackalloc double[Geocentric.dim2_];

            SinCosd(lon, out var slam, out var clam);
            var(Wres, gx, gy, gz) = W(slam, clam);
            Geocentric.Rotation(_sphi, _cphi, slam, clam, M);
            Geocentric.Unrotate(M, gx, gy, gz, out gx, out gy, out gz);
            return(Wres, gx, gy, gz);
        }
示例#5
0
        /// <summary>
        /// Evaluate the gravity disturbance vector.
        /// </summary>
        /// <param name="lon">the geographic longitude (degrees).</param>
        /// <returns>
        /// <list type="bullet">
        /// <item><i>T</i>, the corresponding disturbing potential (m2 s−2).</item>
        /// <item><i>deltax</i>, the easterly component of the disturbance vector (m s^−2).</item>
        /// <item><i>deltay</i>, the northerly component of the disturbance vector (m s^−2).</item>
        /// <item><i>deltaz</i>, the upward component of the disturbance vector (m s^−2).</item>
        /// </list>
        /// </returns>
        public (double T, double deltax, double deltay, double deltaz) Disturbance(double lon)
        {
            Span <double> M = stackalloc double[Geocentric.dim2_];

            SinCosd(lon, out var slam, out var clam);
            var Tres = InternalT(slam, clam, out var deltax, out var deltay, out var deltaz, true, true);

            Geocentric.Rotation(_sphi, _cphi, slam, clam, M);
            Geocentric.Unrotate(M, deltax, deltay, deltaz, out deltax, out deltay, out deltaz);
            return(Tres, deltax, deltay, deltaz);
        }
示例#6
0
        private (double Bx, double By, double Bz) Field(double t, double lat, double lon, double h, bool diffp,
                                                        out double Bxt, out double Byt, out double Bzt)
        {
            Bxt = Byt = Bzt = default;

            Span <double> M = stackalloc double[Geocentric.dim2_];

            var(X, Y, Z) = _earth.IntForward(lat, lon, h, M);
            // Components in geocentric basis
            // initial values to suppress warning
            var(BX, BY, BZ) = FieldGeocentric(t, X, Y, Z, out var BXt, out var BYt, out var BZt);
            if (diffp)
            {
                Geocentric.Unrotate(M, BXt, BYt, BZt, out Bxt, out Byt, out Bzt);
            }
            Geocentric.Unrotate(M, BX, BY, BZ, out var Bx, out var By, out var Bz);

            return(Bx, By, Bz);
        }
        private (double Bx, double By, double Bz) Field(double lon, bool diffp,
                                                        out double Bxt, out double Byt, out double Bzt)
        {
            Bxt = Byt = Bzt = default;

            SinCosd(lon, out var slam, out var clam);
            Span <double> M = stackalloc double[Geocentric.dim2_];

            Geocentric.Rotation(_sphi, _cphi, slam, clam, M);

            var(BX, BY, BZ) = FieldGeocentric(slam, clam, out var BXt, out var BYt, out var BZt);
            if (diffp)
            {
                Geocentric.Unrotate(M, BXt, BYt, BZt, out Bxt, out Byt, out Bzt);
            }
            Geocentric.Unrotate(M, BX, BY, BZ, out var Bx, out var By, out var Bz);

            return(Bx, By, Bz);
        }
示例#8
0
        /// <summary>
        /// Evaluate the components of the gravity anomaly vector using the spherical approximation.
        /// </summary>
        /// <param name="lon">the geographic longitude (degrees).</param>   w
        /// <returns>
        /// <list type="bullet">
        /// <item><i>Dg01</i>, the gravity anomaly (m s^−2).</item>
        /// <item><i>xi</i>, the northerly component of the deflection of the vertical (degrees).</item>
        /// <item><i>eta</i>, the easterly component of the deflection of the vertical (degrees).</item>
        /// </list>
        /// </returns>
        /// <remarks>
        /// The spherical approximation (see Heiskanen and Moritz, Sec 2-14) is used so that the results of the NGA codes are
        /// reproduced accurately. approximations used here.
        /// Details are given in
        /// <a href="https://geographiclib.sourceforge.io/html/gravity.html#gravitygeoid">Details of the geoid height and anomaly calculations</a>.
        /// </remarks>
        public (double Dg01, double xi, double eta) SphericalAnomaly(double lon)
        {
            if (_caps.HasFlag(GravityFlags.SphericalAnomaly))
            {
                return(double.NaN, double.NaN, double.NaN);
            }

            SinCosd(lon, out var slam, out var clam);
            double
                deltax, deltay, deltaz,
                T = InternalT(slam, clam, out deltax, out deltay, out deltaz, true, false);
            // Rotate cartesian into spherical coordinates
            Span <double> MC = stackalloc double[Geocentric.dim2_];

            Geocentric.Rotation(_spsi, _cpsi, slam, clam, MC);
            Geocentric.Unrotate(MC, deltax, deltay, deltaz, out deltax, out deltay, out deltaz);
            // H+M, Eq 2-151c
            var Dg01 = -deltaz - 2 * T * _invR;
            var xi   = -(deltay / _gamma) / Degree;
            var eta  = -(deltax / _gamma) / Degree;

            return(Dg01, xi, eta);
        }