예제 #1
0
def test_potential():
    ell = LevelEllipsoid('GRS80')

    n_test = 100  # * 2
    r_ = np.geomspace(ell.b, 1e8, num=n_test)
    r_ = np.append(-r_[::-1], r_)
    x, y, z = np.meshgrid(r_, r_, r_, indexing='ij')

    sphlat, _, radius = transform.cartesian_to_spherical(x, y, z)
    cond = radius < ell.polar_equation(sphlat)

    x_ = np.ma.masked_where(cond, x).compressed()
    y_ = np.ma.masked_where(cond, y).compressed()
    z_ = np.ma.masked_where(cond, z).compressed()

    sphlat, _, radius = transform.cartesian_to_spherical(x_, y_, z_)
    rlat, _, u = transform.cartesian_to_ellipsoidal(x_, y_, z_, ell=ell)
    gravity_potential_ell = ell.gravity_potential(rlat, u)
    gravity_potential_sph = ell.gravity_potential_sph(sphlat, radius)

    np.testing.assert_almost_equal(
        gravity_potential_sph,
        gravity_potential_ell, decimal=4)

    gravitational_potential_ell = ell.gravitational_potential(rlat, u)
    gravitational_potential_sph = ell.gravitational_potential_sph(
        sphlat, radius)

    np.testing.assert_almost_equal(
        gravitational_potential_sph,
        gravitational_potential_ell, decimal=4)
예제 #2
0
    def gravity_disturbance(self,
                            lat: u.deg,
                            lon: u.deg,
                            r: u.m,
                            lmax: int = None) -> u.mGal:
        """Return gravity disturbance.

        The gravity disturbance is defined as the magnitude of the gradient of
        the potential at a given point minus the magnitude of the gradient of
        the normal potential at the same point (eqs. 87 and 121 − 124 of STR09/02).

        Parameters
        ----------
        lat : ~astropy.units.Quantity
            Spherical latitude.
        lon : ~astropy.units.Quantity
            Spherical longitude.
        r : ~astropy.units.Quantity
            Radial distance.
        lmax : int, optional
            Maximum degree of the coefficients. Default is `None` (use all
            the coefficients).

        Returns
        -------
        ~astropy.units.Quantity
            Gravity disturbance.
        """
        rlat, _, u_ax = _transform.cartesian_to_ellipsoidal(
            *_transform.spherical_to_cartesian(lat, lon, r), self._ell)

        g = self._gravity.gradient(lat, lon, r, lmax)[-1]
        gamma = self._ell.normal_gravity(rlat, u_ax)

        return g - gamma
예제 #3
0
    def height_anomaly_ell(self,
                           lat: u.deg,
                           lon: u.deg,
                           r: u.m,
                           ref_pot: u.m**2 / u.s**2 = None,
                           lmax=None) -> u.m:
        """Return height anomaly above the ellispoid.

        The height anomaly can be generalised to a 3-d function, (sometimes
        called "generalised pseudo-height-anomaly"). Here it can be calculated
        on (h=0) or above (h>0) the ellipsoid, approximated by Bruns’ formula
        (eqs. 78 and 118 of STR09/02)

        Parameters
        ----------
        lat : ~astropy.units.Quantity
            Spherical latitude.
        lon : ~astropy.units.Quantity
            Spherical longitude.
        r : ~astropy.units.Quantity
            Radial distance.
        ref_pot : ~astropy.units.Quantity
            Reference potential value W0 for the zero degree term. Defaut is
            `None` (zero degree term is not considered).
        lmax : int, optional
            Maximum degree of the coefficients. Default is `None` (use all
            the coefficients).

        Returns
        -------
        ~astropy.units.Quantity
            Anomaly height.
        """
        rlat, _, u_ax = _transform.cartesian_to_ellipsoidal(
            *_transform.spherical_to_cartesian(lat, lon, r), self._ell)

        T = self.anomalous_potential.potential(lat, lon, r, lmax=lmax)

        gamma = self._ell.normal_gravity(rlat, u_ax)

        zeta = _np.squeeze(T / gamma)

        if ref_pot is not None:
            zeta -= (ref_pot - self._ell.surface_potential) / gamma

        return zeta
예제 #4
0
    def gravity_disturbance(self, lat, lon, r, lmax=None, degrees=True):
        """Return gravity disturbance.

        The gravity disturbance is defined as the magnitude of the gradient of
        the potential at a given point minus the magnitude of the gradient of
        the normal potential at the same point (eqs. 87 and 121 − 124 of STR09/02).

        Parameters
        ----------
        lat : float
            Latitude, in degrees
        lon : float
            Longitude, in degrees
        r   : float
            Radial distance, im meters
        lmax : int, optional
            Maximum degree of the coefficients. Default is `None` (use all
            the coefficients).
        degrees : bool, optional
            If True, the input `lat` and `lon` are given in degrees,
            otherwise radians.

        Returns
        -------
        float
            Gravity disturbance, in m/s**2
        """
        if degrees:
            lat = _np.radians(lat)
            lon = _np.radians(lon)

        rlat, _, u = _transform.cartesian_to_ellipsoidal(
            *_transform.spherical_to_cartesian(lat, lon, r, degrees=False),
            self._ell,
            degrees=False)

        g = self._gravity.gradient(lat, lon, r, lmax, degrees=False)[-1]
        gamma = self._ell.normal_gravity(rlat, u, degrees=False)

        return g - gamma
예제 #5
0
    def ellipsoidal(self, ell):
        """Return ellipsoidal-harmonic coordinates.

        Parameters
        ----------
        ell : instance of the `pygeoid.coordinates.ellipsoid.Ellipsoid`
            Reference ellipsoid to which ellipsoidal coordinates are referenced to.

        Returns
        -------
        rlat : ~astropy.units.Quantity
            Reduced latitude.
        lon : ~astropy.units.Quantity
            Longitude.
        u_ax : ~astropy.units.Quantity
            Polar axis of the ellipsoid passing through the given point.
        """
        rlat, lon, u_ax = transform.cartesian_to_ellipsoidal(self._x,
                                                             self._y,
                                                             self._z,
                                                             ell=ell)
        return rlat, lon, u_ax
예제 #6
0
    def height_anomaly_ell(self,
                           lat,
                           lon,
                           r,
                           ref_pot=None,
                           lmax=None,
                           degrees=True):
        """Return height anomaly above the ellispoid.

        The height anomaly can be generalised to a 3-d function, (sometimes
        called "generalised pseudo-height-anomaly"). Here it can be calculated
        on (h=0) or above (h>0) the ellipsoid, approximated by Bruns’ formula
        (eqs. 78 and 118 of STR09/02)

        Parameters
        ----------
        lat : float
            Latitude, in degrees
        lon : float
            Longitude, in degrees
        r   : float
            Radial distance, im meters
        ref_pot : float, in m**2 / s**2
            Reference potential value W0 for the zero degree term. Defaut is
            `None` (zero degree term is not considered).
        lmax : int, optional
            Maximum degree of the coefficients. Default is `None` (use all
            the coefficients).
        degrees : bool, optional
            If True, the input `lat` and `lon` are given in degrees,
            otherwise radians.

        Returns
        -------
        float
            Anomaly height, in meters
        """

        if degrees:
            lat = _np.radians(lat)
            lon = _np.radians(lon)

        rlat, _, u = _transform.cartesian_to_ellipsoidal(
            *_transform.spherical_to_cartesian(lat, lon, r, degrees=False),
            self._ell,
            degrees=False)

        T = self.anomalous_potential.potential(lat,
                                               lon,
                                               r,
                                               lmax=lmax,
                                               degrees=False)

        gamma = self._ell.normal_gravity(rlat, u, degrees=False)

        zeta = _np.squeeze(T / gamma)

        if ref_pot is not None:
            zeta -= (ref_pot - self._ell.surface_potential) / gamma

        return zeta