Skip to content

Commit

Permalink
add magnetosheath
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolasaunai committed Nov 3, 2020
1 parent 321790e commit ade2d6e
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 10 deletions.
2 changes: 1 addition & 1 deletion space/coordinates/coordinates.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def spherical_to_cartesian(R, theta, phi):

def cartesian_to_spherical(X,Y,Z):
r = np.sqrt(X**2+Y**2+Z**2)
theta = np.arccos(X/R)
theta = np.arccos(X/r)
phi = np.arctan2(Z,Y)
return r,theta,phi

Expand Down
82 changes: 73 additions & 9 deletions space/models/planetary.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@
sys.path.append('.')
from .. import utils
from ..coordinates import coordinates as coords
from ..smath import resolve_poly2



def _checking_angles(theta,phi):
theta = utils.listify(theta)
phi = utils.listify(phi)
if (len(np.shape(theta)) == 1) & (len(np.shape(phi)) == 1) & (len(theta) > 1) & (len(phi) > 1):
theta, phi = np.meshgrid(theta, phi)
print('theta and phi are both 1D array : applying meshgrid to do a 3D boundaries')
def _checking_angles(theta, phi):

if isinstance(theta, np.ndarray) and isinstance(theta, np.ndarray) and len(theta.shape) > 1 and len(phi.shape) > 1:
return np.meshgrid(theta, phi)
return theta, phi


Expand Down Expand Up @@ -62,13 +61,21 @@ def formisano1979(theta, phi, **kwargs):
r = _formisano1979(theta, phi, coefs = coefs)
base = kwargs.get("base", "cartesian")
if base == "cartesian":
return coords.spherical_to_cartesian(R, theta, phi)
return coords.spherical_to_cartesian(r, theta, phi)
elif base == "spherical":
return r, theta, phi
raise ValueError("unknown base '{}'".format(kwargs["base"]))



def mp_formisano1979(theta, phi, **kwargs):
return formisano1979(theta, phi, boundary="magnetopause", **kwargs)

def bs_formisano1979(theta, phi, **kwargs):
return formisano1979(theta, phi, boundary="bow_shock", **kwargs)




def Fairfield1971(x, args):

Expand Down Expand Up @@ -108,7 +115,7 @@ def Fairfield1971(x, args):



def BS_Jerab2005( Np, V, Ma, B, gamma=2.15 ):
def bs_Jerab2005( Np, V, Ma, B, gamma=2.15 ):

'''
Jerab 2005 Bow shock model. Give positions of the box shock in plans (XY) with Z=0 and (XZ) with Y=0 as a function of the upstream solar wind.
Expand Down Expand Up @@ -169,7 +176,7 @@ def make_Rav(theta,phi):
return pos.sort_values('Y')


def shue1998(theta, phi, **kwargs):
def mp_shue1998(theta, phi, **kwargs):
'''
Shue 1998 Magnetopause model.
Expand Down Expand Up @@ -305,3 +312,60 @@ def quad(i, s):
return r+Q


_models = {"mp_shue": mp_shue1998,
"mp_formisano1979": mp_formisano1979,
"bs_formisano1979": bs_formisano1979,
"bs_jerab": bs_Jerab2005}


class Magnetosheath:
def __init__(self, **kwargs):
self.magnetopause = _models[kwargs.get("magnetopause", "shue")]
self.bow_shock = _models[kwargs.get("bow_shock", "jerab")]

def boundaries(self, theta, phi, **kwargs):
return self.magnetopause(theta, phi, **kwargs), self.bow_shock(theta, phi, **kwargs)


def _interest_points(model, **kwargs):
dup = kwargs.copy()
dup["base"] = "cartesian"
x = model(0, 0, **dup)[0]
y = model(np.pi / 2, 0, **dup)[1]
xf = x - y ** 2 / (4 * x)
return x, y, xf


def _parabolic_approx(theta, phi, x, xf, **kwargs):
theta, phi = _checking_angles(theta, phi)
K = x - xf
a = np.sin(theta) ** 2
b = 4 * K * np.cos(theta)
c = -4 * K * x
r = resolve_poly2(a, b, c)[0]
return coords.BaseChoice(kwargs.get("base", "cartesian"), r, theta, phi)


class ParabolicMagnetosheath:
def __init__(self, **kwargs):
self._magnetopause = _models[kwargs.get("magnetopause", "shue")]
self._bow_shock = _models[kwargs.get("bow_shock", "jerab")]

def magnetopause(self, theta, phi, **kwargs):
return self._parabolize(theta, phi, **kwargs)[0]

def bow_shock(self, theta, phi, **kwargs):
return self._parabolize(theta, phi, **kwargs)[1]

def _parabolize(self, theta, phi, **kwargs):
xmp, y, xfmp = _interest_points(self._magnetopause, **kwargs)
xbs, y, xfbs = _interest_points(self._bow_shock, **kwargs)
if kwargs.get("confocal", False) is True:
xfmp = xmp / 2
xfbs = xmp / 2
mp_coords = _parabolic_approx(theta, phi, xmp, xfmp, **kwargs)
bs_coords = _parabolic_approx(theta, phi, xbs, xfbs, **kwargs)
return mp_coords, bs_coords

def boundaries(self, theta, phi, **kwargs):
return self._parabolize(theta, phi, **kwargs)
28 changes: 28 additions & 0 deletions space/smath.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import numpy as np

def norm(u, v, w):
return np.sqrt(u**2 + v**2 + w**2)


def resolve_poly2(a, b, c):
if isinstance(a, np.ndarray):
r1 = np.zeros_like(a)
r2 = np.zeros_like(a)
a_null = np.where(np.abs(a) < 1e-6)[0]

delta = b ** 2 - 4 * a * c
np.testing.assert_array_less(-delta, 0)

r1, r2 = (-b + np.sqrt(delta)) / (2 * a), (-b + np.sqrt(delta)) / (2 * a)
if isinstance(c, np.ndarray):
c = c[a_null]
if isinstance(b, np.ndarray):
b = b[a_null]
r1[a_null] = r2[a_null] = -c / b
else:
delta = b ** 2 - 4 * a * c
np.testing.assert_array_less(-delta, 0)
r1, r2 = (-b + np.sqrt(delta)) / (2 * a), (-b - np.sqrt(delta)) / (2 * a)
if np.abs(a) < 1e-6:
r1 = r2 = -c / b
return r1, r2

0 comments on commit ade2d6e

Please sign in to comment.