Source code for irfpy.mars.bowshock

''' Bow shock model by Vignes et al.

- :class:`BowshockVignes` provides default bow shock model
- :class:`BowshockVignesScaled` provides a bow shock model of your own scaling
'''
import numpy as _np


[docs]class BowshockVignes: r""" Vignes et al, (TBC) model for bow shock position. >>> bsx, bsr = BowshockVignes.xr() Conic curve (hyperbola) model with a formulation of .. math:: x &= R \cos\theta + x_0 \\ y &= R \sin\theta with .. math:: R = \frac{L}{1+\epsilon\cos\theta} The parameters are .. math:: L &= 2.04 \\ \epsilon &= 1.03 \\ x_0 &= 0.64 in the unit of Martian radii. """ L = 2.04 e = 1.03 x0 = 0.64
[docs] @classmethod def xr(self): ''' Return the bow shock position. :returns: The array with shape of (2, 180). Unit is in Rm. >>> print(BowshockVignes.xr()[:, 50]) [1.49948598 0.77115753] ''' L, e, x0 = self.L, self.e, self.x0 theta = _np.linspace(0, 150 * _np.pi / 180., 180) r = L / (1 + e * _np.cos(theta)) x = r * _np.cos(theta) + x0 y = r * _np.sin(theta) return _np.array([x, y])
[docs] @classmethod def inside(self, x, y, z): ''' Return True if s/c is in bow shock. >>> print(BowshockVignes.inside(1.2, 0, 0)) True >>> print(BowshockVignes.inside(3, 0, 0)) False ''' L, e, x0 = self.L, self.e, self.x0 xx = x - x0 yy = _np.sqrt(y ** 2 + z ** 2) theta = _np.arctan2(yy, xx) rr2 = xx ** 2 + yy ** 2 rb = L / (1 + e * _np.cos(theta)) rb2 = rb ** 2 return rr2 < rb2
class _Hyperbola: def __init__(self, L, e, x0): self.L = L self.e = e self.x0 = x0 def xr(self): ''' Return the bow shock position. :returns: The array with shape of (2, 180). Unit is in Rm. >>> print(BowshockVignes.xr()[:, 50]) [1.49948598 0.77115753] ''' L, e, x0 = self.L, self.e, self.x0 if e > 1: maxangle = _np.arccos(-1 / e) else: maxangle = _np.pi theta = _np.linspace(0, maxangle, 180, endpoint=False) r = L / (1 + e * _np.cos(theta)) x = r * _np.cos(theta) + x0 y = r * _np.sin(theta) return _np.array([x, y]) def inside(self, x, y, z=0): ''' Return True if s/c is in bow shock. >>> print(BowshockVignes.inside(1.2, 0, 0)) True >>> print(BowshockVignes.inside(3, 0, 0)) False ''' L, e, x0 = self.L, self.e, self.x0 xx = x - x0 yy = _np.sqrt(y ** 2 + z ** 2) theta = _np.arctan2(yy, xx) rr2 = xx ** 2 + yy ** 2 rb = L / (1 + e * _np.cos(theta)) rb2 = rb ** 2 return rr2 < rb2
[docs]def BowshockVignesScaled(scale=1): """ Vignes et al., while scaled by changing the parameter L. :param scale: Default 1. :return: A Vignes model with scaled by the given scale. 10% bigger model is obtained as follows >>> vig10 = BowshockVignesScaled(1.1) # 10% bigger model >>> x10, r10 = vig10.xr() >>> plt.plot(x10, r10) # doctest: +SKIP >>> vig10.inside(0, 2.7, 0) True >>> x00, r00 = BowshockVignes.xr() >>> plt.plot(x00, r00) # doctest: +SKIP >>> BowshockVignes.inside(0, 2.7, 0) False """ return _Hyperbola(2.04 * scale, 1.03, 0.64)