def lon_derivative(self, lat: u.deg, lon: u.deg, r: u.m, lmax: int = None): """Return longitudinal derivative of the potential. 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 Longitudinal derivative. """ cilm, lmax_comp = _get_lmax(self._coeffs.coeffs, lmax=lmax) _, _, degrees, cosin, x, q = _expand.common_precompute( lat, lon, r, self.r0, lmax_comp) m_coeff = _np.tile(degrees, (lmax_comp + 1, 1)) args = (_expand.in_coeff_lon_derivative, _expand.sum_lon_derivative, lmax_comp, degrees, m_coeff, cosin, cilm) values = _expand.expand_parallel(x, q, *args) ri = 1 / r out = -self.gm * ri * values return out.squeeze()
def gradient(self, lat, lon, r, lmax=None, degrees=True): """Return gradient vector. The magnitude and the components of the gradient of the potential calculated on or above the ellipsoid without the centrifugal potential (eqs. 7 and 122 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. """ if degrees: lat = _np.radians(lat) lon = _np.radians(lon) cilm, lmax_comp = _get_lmax(self._coeffs.coeffs, lmax=lmax) lat, _, degrees, cosin, x, q = _expand.common_precompute( lat, lon, r, self.r0, lmax_comp) m_coeff = _np.tile(degrees, (lmax_comp + 1, 1)) args = (_expand.in_coeff_gradient, _expand.sum_gradient, lmax_comp, degrees, m_coeff, cosin, cilm) values = _expand.expand_parallel(x, q, *args) ri = 1 / r gmri = self.gm * ri clat = _np.cos(lat) lat_d = gmri * clat * values[:, :, 0] lon_d = -gmri * values[:, :, 1] rad_d = -self.gm * ri**2 * values[:, :, 2] if self.omega is not None: lat_d += self.centrifugal.lat_derivative(lat, r, degrees=False) rad_d += self.centrifugal.r_derivative(lat, r, degrees=False) # total clati = _np.atleast_2d(1 / _np.ma.masked_values(clat, 0.0)) clati = clati.filled(0.0) total = _np.sqrt((ri * lat_d)**2 + (clati * ri * lon_d)**2 + rad_d**2) return _np.squeeze([rad_d, lon_d, lat_d, total])
def gradient(self, lat: u.deg, lon: u.deg, r: u.m, lmax: int = None): """Return gradient vector. The magnitude and the components of the gradient of the potential calculated on or above the ellipsoid without the centrifugal potential (eqs. 7 and 122 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). """ cilm, lmax_comp = _get_lmax(self._coeffs.coeffs, lmax=lmax) lat, _, degrees, cosin, x, q = _expand.common_precompute( lat, lon, r, self.r0, lmax_comp) m_coeff = _np.tile(degrees, (lmax_comp + 1, 1)) args = (_expand.in_coeff_gradient, _expand.sum_gradient, lmax_comp, degrees, m_coeff, cosin, cilm) values = _expand.expand_parallel(x, q, *args) ri = 1 / r gmri = self.gm * ri clat = _np.cos(lat) lat_d = gmri * clat * values[:, :, 0] lon_d = -gmri * values[:, :, 1] rad_d = -self.gm * ri**2 * values[:, :, 2] if self.omega is not None: lat_d += self.centrifugal.lat_derivative(lat, r) rad_d += self.centrifugal.r_derivative(lat, r) # total clati = _np.atleast_2d(1 / _np.ma.masked_values(clat, 0.0)) clati = clati.filled(0.0) total = _np.sqrt((ri * lat_d)**2 + (clati * ri * lon_d)**2 + rad_d**2) return (rad_d.squeeze(), lon_d.squeeze(), lat_d.squeeze(), total.squeeze())
def gravity_anomaly_sa(self, lat, lon, r, lmax=None, degrees=True): """Return (Molodensky) gravity anomaly in spherical approximation. The gravity anomaly calculated by spherical approximation (eqs. 100 or 104 and 126 of STR09/02). Unlike the classical gravity anomaly, the Molodensky gravity anomaly and the spherical approximation can be generalised to 3-d space, hence here it can be calculated on (h=0) or above (h>0) the ellipsoid. 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 anomaly, in m/s**2 """ if degrees: lat = _np.radians(lat) lon = _np.radians(lon) coeffs = self._anomalous._coeffs.coeffs cilm, lmax_comp = _get_lmax(coeffs, lmax=lmax) _, _, degrees, cosin, x, q = _expand.common_precompute( lat, lon, r, self._coeffs.r0, lmax_comp) args = (_expand.in_coeff_gravity_anomaly, _expand.sum_potential, lmax_comp, degrees, cosin, cilm) values = _expand.expand_parallel(x, q, *args) ri = 1 / r out = self._coeffs.gm * ri**2 * values return _np.squeeze(out)
def potential(self, lat, lon, r, lmax=None, degrees=True): """Return potential value. Parameters ---------- lat : float or array Latitude, in degrees lon : float or array Longitude, in degrees r : float or array 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 or array Potential, in m**2/s**2 """ if degrees: lat = _np.radians(lat) lon = _np.radians(lon) cilm, lmax_comp = _get_lmax(self._coeffs.coeffs, lmax=lmax) _, _, degrees, cosin, x, q = _expand.common_precompute( lat, lon, r, self.r0, lmax_comp) args = (_expand.in_coeff_potential, _expand.sum_potential, lmax_comp, degrees, cosin, cilm) values = _expand.expand_parallel(x, q, *args) ri = 1 / r out = _np.squeeze(self.gm * ri * values) if self.omega is not None: out += self.centrifugal.potential(lat, r, degrees=False) return out
def gravity_anomaly_sa(self, lat: u.deg, lon: u.deg, r: u.m, lmax: int = None) -> u.mGal: """Return (Molodensky) gravity anomaly in spherical approximation. The gravity anomaly calculated by spherical approximation (eqs. 100 or 104 and 126 of STR09/02). Unlike the classical gravity anomaly, the Molodensky gravity anomaly and the spherical approximation can be generalised to 3-d space, hence here it can be calculated on (h=0) or above (h>0) the ellipsoid. 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 anomaly. """ coeffs = self._anomalous._coeffs.coeffs cilm, lmax_comp = _get_lmax(coeffs, lmax=lmax) _, _, degrees, cosin, x, q = _expand.common_precompute( lat, lon, r, self._coeffs.r0, lmax_comp) args = (_expand.in_coeff_gravity_anomaly, _expand.sum_potential, lmax_comp, degrees, cosin, cilm) values = _expand.expand_parallel(x, q, *args) ri = 1 / r out = self._coeffs.gm * ri**2 * values return _np.squeeze(out)
def lon_derivative(self, lat, lon, r, lmax=None, degrees=True): """Return longitudinal derivative of the potential, in m/s**2. Parameters ---------- lat : float or array Latitude, in degrees lon : float or array Longitude, in degrees r : float or array 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 or array Longitudinal derivative, in m/s**2 """ if degrees: lat = _np.radians(lat) lon = _np.radians(lon) cilm, lmax_comp = _get_lmax(self._coeffs.coeffs, lmax=lmax) _, _, degrees, cosin, x, q = _expand.common_precompute( lat, lon, r, self.r0, lmax_comp) m_coeff = _np.tile(degrees, (lmax_comp + 1, 1)) args = (_expand.in_coeff_lon_derivative, _expand.sum_lon_derivative, lmax_comp, degrees, m_coeff, cosin, cilm) values = _expand.expand_parallel(x, q, *args) ri = 1 / r out = -self.gm * ri * values return _np.squeeze(out)
def potential(self, lat: u.deg, lon: u.deg, r: u.m, lmax=None) -> u.m**2 / u.s**2: """Return potential value. 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 Potential. """ cilm, lmax_comp = _get_lmax(self._coeffs.coeffs, lmax=lmax) _, _, degrees, cosin, x, q = _expand.common_precompute( lat, lon, r, self.r0, lmax_comp) args = (_expand.in_coeff_potential, _expand.sum_potential, lmax_comp, degrees, cosin, cilm) values = _expand.expand_parallel(x, q, *args) ri = 1 / r out = _np.squeeze(self.gm * ri * values) if self.omega is not None: out += self.centrifugal.potential(lat, r) return out