geopack-vectorize 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- geopack/__init__.py +207 -0
- geopack/core.py +0 -0
- geopack/geopack.py +1449 -0
- geopack/igrf_coeffs/igrf10coeffs.txt +196 -0
- geopack/igrf_coeffs/igrf11coeffs.txt +199 -0
- geopack/igrf_coeffs/igrf12coeffs.txt +199 -0
- geopack/igrf_coeffs/igrf13coeffs.txt +199 -0
- geopack/igrf_coeffs/igrf14coeffs.txt +199 -0
- geopack/igrf_coeffs/igrf9coeffs.txt +196 -0
- geopack/models/__init__.py +10 -0
- geopack/models/t01.py +2283 -0
- geopack/models/t04.py +2215 -0
- geopack/models/t89.py +375 -0
- geopack/models/t96.py +1895 -0
- geopack/print_structure.py +23 -0
- geopack/vectorized/__init__.py +137 -0
- geopack/vectorized/condip1_exact.py +256 -0
- geopack/vectorized/coordinates.py +381 -0
- geopack/vectorized/coordinates_complex.py +170 -0
- geopack/vectorized/field_line_directional_derivatives.py +325 -0
- geopack/vectorized/field_line_geometry.py +412 -0
- geopack/vectorized/igrf.py +294 -0
- geopack/vectorized/trace.py +596 -0
- geopack_vectorize-2.0.0.dist-info/METADATA +346 -0
- geopack_vectorize-2.0.0.dist-info/RECORD +28 -0
- geopack_vectorize-2.0.0.dist-info/WHEEL +5 -0
- geopack_vectorize-2.0.0.dist-info/licenses/LICENSE +22 -0
- geopack_vectorize-2.0.0.dist-info/top_level.txt +1 -0
geopack/models/t04.py
ADDED
|
@@ -0,0 +1,2215 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
# t04 is identical to t01 except for several factors.
|
|
4
|
+
|
|
5
|
+
def t04(parmod,ps,x,y,z):
|
|
6
|
+
"""
|
|
7
|
+
A data-based model of the external (i.e., without earth's contribution) part of the
|
|
8
|
+
magnetospheric magnetic field, calibrated by
|
|
9
|
+
(1) solar wind pressure pdyn (nanopascals),
|
|
10
|
+
(2) dst (nanotesla),
|
|
11
|
+
(3) byimf,
|
|
12
|
+
(4) bzimf (nanotesla)
|
|
13
|
+
(5-10) indices w1 - w6, calculated as time integrals from the beginning of a storm
|
|
14
|
+
see the reference (3) below, for a detailed definition of those variables
|
|
15
|
+
|
|
16
|
+
:param parmod: The elements are explained above.
|
|
17
|
+
:param x,y,z: GSM coordinates in Re (1 Re = 6371.2 km)
|
|
18
|
+
:return: bx,by,bz. Field components in GSM system, in nT.
|
|
19
|
+
Computed as a sum of contributions from principal field sources.
|
|
20
|
+
|
|
21
|
+
Assembled: March 25, 2004; Updated: August 2 & 31, December 27, 2004.
|
|
22
|
+
A bug eliminated March 14, 2005 (might cause compilation problems with some fortran compilers)
|
|
23
|
+
|
|
24
|
+
Attention: The model is based on data taken sunward from x=-15Re, and hence becomes invalid at larger tailward distances !!! *
|
|
25
|
+
|
|
26
|
+
REFERENCES:
|
|
27
|
+
(1) N. A. Tsyganenko, A new data-based model of the near magnetosphere magnetic field:
|
|
28
|
+
1. Mathematical structure.
|
|
29
|
+
2. Parameterization and fitting to observations. JGR v. 107(A8), 1176/1179, doi:10.1029/2001JA000219/220, 2002.
|
|
30
|
+
(2) N. A. Tsyganenko, H. J. Singer, J. C. Kasper, Storm-time distortion of the
|
|
31
|
+
inner magnetosphere: How severe can it get ? JGR v. 108(A5), 1209, doi:10.1029/2002JA009808, 2003.
|
|
32
|
+
(3) N. A. Tsyganenko and M. I. Sitnov, Modeling the dynamics of the inner magnetosphere during
|
|
33
|
+
strong geomagnetic storms, J. Geophys. Res., v. 110 (A3), A03208, doi: 10.1029/2004JA010798, 2005.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
a = np.array([
|
|
37
|
+
1.00000,5.44118,0.891995,9.09684,0.00000,-7.18972,12.2700,
|
|
38
|
+
-4.89408,0.00000,0.870536,1.36081,0.00000,0.688650,0.602330,
|
|
39
|
+
0.00000,0.316346,1.22728,-0.363620E-01,-0.405821,0.452536,
|
|
40
|
+
0.755831,0.215662,0.152759,5.96235,23.2036,11.2994,69.9596,
|
|
41
|
+
0.989596,-0.132131E-01,0.985681,0.344212E-01,1.02389,0.207867,
|
|
42
|
+
1.51220,0.682715E-01,1.84714,1.76977,1.37690,0.696350,0.343280,
|
|
43
|
+
3.28846,111.293,5.82287,4.39664,0.383403,0.648176,0.318752E-01,
|
|
44
|
+
0.581168,1.15070,0.843004,0.394732,0.846509,0.916555,0.550920,
|
|
45
|
+
0.180725,0.898772,0.387365,2.26596,1.29123,0.436819,1.28211,
|
|
46
|
+
1.33199,.405553,1.6229,.699074,1.26131,2.42297,.537116,.619441])
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
iopgen,ioptt,iopb,iopr = [0.]*4
|
|
50
|
+
|
|
51
|
+
pdyn=parmod[0]
|
|
52
|
+
dst_ast=parmod[1]*0.8-13*np.sqrt(pdyn)
|
|
53
|
+
bximf,byimf,bzimf=[0.,parmod[2],parmod[3]]
|
|
54
|
+
w1,w2,w3,w4,w5,w6 = parmod[4:10]
|
|
55
|
+
pss,xx,yy,zz = [ps,x,y,z]
|
|
56
|
+
|
|
57
|
+
return extern(iopgen,ioptt,iopb,iopr,a,69,pdyn,dst_ast,bximf,byimf,bzimf,
|
|
58
|
+
w1,w2,w3,w4,w5,w6,pss,xx,yy,zz)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def extern(iopgen,iopt,iopb,iopr,a,ntot,pdyn,dst,bximf,byimf,bzimf,w1,w2,w3,w4,w5,w6,ps,x,y,z):
|
|
62
|
+
"""
|
|
63
|
+
:param iopgen: general option flag:
|
|
64
|
+
iopgen=0 - calculate total field
|
|
65
|
+
iopgen=1 - dipole shielding only
|
|
66
|
+
iopgen=2 - tail field only
|
|
67
|
+
iopgen=3 - birkeland field only
|
|
68
|
+
iopgen=4 - ring current field only
|
|
69
|
+
iopgen=5 - interconnection field only
|
|
70
|
+
:param iopt: tail field flag:
|
|
71
|
+
iopt=0 - both modes
|
|
72
|
+
iopt=1 - mode 1 only
|
|
73
|
+
iopt=2 - mode 2 only
|
|
74
|
+
:param iopb: birkeland field flag:
|
|
75
|
+
iopb=0 - all 4 terms
|
|
76
|
+
iopb=1 - region 1, modes 1 and 2
|
|
77
|
+
iopb=2 - region 2, modes 1 and 2
|
|
78
|
+
:param iopr: ring current flag:
|
|
79
|
+
iopr=0 - both src and prc
|
|
80
|
+
iopr=1 - src only
|
|
81
|
+
iopr=2 - prc only
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
# common /tail/ dxshift1,dxshift2,d,deltady ! the common blocks forward nonlinear parameters
|
|
85
|
+
# common /birkpar/ xkappa1,xkappa2
|
|
86
|
+
# common /rcpar/ sc_sy,sc_as,phi
|
|
87
|
+
# common /g/ g
|
|
88
|
+
# common /rh0/ rh0
|
|
89
|
+
global dxshift1, dxshift2, d, deltady
|
|
90
|
+
global xkappa1, xkappa2
|
|
91
|
+
global sc_sy, sc_pr, phi
|
|
92
|
+
global g
|
|
93
|
+
global rh0
|
|
94
|
+
|
|
95
|
+
a0_a,a0_s0,a0_x0 = [34.586,1.1960,3.4397] # Shue et al. parameters
|
|
96
|
+
dsig = 0.005
|
|
97
|
+
rh0,rh2 = [8.0,-5.2]
|
|
98
|
+
|
|
99
|
+
xappa = (pdyn/2.)**a[22] # overall scaling parameter
|
|
100
|
+
rh0 = 7.5 # tail hinging distance
|
|
101
|
+
g = 35.0 # tail warping parameter
|
|
102
|
+
|
|
103
|
+
xappa3=xappa**3
|
|
104
|
+
|
|
105
|
+
xx=x*xappa
|
|
106
|
+
yy=y*xappa
|
|
107
|
+
zz=z*xappa
|
|
108
|
+
|
|
109
|
+
sps=np.sin(ps)
|
|
110
|
+
|
|
111
|
+
x0=a0_x0/xappa
|
|
112
|
+
am=a0_a/xappa
|
|
113
|
+
s0=a0_s0
|
|
114
|
+
|
|
115
|
+
# Calculate "imf" components outside the magnetopause layer (hence begin with "o")
|
|
116
|
+
# They are needed only if the point (x,y,z) is within the transition magnetopause layer or outside the magnetosphere:
|
|
117
|
+
factimf=a[19]
|
|
118
|
+
|
|
119
|
+
oimfx=0.
|
|
120
|
+
oimfy=byimf*factimf
|
|
121
|
+
oimfz=bzimf*factimf
|
|
122
|
+
|
|
123
|
+
r=np.sqrt(x**2+y**2+z**2)
|
|
124
|
+
xss=x
|
|
125
|
+
zss=z
|
|
126
|
+
|
|
127
|
+
# begin iterative search of unwarped coords (to find sigma)
|
|
128
|
+
dd = 1.
|
|
129
|
+
while dd > 1e-6:
|
|
130
|
+
xsold=xss
|
|
131
|
+
zsold=zss
|
|
132
|
+
|
|
133
|
+
rh=rh0+rh2*(zss/r)**2
|
|
134
|
+
sinpsas=sps/(1+(r/rh)**3)**0.33333333
|
|
135
|
+
cospsas=np.sqrt(1-sinpsas**2)
|
|
136
|
+
zss=x*sinpsas+z*cospsas
|
|
137
|
+
xss=x*cospsas-z*sinpsas
|
|
138
|
+
dd=np.abs(xss-xsold)+np.abs(zss-zsold)
|
|
139
|
+
|
|
140
|
+
rho2=y**2+zss**2
|
|
141
|
+
asq=am**2
|
|
142
|
+
xmxm=am+xss-x0
|
|
143
|
+
if xmxm < 0: xmxm = 0 # the boundary is a cylinder tailward of x=x0-am
|
|
144
|
+
axx0=xmxm**2
|
|
145
|
+
aro=asq+rho2
|
|
146
|
+
sigma=np.sqrt((aro+axx0+np.sqrt((aro+axx0)**2-4.*asq*axx0))/(2.*asq))
|
|
147
|
+
|
|
148
|
+
# Now, there are three possible cases:
|
|
149
|
+
# (1) inside the magnetosphere
|
|
150
|
+
# (2) in the boundary layer
|
|
151
|
+
# (3) outside the magnetosphere and b.layer
|
|
152
|
+
|
|
153
|
+
# First of all, consider the cases (1) and (2):
|
|
154
|
+
if sigma < (s0+dsig): # cases (1) or (2); calculate the model field (with the potential "penetrated" interconnection field):
|
|
155
|
+
|
|
156
|
+
bxcf,bycf,bzcf = [0.]*3
|
|
157
|
+
if iopgen <= 1:
|
|
158
|
+
cfx,cfy,cfz = shlcar3x3(xx,yy,zz,ps) # dipole shielding field
|
|
159
|
+
bxcf=cfx*xappa3
|
|
160
|
+
bycf=cfy*xappa3
|
|
161
|
+
bzcf=cfz*xappa3
|
|
162
|
+
|
|
163
|
+
bxt1,byt1,bzt1,bxt2,byt2,bzt2 = [0.]*6
|
|
164
|
+
if (iopgen == 0) | (iopgen == 2):
|
|
165
|
+
dstt = -20.
|
|
166
|
+
if dst < dstt: dstt = dst
|
|
167
|
+
znam = np.abs(dstt)**0.37
|
|
168
|
+
dxshift1=a[23]-a[24]/znam
|
|
169
|
+
dxshift2=a[25]-a[26]/znam
|
|
170
|
+
d=a[35]*np.exp(-w1/a[36])+a[68]
|
|
171
|
+
deltady=4.7
|
|
172
|
+
bxt1,byt1,bzt1,bxt2,byt2,bzt2 = deformed(iopt,ps,xx,yy,zz)
|
|
173
|
+
|
|
174
|
+
bxr11,byr11,bzr11, bxr12,byr12,bzr12, bxr21,byr21,bzr21, bxr22,byr22,bzr22 = [0.]*12
|
|
175
|
+
if (iopgen == 0) | (iopgen == 3):
|
|
176
|
+
znam = np.abs(dst)
|
|
177
|
+
if dst >= -20: znam = 20.
|
|
178
|
+
xkappa1=a[31]*(znam/20)**a[32]
|
|
179
|
+
xkappa2=a[33]*(znam/20)**a[34]
|
|
180
|
+
# Birkeland field (two modes for r1 and two modes for r2)
|
|
181
|
+
bxr11,byr11,bzr11, bxr12,byr12,bzr12, bxr21,byr21,bzr21, bxr22,byr22,bzr22 = \
|
|
182
|
+
birk_tot(iopb,ps,xx,yy,zz)
|
|
183
|
+
|
|
184
|
+
bxsrc,bysrc,bzsrc, bxprc,byprc,bzprc = [0.]*6
|
|
185
|
+
if (iopgen == 0) | (iopgen == 4):
|
|
186
|
+
phi=a[37]
|
|
187
|
+
znam=np.abs(dst)
|
|
188
|
+
if dst >= -20: znam = 20
|
|
189
|
+
sc_sy=a[27]*(20/znam)**a[28]*xappa
|
|
190
|
+
sc_pr=a[29]*(20/znam)**a[30]*xappa
|
|
191
|
+
# shielded ring current (src and prc)
|
|
192
|
+
bxsrc,bysrc,bzsrc, bxprc,byprc,bzprc = full_rc(iopr,ps,xx,yy,zz)
|
|
193
|
+
|
|
194
|
+
hximf,hyimf,hzimf = [0.]*3
|
|
195
|
+
if (iopgen == 0) | (iopgen == 5):
|
|
196
|
+
# These are components of the penetrated field per unit of the penetration coefficient.
|
|
197
|
+
# In other words, these are derivatives of the penetration field components with respect
|
|
198
|
+
# to the penetration coefficient. We assume that only the transverse component of the
|
|
199
|
+
# field penetrates inside.
|
|
200
|
+
hximf,hyimf,hzimf = [0.,byimf,bzimf]
|
|
201
|
+
|
|
202
|
+
# Now, add up all the components:
|
|
203
|
+
dlp1=(pdyn/2)**a[20]
|
|
204
|
+
dlp2=(pdyn/2)**a[21]
|
|
205
|
+
|
|
206
|
+
tamp1=a[1]+a[2]*dlp1+a[3]*a[38]*w1/np.sqrt(w1**2+a[38]**2)+a[4]*dst
|
|
207
|
+
tamp2=a[5]+a[6]*dlp2+a[7]*a[39]*w2/np.sqrt(w2**2+a[39]**2)+a[8]*dst
|
|
208
|
+
a_src=a[9] +a[10]*a[40]*w3/np.sqrt(w3**2+a[40]**2)+a[11]*dst
|
|
209
|
+
a_prc=a[12]+a[13]*a[41]*w4/np.sqrt(w4**2+a[41]**2)+a[14]*dst
|
|
210
|
+
a_r11=a[15]+a[16]*a[42]*w5/np.sqrt(w5**2+a[42]**2)
|
|
211
|
+
a_r21=a[17]+a[18]*a[43]*w6/np.sqrt(w6**2+a[43]**2)
|
|
212
|
+
|
|
213
|
+
bbx=a[0]*bxcf + tamp1*bxt1+tamp2*bxt2 + a_src*bxsrc+a_prc*bxprc + a_r11*bxr11+a_r21*bxr21 + a[19]*hximf
|
|
214
|
+
bby=a[0]*bycf + tamp1*byt1+tamp2*byt2 + a_src*bysrc+a_prc*byprc + a_r11*byr11+a_r21*byr21 + a[19]*hyimf
|
|
215
|
+
bbz=a[0]*bzcf + tamp1*bzt1+tamp2*bzt2 + a_src*bzsrc+a_prc*bzprc + a_r11*bzr11+a_r21*bzr21 + a[19]*hzimf
|
|
216
|
+
|
|
217
|
+
# And we have the total external field.
|
|
218
|
+
# Now, let us check whether we have the case (1). if yes - we are done:
|
|
219
|
+
if sigma < (s0-dsig): # (x,y,z) is inside the magnetosphere
|
|
220
|
+
bx,by,bz = [bbx,bby,bbz]
|
|
221
|
+
else: # this is the most complex case: we are inside the interpolation region
|
|
222
|
+
fint=0.5*(1.-(sigma-s0)/dsig)
|
|
223
|
+
fext=0.5*(1.+(sigma-s0)/dsig)
|
|
224
|
+
|
|
225
|
+
qx,qy,qz = dipole(ps,x,y,z)
|
|
226
|
+
bx=(bbx+qx)*fint+oimfx*fext -qx
|
|
227
|
+
by=(bby+qy)*fint+oimfy*fext -qy
|
|
228
|
+
bz=(bbz+qz)*fint+oimfz*fext -qz
|
|
229
|
+
# The cases (1) and (2) are exhausted; the only remaining possibility is now the case (3):
|
|
230
|
+
else:
|
|
231
|
+
qx,qy,qz = dipole(ps,x,y,z)
|
|
232
|
+
bx=oimfx-qx
|
|
233
|
+
by=oimfy-qy
|
|
234
|
+
bz=oimfz-qz
|
|
235
|
+
|
|
236
|
+
return bx,by,bz
|
|
237
|
+
|
|
238
|
+
def shlcar3x3(x,y,z, ps):
|
|
239
|
+
"""
|
|
240
|
+
This subroutine returns the shielding field for the earth's dipole, represented by
|
|
241
|
+
2x3x3=18 "cartesian" harmonics, tilted with respect to the z=0 plane (nb#4, p.74)
|
|
242
|
+
|
|
243
|
+
:param x,y,z: GSM coordinates in Re (1 Re = 6371.2 km)
|
|
244
|
+
:param ps: geo-dipole tilt angle in radius.
|
|
245
|
+
:return: bx,by,bz. Field components in GSM system, in nT.
|
|
246
|
+
"""
|
|
247
|
+
# The 36 coefficients enter in pairs in the amplitudes of the "cartesian" harmonics (A(1)-A(36).
|
|
248
|
+
# The 14 nonlinear parameters (A(37)-A(50) are the scales Pi,Ri,Qi,and Si entering the arguments of exponents, sines, and cosines in each of the
|
|
249
|
+
# 18 "cartesian" harmonics plus two tilt angles for the cartesian harmonics (one for the psi=0 mode and another for the psi=90 mode)
|
|
250
|
+
|
|
251
|
+
a = np.array([
|
|
252
|
+
-901.2327248,895.8011176,817.6208321,-845.5880889,-83.73539535,
|
|
253
|
+
86.58542841,336.8781402,-329.3619944,-311.2947120,308.6011161,
|
|
254
|
+
31.94469304,-31.30824526,125.8739681,-372.3384278,-235.4720434,
|
|
255
|
+
286.7594095,21.86305585,-27.42344605,-150.4874688,2.669338538,
|
|
256
|
+
1.395023949,-.5540427503,-56.85224007,3.681827033,-43.48705106,
|
|
257
|
+
5.103131905,1.073551279,-.6673083508,12.21404266,4.177465543,
|
|
258
|
+
5.799964188,-.3977802319,-1.044652977,.5703560010,3.536082962,
|
|
259
|
+
-3.222069852,9.620648151,6.082014949,27.75216226,12.44199571,
|
|
260
|
+
5.122226936,6.982039615,20.12149582,6.150973118,4.663639687,
|
|
261
|
+
15.73319647,2.303504968,5.840511214,.8385953499E-01,.3477844929])
|
|
262
|
+
|
|
263
|
+
p1,p2,p3, r1,r2,r3, q1,q2,q3, s1,s2,s3 = a[36:48]
|
|
264
|
+
t1,t2 = a[48:50]
|
|
265
|
+
|
|
266
|
+
cps=np.cos(ps)
|
|
267
|
+
sps=np.sin(ps)
|
|
268
|
+
s2ps=2*cps # modified here (sin(2*ps) instead of sin(3*ps))
|
|
269
|
+
|
|
270
|
+
st1=np.sin(ps*t1)
|
|
271
|
+
ct1=np.cos(ps*t1)
|
|
272
|
+
st2=np.sin(ps*t2)
|
|
273
|
+
ct2=np.cos(ps*t2)
|
|
274
|
+
|
|
275
|
+
x1=x*ct1-z*st1
|
|
276
|
+
z1=x*st1+z*ct1
|
|
277
|
+
x2=x*ct2-z*st2
|
|
278
|
+
z2=x*st2+z*ct2
|
|
279
|
+
|
|
280
|
+
# make the terms in the 1st sum ("perpendicular" symmetry):
|
|
281
|
+
# i=1:
|
|
282
|
+
sqpr= np.sqrt(1/p1**2+1/r1**2)
|
|
283
|
+
cyp = np.cos(y/p1)
|
|
284
|
+
syp = np.sin(y/p1)
|
|
285
|
+
czr = np.cos(z1/r1)
|
|
286
|
+
szr = np.sin(z1/r1)
|
|
287
|
+
expr= np.exp(sqpr*x1)
|
|
288
|
+
fx1 =-sqpr*expr*cyp*szr
|
|
289
|
+
hy1 = expr/p1*syp*szr
|
|
290
|
+
fz1 =-expr*cyp/r1*czr
|
|
291
|
+
hx1 = fx1*ct1+fz1*st1
|
|
292
|
+
hz1 =-fx1*st1+fz1*ct1
|
|
293
|
+
|
|
294
|
+
sqpr= np.sqrt(1/p1**2+1/r2**2)
|
|
295
|
+
cyp = np.cos(y/p1)
|
|
296
|
+
syp = np.sin(y/p1)
|
|
297
|
+
czr = np.cos(z1/r2)
|
|
298
|
+
szr = np.sin(z1/r2)
|
|
299
|
+
expr= np.exp(sqpr*x1)
|
|
300
|
+
fx2 =-sqpr*expr*cyp*szr
|
|
301
|
+
hy2 = expr/p1*syp*szr
|
|
302
|
+
fz2 =-expr*cyp/r2*czr
|
|
303
|
+
hx2 = fx2*ct1+fz2*st1
|
|
304
|
+
hz2 =-fx2*st1+fz2*ct1
|
|
305
|
+
|
|
306
|
+
sqpr= np.sqrt(1/p1**2+1/r3**2)
|
|
307
|
+
cyp = np.cos(y/p1)
|
|
308
|
+
syp = np.sin(y/p1)
|
|
309
|
+
czr = np.cos(z1/r3)
|
|
310
|
+
szr = np.sin(z1/r3)
|
|
311
|
+
expr= np.exp(sqpr*x1)
|
|
312
|
+
fx3 =-expr*cyp*(sqpr*z1*czr+szr/r3*(x1+1/sqpr))
|
|
313
|
+
hy3 = expr/p1*syp*(z1*czr+x1/r3*szr/sqpr)
|
|
314
|
+
fz3 =-expr*cyp*(czr*(1+x1/r3**2/sqpr)-z1/r3*szr)
|
|
315
|
+
hx3 = fx3*ct1+fz3*st1
|
|
316
|
+
hz3 =-fx3*st1+fz3*ct1
|
|
317
|
+
|
|
318
|
+
# i=2:
|
|
319
|
+
sqpr= np.sqrt(1/p2**2+1/r1**2)
|
|
320
|
+
cyp = np.cos(y/p2)
|
|
321
|
+
syp = np.sin(y/p2)
|
|
322
|
+
czr = np.cos(z1/r1)
|
|
323
|
+
szr = np.sin(z1/r1)
|
|
324
|
+
expr= np.exp(sqpr*x1)
|
|
325
|
+
fx4 =-sqpr*expr*cyp*szr
|
|
326
|
+
hy4 = expr/p2*syp*szr
|
|
327
|
+
fz4 =-expr*cyp/r1*czr
|
|
328
|
+
hx4 = fx4*ct1+fz4*st1
|
|
329
|
+
hz4 =-fx4*st1+fz4*ct1
|
|
330
|
+
|
|
331
|
+
sqpr= np.sqrt(1/p2**2+1/r2**2)
|
|
332
|
+
cyp = np.cos(y/p2)
|
|
333
|
+
syp = np.sin(y/p2)
|
|
334
|
+
czr = np.cos(z1/r2)
|
|
335
|
+
szr = np.sin(z1/r2)
|
|
336
|
+
expr= np.exp(sqpr*x1)
|
|
337
|
+
fx5 =-sqpr*expr*cyp*szr
|
|
338
|
+
hy5 = expr/p2*syp*szr
|
|
339
|
+
fz5 =-expr*cyp/r2*czr
|
|
340
|
+
hx5 = fx5*ct1+fz5*st1
|
|
341
|
+
hz5 =-fx5*st1+fz5*ct1
|
|
342
|
+
|
|
343
|
+
sqpr= np.sqrt(1/p2**2+1/r3**2)
|
|
344
|
+
cyp = np.cos(y/p2)
|
|
345
|
+
syp = np.sin(y/p2)
|
|
346
|
+
czr = np.cos(z1/r3)
|
|
347
|
+
szr = np.sin(z1/r3)
|
|
348
|
+
expr= np.exp(sqpr*x1)
|
|
349
|
+
fx6 =-expr*cyp*(sqpr*z1*czr+szr/r3*(x1+1/sqpr))
|
|
350
|
+
hy6 = expr/p2*syp*(z1*czr+x1/r3*szr/sqpr)
|
|
351
|
+
fz6 =-expr*cyp*(czr*(1+x1/r3**2/sqpr)-z1/r3*szr)
|
|
352
|
+
hx6 = fx6*ct1+fz6*st1
|
|
353
|
+
hz6 =-fx6*st1+fz6*ct1
|
|
354
|
+
|
|
355
|
+
# i=3:
|
|
356
|
+
sqpr= np.sqrt(1/p3**2+1/r1**2)
|
|
357
|
+
cyp = np.cos(y/p3)
|
|
358
|
+
syp = np.sin(y/p3)
|
|
359
|
+
czr = np.cos(z1/r1)
|
|
360
|
+
szr = np.sin(z1/r1)
|
|
361
|
+
expr= np.exp(sqpr*x1)
|
|
362
|
+
fx7 =-sqpr*expr*cyp*szr
|
|
363
|
+
hy7 = expr/p3*syp*szr
|
|
364
|
+
fz7 =-expr*cyp/r1*czr
|
|
365
|
+
hx7 = fx7*ct1+fz7*st1
|
|
366
|
+
hz7 =-fx7*st1+fz7*ct1
|
|
367
|
+
|
|
368
|
+
sqpr= np.sqrt(1/p3**2+1/r2**2)
|
|
369
|
+
cyp = np.cos(y/p3)
|
|
370
|
+
syp = np.sin(y/p3)
|
|
371
|
+
czr = np.cos(z1/r2)
|
|
372
|
+
szr = np.sin(z1/r2)
|
|
373
|
+
expr= np.exp(sqpr*x1)
|
|
374
|
+
fx8 =-sqpr*expr*cyp*szr
|
|
375
|
+
hy8 = expr/p3*syp*szr
|
|
376
|
+
fz8 =-expr*cyp/r2*czr
|
|
377
|
+
hx8 = fx8*ct1+fz8*st1
|
|
378
|
+
hz8 =-fx8*st1+fz8*ct1
|
|
379
|
+
|
|
380
|
+
sqpr= np.sqrt(1/p3**2+1/r3**2)
|
|
381
|
+
cyp = np.cos(y/p3)
|
|
382
|
+
syp = np.sin(y/p3)
|
|
383
|
+
czr = np.cos(z1/r3)
|
|
384
|
+
szr = np.sin(z1/r3)
|
|
385
|
+
expr= np.exp(sqpr*x1)
|
|
386
|
+
fx9 =-expr*cyp*(sqpr*z1*czr+szr/r3*(x1+1/sqpr))
|
|
387
|
+
hy9 = expr/p3*syp*(z1*czr+x1/r3*szr/sqpr)
|
|
388
|
+
fz9 =-expr*cyp*(czr*(1+x1/r3**2/sqpr)-z1/r3*szr)
|
|
389
|
+
hx9 = fx9*ct1+fz9*st1
|
|
390
|
+
hz9 =-fx9*st1+fz9*ct1
|
|
391
|
+
|
|
392
|
+
a1=a[0]+a[1]*cps
|
|
393
|
+
a2=a[2]+a[3]*cps
|
|
394
|
+
a3=a[4]+a[5]*cps
|
|
395
|
+
a4=a[6]+a[7]*cps
|
|
396
|
+
a5=a[8]+a[9]*cps
|
|
397
|
+
a6=a[10]+a[11]*cps
|
|
398
|
+
a7=a[12]+a[13]*cps
|
|
399
|
+
a8=a[14]+a[15]*cps
|
|
400
|
+
a9=a[16]+a[17]*cps
|
|
401
|
+
bx=a1*hx1+a2*hx2+a3*hx3+a4*hx4+a5*hx5+a6*hx6+a7*hx7+a8*hx8+a9*hx9
|
|
402
|
+
by=a1*hy1+a2*hy2+a3*hy3+a4*hy4+a5*hy5+a6*hy6+a7*hy7+a8*hy8+a9*hy9
|
|
403
|
+
bz=a1*hz1+a2*hz2+a3*hz3+a4*hz4+a5*hz5+a6*hz6+a7*hz7+a8*hz8+a9*hz9
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
# make the terms in the 2nd sum ("parallel" symmetry):
|
|
407
|
+
# i=1
|
|
408
|
+
sqqs= np.sqrt(1/q1**2+1/s1**2)
|
|
409
|
+
cyq = np.cos(y/q1)
|
|
410
|
+
syq = np.sin(y/q1)
|
|
411
|
+
czs = np.cos(z2/s1)
|
|
412
|
+
szs = np.sin(z2/s1)
|
|
413
|
+
exqs= np.exp(sqqs*x2)
|
|
414
|
+
fx1 =-sqqs*exqs*cyq*czs *sps
|
|
415
|
+
hy1 = exqs/q1*syq*czs *sps
|
|
416
|
+
fz1 = exqs*cyq/s1*szs *sps
|
|
417
|
+
hx1 = fx1*ct2+fz1*st2
|
|
418
|
+
hz1 =-fx1*st2+fz1*ct2
|
|
419
|
+
|
|
420
|
+
sqqs= np.sqrt(1/q1**2+1/s2**2)
|
|
421
|
+
cyq = np.cos(y/q1)
|
|
422
|
+
syq = np.sin(y/q1)
|
|
423
|
+
czs = np.cos(z2/s2)
|
|
424
|
+
szs = np.sin(z2/s2)
|
|
425
|
+
exqs= np.exp(sqqs*x2)
|
|
426
|
+
fx2 =-sqqs*exqs*cyq*czs *sps
|
|
427
|
+
hy2 = exqs/q1*syq*czs *sps
|
|
428
|
+
fz2 = exqs*cyq/s2*szs *sps
|
|
429
|
+
hx2 = fx2*ct2+fz2*st2
|
|
430
|
+
hz2 =-fx2*st2+fz2*ct2
|
|
431
|
+
|
|
432
|
+
sqqs= np.sqrt(1/q1**2+1/s3**2)
|
|
433
|
+
cyq = np.cos(y/q1)
|
|
434
|
+
syq = np.sin(y/q1)
|
|
435
|
+
czs = np.cos(z2/s3)
|
|
436
|
+
szs = np.sin(z2/s3)
|
|
437
|
+
exqs= np.exp(sqqs*x2)
|
|
438
|
+
fx3 =-sqqs*exqs*cyq*czs *sps
|
|
439
|
+
hy3 = exqs/q1*syq*czs *sps
|
|
440
|
+
fz3 = exqs*cyq/s3*szs *sps
|
|
441
|
+
hx3 = fx3*ct2+fz3*st2
|
|
442
|
+
hz3 =-fx3*st2+fz3*ct2
|
|
443
|
+
|
|
444
|
+
# i=2:
|
|
445
|
+
sqqs= np.sqrt(1/q2**2+1/s1**2)
|
|
446
|
+
cyq = np.cos(y/q2)
|
|
447
|
+
syq = np.sin(y/q2)
|
|
448
|
+
czs = np.cos(z2/s1)
|
|
449
|
+
szs = np.sin(z2/s1)
|
|
450
|
+
exqs= np.exp(sqqs*x2)
|
|
451
|
+
fx4 =-sqqs*exqs*cyq*czs *sps
|
|
452
|
+
hy4 = exqs/q2*syq*czs *sps
|
|
453
|
+
fz4 = exqs*cyq/s1*szs *sps
|
|
454
|
+
hx4 = fx4*ct2+fz4*st2
|
|
455
|
+
hz4 =-fx4*st2+fz4*ct2
|
|
456
|
+
|
|
457
|
+
sqqs= np.sqrt(1/q2**2+1/s2**2)
|
|
458
|
+
cyq = np.cos(y/q2)
|
|
459
|
+
syq = np.sin(y/q2)
|
|
460
|
+
czs = np.cos(z2/s2)
|
|
461
|
+
szs = np.sin(z2/s2)
|
|
462
|
+
exqs= np.exp(sqqs*x2)
|
|
463
|
+
fx5 =-sqqs*exqs*cyq*czs *sps
|
|
464
|
+
hy5 = exqs/q2*syq*czs *sps
|
|
465
|
+
fz5 = exqs*cyq/s2*szs *sps
|
|
466
|
+
hx5 = fx5*ct2+fz5*st2
|
|
467
|
+
hz5 =-fx5*st2+fz5*ct2
|
|
468
|
+
|
|
469
|
+
sqqs= np.sqrt(1/q2**2+1/s3**2)
|
|
470
|
+
cyq = np.cos(y/q2)
|
|
471
|
+
syq = np.sin(y/q2)
|
|
472
|
+
czs = np.cos(z2/s3)
|
|
473
|
+
szs = np.sin(z2/s3)
|
|
474
|
+
exqs= np.exp(sqqs*x2)
|
|
475
|
+
fx6 =-sqqs*exqs*cyq*czs *sps
|
|
476
|
+
hy6 = exqs/q2*syq*czs *sps
|
|
477
|
+
fz6 = exqs*cyq/s3*szs *sps
|
|
478
|
+
hx6 = fx6*ct2+fz6*st2
|
|
479
|
+
hz6 =-fx6*st2+fz6*ct2
|
|
480
|
+
|
|
481
|
+
# i=3:
|
|
482
|
+
sqqs= np.sqrt(1/q3**2+1/s1**2)
|
|
483
|
+
cyq = np.cos(y/q3)
|
|
484
|
+
syq = np.sin(y/q3)
|
|
485
|
+
czs = np.cos(z2/s1)
|
|
486
|
+
szs = np.sin(z2/s1)
|
|
487
|
+
exqs= np.exp(sqqs*x2)
|
|
488
|
+
fx7 =-sqqs*exqs*cyq*czs *sps
|
|
489
|
+
hy7 = exqs/q3*syq*czs *sps
|
|
490
|
+
fz7 = exqs*cyq/s1*szs *sps
|
|
491
|
+
hx7 = fx7*ct2+fz7*st2
|
|
492
|
+
hz7 =-fx7*st2+fz7*ct2
|
|
493
|
+
|
|
494
|
+
sqqs= np.sqrt(1/q3**2+1/s2**2)
|
|
495
|
+
cyq = np.cos(y/q3)
|
|
496
|
+
syq = np.sin(y/q3)
|
|
497
|
+
czs = np.cos(z2/s2)
|
|
498
|
+
szs = np.sin(z2/s2)
|
|
499
|
+
exqs= np.exp(sqqs*x2)
|
|
500
|
+
fx8 =-sqqs*exqs*cyq*czs *sps
|
|
501
|
+
hy8 = exqs/q3*syq*czs *sps
|
|
502
|
+
fz8 = exqs*cyq/s2*szs *sps
|
|
503
|
+
hx8 = fx8*ct2+fz8*st2
|
|
504
|
+
hz8 =-fx8*st2+fz8*ct2
|
|
505
|
+
|
|
506
|
+
sqqs= np.sqrt(1/q3**2+1/s3**2)
|
|
507
|
+
cyq = np.cos(y/q3)
|
|
508
|
+
syq = np.sin(y/q3)
|
|
509
|
+
czs = np.cos(z2/s3)
|
|
510
|
+
szs = np.sin(z2/s3)
|
|
511
|
+
exqs= np.exp(sqqs*x2)
|
|
512
|
+
fx9 =-sqqs*exqs*cyq*czs *sps
|
|
513
|
+
hy9 = exqs/q3*syq*czs *sps
|
|
514
|
+
fz9 = exqs*cyq/s3*szs *sps
|
|
515
|
+
hx9 = fx9*ct2+fz9*st2
|
|
516
|
+
hz9 =-fx9*st2+fz9*ct2
|
|
517
|
+
|
|
518
|
+
a1=a[18]+a[19]*s2ps
|
|
519
|
+
a2=a[20]+a[21]*s2ps
|
|
520
|
+
a3=a[22]+a[23]*s2ps
|
|
521
|
+
a4=a[24]+a[25]*s2ps
|
|
522
|
+
a5=a[26]+a[27]*s2ps
|
|
523
|
+
a6=a[28]+a[29]*s2ps
|
|
524
|
+
a7=a[30]+a[31]*s2ps
|
|
525
|
+
a8=a[32]+a[33]*s2ps
|
|
526
|
+
a9=a[34]+a[35]*s2ps
|
|
527
|
+
|
|
528
|
+
bx=bx+a1*hx1+a2*hx2+a3*hx3+a4*hx4+a5*hx5+a6*hx6+a7*hx7+a8*hx8+a9*hx9
|
|
529
|
+
by=by+a1*hy1+a2*hy2+a3*hy3+a4*hy4+a5*hy5+a6*hy6+a7*hy7+a8*hy8+a9*hy9
|
|
530
|
+
bz=bz+a1*hz1+a2*hz2+a3*hz3+a4*hz4+a5*hz5+a6*hz6+a7*hz7+a8*hz8+a9*hz9
|
|
531
|
+
|
|
532
|
+
return bx, by, bz
|
|
533
|
+
|
|
534
|
+
def deformed(iopt, ps, x,y,z):
|
|
535
|
+
"""
|
|
536
|
+
Calculates gsm components of two unit-amplitude tail field modes, taking into account
|
|
537
|
+
both effects of dipole tilt: warping in y-z (done by the subroutine warped) and bending
|
|
538
|
+
in x-z (done by this subroutine)
|
|
539
|
+
|
|
540
|
+
:param iopt: tail field mode flag: iopt=0 - the two tail modes are added up; iopt=1 - mode 1 only; iopt=2 - mode 2 only
|
|
541
|
+
:param ps: geo-dipole tilt angle in radius.
|
|
542
|
+
:param x,y,z: GSM coordinates in Re (1 Re = 6371.2 km)
|
|
543
|
+
:return:
|
|
544
|
+
"""
|
|
545
|
+
|
|
546
|
+
# rh0,rh1,rh2, and ieps control the tilt-related deformation of the tail field
|
|
547
|
+
# common /rh0/ rh0
|
|
548
|
+
global rh0
|
|
549
|
+
rh2,ieps = [-5.2,3]
|
|
550
|
+
|
|
551
|
+
sps = np.sin(ps)
|
|
552
|
+
r2 = x**2+y**2+z**2
|
|
553
|
+
r = np.sqrt(r2)
|
|
554
|
+
zr = z/r
|
|
555
|
+
rh = rh0+rh2*zr**2
|
|
556
|
+
drhdr = -zr/r*2*rh2*zr
|
|
557
|
+
drhdz = 2*rh2*zr/r
|
|
558
|
+
rrh = r/rh
|
|
559
|
+
f = 1/(1+rrh**ieps)**(1/ieps)
|
|
560
|
+
dfdr = -rrh**(ieps-1)*f**(ieps+1)/rh
|
|
561
|
+
dfdrh = -rrh*dfdr
|
|
562
|
+
|
|
563
|
+
spsas = sps*f
|
|
564
|
+
cpsas = np.sqrt(1-spsas**2)
|
|
565
|
+
|
|
566
|
+
xas = x*cpsas-z*spsas
|
|
567
|
+
zas = x*spsas+z*cpsas
|
|
568
|
+
|
|
569
|
+
facps = sps/cpsas*(dfdr+dfdrh*drhdr)/r
|
|
570
|
+
psasx = facps*x
|
|
571
|
+
psasy = facps*y
|
|
572
|
+
psasz = facps*z+sps/cpsas*dfdrh*drhdz
|
|
573
|
+
|
|
574
|
+
dxasdx = cpsas-zas*psasx
|
|
575
|
+
dxasdy =-zas*psasy
|
|
576
|
+
dxasdz =-spsas-zas*psasz
|
|
577
|
+
dzasdx = spsas+xas*psasx
|
|
578
|
+
dzasdy = xas*psasy
|
|
579
|
+
dzasdz = cpsas+xas*psasz
|
|
580
|
+
fac1 = dxasdz*dzasdy-dxasdy*dzasdz
|
|
581
|
+
fac2 = dxasdx*dzasdz-dxasdz*dzasdx
|
|
582
|
+
fac3 = dzasdx*dxasdy-dxasdx*dzasdy
|
|
583
|
+
|
|
584
|
+
# deform:
|
|
585
|
+
bxas1,byas1,bzas1, bxas2,byas2,bzas2 = warped(iopt,ps,xas,y,zas)
|
|
586
|
+
|
|
587
|
+
bx1=bxas1*dzasdz-bzas1*dxasdz +byas1*fac1
|
|
588
|
+
by1=byas1*fac2
|
|
589
|
+
bz1=bzas1*dxasdx-bxas1*dzasdx +byas1*fac3
|
|
590
|
+
|
|
591
|
+
bx2=bxas2*dzasdz-bzas2*dxasdz +byas2*fac1
|
|
592
|
+
by2=byas2*fac2
|
|
593
|
+
bz2=bzas2*dxasdx-bxas2*dzasdx +byas2*fac3
|
|
594
|
+
|
|
595
|
+
return bx1,by1,bz1, bx2,by2,bz2
|
|
596
|
+
|
|
597
|
+
def warped(iopt, ps, x,y,z):
|
|
598
|
+
"""
|
|
599
|
+
Calculates GSM components of the warped field for two tail unit modes. The warping deformation
|
|
600
|
+
is imposed on the unwarped field, computed by the subroutine "unwarped". The warping parameter
|
|
601
|
+
g was obtained by least squares fitting to the entire dataset.
|
|
602
|
+
|
|
603
|
+
:param iopt: tail field mode flag: iopt=0 - the two tail modes are added up; iopt=1 - mode 1 only; iopt=2 - mode 2 only
|
|
604
|
+
:param ps: geo-dipole tilt angle in radius.
|
|
605
|
+
:param x,y,z: GSM coordinates in Re (1 Re = 6371.2 km)
|
|
606
|
+
:return:
|
|
607
|
+
"""
|
|
608
|
+
|
|
609
|
+
# common /g/ g
|
|
610
|
+
global g
|
|
611
|
+
dgdx,xl,dxldx = [0.,20,0]
|
|
612
|
+
|
|
613
|
+
sps=np.sin(ps)
|
|
614
|
+
rho2=y**2+z**2
|
|
615
|
+
rho=np.sqrt(rho2)
|
|
616
|
+
|
|
617
|
+
if (y == 0) & (z == 0):
|
|
618
|
+
phi=0.
|
|
619
|
+
cphi=1.
|
|
620
|
+
sphi=0.
|
|
621
|
+
else:
|
|
622
|
+
phi=np.arctan2(z,y)
|
|
623
|
+
cphi=y/rho
|
|
624
|
+
sphi=z/rho
|
|
625
|
+
|
|
626
|
+
rr4l4=rho/(rho2**2+xl**4)
|
|
627
|
+
|
|
628
|
+
f=phi+g*rho2*rr4l4*cphi*sps
|
|
629
|
+
dfdphi=1-g*rho2*rr4l4*sphi*sps
|
|
630
|
+
dfdrho=g*rr4l4**2*(3*xl**4-rho2**2)*cphi*sps
|
|
631
|
+
dfdx=rr4l4*cphi*sps*(dgdx*rho2-g*rho*rr4l4*4*xl**3*dxldx)
|
|
632
|
+
|
|
633
|
+
cf=np.cos(f)
|
|
634
|
+
sf=np.sin(f)
|
|
635
|
+
yas=rho*cf
|
|
636
|
+
zas=rho*sf
|
|
637
|
+
|
|
638
|
+
bx_as1,by_as1,bz_as1, bx_as2,by_as2,bz_as2 = unwarped(iopt,x,yas,zas)
|
|
639
|
+
|
|
640
|
+
brho_as = by_as1*cf+bz_as1*sf # deform the 1st mode
|
|
641
|
+
bphi_as = -by_as1*sf+bz_as1*cf
|
|
642
|
+
brho_s = brho_as*dfdphi
|
|
643
|
+
bphi_s = bphi_as-rho*(bx_as1*dfdx+brho_as*dfdrho)
|
|
644
|
+
bx1 = bx_as1*dfdphi
|
|
645
|
+
by1 = brho_s*cphi-bphi_s*sphi
|
|
646
|
+
bz1 = brho_s*sphi+bphi_s*cphi # done
|
|
647
|
+
|
|
648
|
+
brho_as = by_as2*cf+bz_as2*sf # deform the 2nd mode
|
|
649
|
+
bphi_as = -by_as2*sf+bz_as2*cf
|
|
650
|
+
brho_s = brho_as*dfdphi
|
|
651
|
+
bphi_s = bphi_as-rho*(bx_as2*dfdx+brho_as*dfdrho)
|
|
652
|
+
bx2 = bx_as2*dfdphi
|
|
653
|
+
by2 = brho_s*cphi-bphi_s*sphi
|
|
654
|
+
bz2 = brho_s*sphi+bphi_s*cphi # done
|
|
655
|
+
|
|
656
|
+
return bx1,by1,bz1, bx2,by2,bz2
|
|
657
|
+
|
|
658
|
+
def unwarped(iopt, x,y,z):
|
|
659
|
+
"""
|
|
660
|
+
Calculates GSM components of the shielded field of two tail modes with unit amplitudes, without any
|
|
661
|
+
warping or bending. Nonlinear parameters of the modes are forwarded here via a common block /tail/.
|
|
662
|
+
:param iopt: tail field mode flag: iopt=0 - the two tail modes are added up; iopt=1 - mode 1 only; iopt=2 - mode 2 only
|
|
663
|
+
:param x,y,z: GSM coordinates in Re (1 Re = 6371.2 km)
|
|
664
|
+
:return:
|
|
665
|
+
"""
|
|
666
|
+
|
|
667
|
+
# common /tail/ dxshift1,dxshift2,d,deltady
|
|
668
|
+
global dxshift1, dxshift2, d, deltady
|
|
669
|
+
|
|
670
|
+
deltadx1,alpha1,xshift1 = [1.,1.1,6]
|
|
671
|
+
deltadx2,alpha2,xshift2 = [0.,.25,4]
|
|
672
|
+
|
|
673
|
+
a1 = np.array([
|
|
674
|
+
-25.45869857,57.35899080,317.5501869,-2.626756717,-93.38053698,
|
|
675
|
+
-199.6467926,-858.8129729,34.09192395,845.4214929,-29.07463068,
|
|
676
|
+
47.10678547,-128.9797943,-781.7512093,6.165038619,167.8905046,
|
|
677
|
+
492.0680410,1654.724031,-46.77337920,-1635.922669,40.86186772,
|
|
678
|
+
-.1349775602,-.9661991179e-01,-.1662302354,.002810467517,.2487355077,
|
|
679
|
+
.1025565237,-14.41750229,-.8185333989,11.07693629,.7569503173,
|
|
680
|
+
-9.655264745,112.2446542,777.5948964,-5.745008536,-83.03921993,
|
|
681
|
+
-490.2278695,-1155.004209,39.08023320,1172.780574,-39.44349797,
|
|
682
|
+
-14.07211198,-40.41201127,-313.2277343,2.203920979,8.232835341,
|
|
683
|
+
197.7065115,391.2733948,-18.57424451,-437.2779053,23.04976898,
|
|
684
|
+
11.75673963,13.60497313,4.691927060,18.20923547,27.59044809,
|
|
685
|
+
6.677425469,1.398283308,2.839005878,31.24817706,24.53577264])
|
|
686
|
+
|
|
687
|
+
a2 = np.array([
|
|
688
|
+
-287187.1962,4970.499233,410490.1952,-1347.839052,-386370.3240,
|
|
689
|
+
3317.983750,-143462.3895,5706.513767,171176.2904,250.8882750,
|
|
690
|
+
-506570.8891,5733.592632,397975.5842,9771.762168,-941834.2436,
|
|
691
|
+
7990.975260,54313.10318,447.5388060,528046.3449,12751.04453,
|
|
692
|
+
-21920.98301,-21.05075617,31971.07875,3012.641612,-301822.9103,
|
|
693
|
+
-3601.107387,1797.577552,-6.315855803,142578.8406,13161.93640,
|
|
694
|
+
804184.8410,-14168.99698,-851926.6360,-1890.885671,972475.6869,
|
|
695
|
+
-8571.862853,26432.49197,-2554.752298,-482308.3431,-4391.473324,
|
|
696
|
+
105155.9160,-1134.622050,-74353.53091,-5382.670711,695055.0788,
|
|
697
|
+
-916.3365144,-12111.06667,67.20923358,-367200.9285,-21414.14421,
|
|
698
|
+
14.75567902,20.75638190,59.78601609,16.86431444,32.58482365,
|
|
699
|
+
23.69472951,17.24977936,13.64902647,68.40989058,11.67828167])
|
|
700
|
+
|
|
701
|
+
xm1,xm2 = [-12.,-12]
|
|
702
|
+
bx1,by1,bz1, bx2,by2,bz2 = [0.]*6
|
|
703
|
+
|
|
704
|
+
if iopt < 2: # iopt = 0 or 1
|
|
705
|
+
xsc1 = (x-xshift1-dxshift1)*alpha1-xm1*(alpha1-1)
|
|
706
|
+
ysc1 = y*alpha1
|
|
707
|
+
zsc1 = z*alpha1
|
|
708
|
+
d0sc1 = d*alpha1 # here we use a single value d0 of the thickness for both modes
|
|
709
|
+
|
|
710
|
+
fx1,fy1,fz1 = taildisk(d0sc1,deltadx1,deltady,xsc1,ysc1,zsc1)
|
|
711
|
+
hx1,hy1,hz1 = shlcar5x5(a1,x,y,z,dxshift1)
|
|
712
|
+
|
|
713
|
+
bx1=fx1+hx1
|
|
714
|
+
by1=fy1+hy1
|
|
715
|
+
bz1=fz1+hz1
|
|
716
|
+
|
|
717
|
+
if iopt != 1: # iop = 0 or 2
|
|
718
|
+
xsc2 = (x-xshift2-dxshift2)*alpha2-xm2*(alpha2-1)
|
|
719
|
+
ysc2 = y*alpha2
|
|
720
|
+
zsc2 = z*alpha2
|
|
721
|
+
d0sc2 = d*alpha2 # here we use a single value d0 of the thickness for both modes
|
|
722
|
+
|
|
723
|
+
fx2,fy2,fz2 = taildisk(d0sc2,deltadx2,deltady,xsc2,ysc2,zsc2)
|
|
724
|
+
hx2,hy2,hz2 = shlcar5x5(a2,x,y,z,dxshift2)
|
|
725
|
+
|
|
726
|
+
bx2=fx2+hx2
|
|
727
|
+
by2=fy2+hy2
|
|
728
|
+
bz2=fz2+hz2
|
|
729
|
+
|
|
730
|
+
return bx1,by1,bz1, bx2,by2,bz2
|
|
731
|
+
|
|
732
|
+
def taildisk(d0,deltadx,deltady, x,y,z):
|
|
733
|
+
"""
|
|
734
|
+
This subroutine computes the components of the tail current field, similar to that described by
|
|
735
|
+
Tsyganenko and peredo (1994). The difference is that now we use spacewarping, as described in
|
|
736
|
+
our paper on modeling Birkeland currents (Tsyganenko and stern, 1996) instead of shearing it in
|
|
737
|
+
the spirit of the T89 tail model.
|
|
738
|
+
|
|
739
|
+
:param d0:
|
|
740
|
+
:param deltadx:
|
|
741
|
+
:param deltady:
|
|
742
|
+
:param x,y,z: GSM coordinates in Re (1 Re = 6371.2 km)
|
|
743
|
+
:return: bx,by,bz. Field components in GSM system, in nT.
|
|
744
|
+
"""
|
|
745
|
+
|
|
746
|
+
f = np.array([-71.09346626,-1014.308601,-1272.939359,-3224.935936,-44546.86232])
|
|
747
|
+
b = np.array([10.90101242,12.68393898,13.51791954,14.86775017,15.12306404])
|
|
748
|
+
c = np.array([.7954069972,.6716601849,1.174866319,2.565249920,10.01986790])
|
|
749
|
+
|
|
750
|
+
rho=np.sqrt(x**2+y**2)
|
|
751
|
+
drhodx=x/rho
|
|
752
|
+
drhody=y/rho
|
|
753
|
+
|
|
754
|
+
dex=np.exp(x/7)
|
|
755
|
+
d=d0+deltady*(y/20)**2+deltadx*dex # The last term (introduced 10/11/2000) makes the sheet thicken sunward, to avoid problems in the subsolar region
|
|
756
|
+
dddy=deltady*y*0.005
|
|
757
|
+
dddx=deltadx/7*dex
|
|
758
|
+
|
|
759
|
+
dzeta=np.sqrt(z**2+d**2) # this is the same simple way to spread out the sheet, as that used in t89
|
|
760
|
+
ddzetadx=d*dddx/dzeta
|
|
761
|
+
ddzetady=d*dddy/dzeta
|
|
762
|
+
ddzetadz=z/dzeta
|
|
763
|
+
|
|
764
|
+
dbx,dby,dbz = [0.0,0,0]
|
|
765
|
+
|
|
766
|
+
for i in range(5):
|
|
767
|
+
bi=b[i]
|
|
768
|
+
ci=c[i]
|
|
769
|
+
|
|
770
|
+
s1=np.sqrt((rho+bi)**2+(dzeta+ci)**2)
|
|
771
|
+
s2=np.sqrt((rho-bi)**2+(dzeta+ci)**2)
|
|
772
|
+
|
|
773
|
+
ds1drho=(rho+bi)/s1
|
|
774
|
+
ds2drho=(rho-bi)/s2
|
|
775
|
+
ds1ddz=(dzeta+ci)/s1
|
|
776
|
+
ds2ddz=(dzeta+ci)/s2
|
|
777
|
+
|
|
778
|
+
ds1dx=ds1drho*drhodx+ds1ddz*ddzetadx
|
|
779
|
+
ds1dy=ds1drho*drhody+ds1ddz*ddzetady
|
|
780
|
+
ds1dz= ds1ddz*ddzetadz
|
|
781
|
+
|
|
782
|
+
ds2dx=ds2drho*drhodx+ds2ddz*ddzetadx
|
|
783
|
+
ds2dy=ds2drho*drhody+ds2ddz*ddzetady
|
|
784
|
+
ds2dz= ds2ddz*ddzetadz
|
|
785
|
+
|
|
786
|
+
s1ts2=s1*s2
|
|
787
|
+
s1ps2=s1+s2
|
|
788
|
+
s1ps2sq=s1ps2**2
|
|
789
|
+
|
|
790
|
+
fac1=np.sqrt(s1ps2sq-(2*bi)**2)
|
|
791
|
+
asas=fac1/(s1ts2*s1ps2sq)
|
|
792
|
+
dasds1=(1/(fac1*s2)-asas/s1ps2*(s2*s2+s1*(3*s1+4*s2)))/(s1*s1ps2)
|
|
793
|
+
dasds2=(1/(fac1*s1)-asas/s1ps2*(s1*s1+s2*(3*s2+4*s1)))/(s2*s1ps2)
|
|
794
|
+
|
|
795
|
+
dasdx=dasds1*ds1dx+dasds2*ds2dx
|
|
796
|
+
dasdy=dasds1*ds1dy+dasds2*ds2dy
|
|
797
|
+
dasdz=dasds1*ds1dz+dasds2*ds2dz
|
|
798
|
+
|
|
799
|
+
dbx=dbx-f[i]*x*dasdz
|
|
800
|
+
dby=dby-f[i]*y*dasdz
|
|
801
|
+
dbz=dbz+f[i]*(2*asas+x*dasdx+y*dasdy)
|
|
802
|
+
|
|
803
|
+
return dbx, dby, dbz
|
|
804
|
+
|
|
805
|
+
def shlcar5x5(a,x,y,z,dshift):
|
|
806
|
+
"""
|
|
807
|
+
This code returns the shielding field represented by 5x5=25 "cartesian" harmonics
|
|
808
|
+
|
|
809
|
+
:param a:
|
|
810
|
+
:param x,y,z: GSM coordinates in Re (1 Re = 6371.2 km)
|
|
811
|
+
:param dshift:
|
|
812
|
+
:return:
|
|
813
|
+
"""
|
|
814
|
+
|
|
815
|
+
# The nlin coefficients are the amplitudes of the "cartesian" harmonics (a(1)-a(nlin).
|
|
816
|
+
# The nnp nonlinear parameters (a(nlin+1)-a(ntot) are the scales pi and ri entering the arguments of exponents, sines,
|
|
817
|
+
# and cosines in each of the nlin "cartesian" harmonics
|
|
818
|
+
|
|
819
|
+
dhx,dhy,dhz = [0.]*3
|
|
820
|
+
|
|
821
|
+
l=0
|
|
822
|
+
for i in range(5):
|
|
823
|
+
rp=1/a[50+i]
|
|
824
|
+
cypi=np.cos(y*rp)
|
|
825
|
+
sypi=np.sin(y*rp)
|
|
826
|
+
|
|
827
|
+
for k in range(5):
|
|
828
|
+
rr=1/a[55+k]
|
|
829
|
+
szrk=np.sin(z*rr)
|
|
830
|
+
czrk=np.cos(z*rr)
|
|
831
|
+
sqpr=np.sqrt(rp**2+rr**2)
|
|
832
|
+
epr= np.exp(x*sqpr)
|
|
833
|
+
|
|
834
|
+
dbx=-sqpr*epr*cypi*szrk
|
|
835
|
+
dby= rp*epr*sypi*szrk
|
|
836
|
+
dbz=-rr*epr*cypi*czrk
|
|
837
|
+
|
|
838
|
+
coef=a[l]+a[l+1]*dshift
|
|
839
|
+
l += 2
|
|
840
|
+
dhx=dhx+coef*dbx
|
|
841
|
+
dhy=dhy+coef*dby
|
|
842
|
+
dhz=dhz+coef*dbz
|
|
843
|
+
|
|
844
|
+
return dhx,dhy,dhz
|
|
845
|
+
|
|
846
|
+
def birk_tot(iopb, ps, x,y,z):
|
|
847
|
+
"""
|
|
848
|
+
|
|
849
|
+
:param iopb: birkeland field mode flag:
|
|
850
|
+
iopb=0 - all components; iopb=1 - region 1, modes 1 & 2; iopb=2 - region 2, modes 1 & 2
|
|
851
|
+
:param ps: geo-dipole tilt angle in radius.
|
|
852
|
+
:param x,y,z: GSM coordinates in Re (1 Re = 6371.2 km)
|
|
853
|
+
:return: bx11,by11,bz11, bx12,by12,bz12, bx21,by21,bz21, bx22,by22,bz22.
|
|
854
|
+
"""
|
|
855
|
+
|
|
856
|
+
# common /birkpar/ xkappa1,xkappa2 ! input parameters, specified from s/r extall
|
|
857
|
+
# common /dphi_b_rho0/ dphi,b,rho_0,xkappa ! parameters, controlling the day-night asymmetry of f.a.c.
|
|
858
|
+
global xkappa1, xkappa2
|
|
859
|
+
global dphi, b, rho_0, xkappa
|
|
860
|
+
|
|
861
|
+
sh11 = np.array([
|
|
862
|
+
46488.84663,-15541.95244,-23210.09824,-32625.03856,-109894.4551,
|
|
863
|
+
-71415.32808,58168.94612,55564.87578,-22890.60626,-6056.763968,
|
|
864
|
+
5091.368100,239.7001538,-13899.49253,4648.016991,6971.310672,
|
|
865
|
+
9699.351891,32633.34599,21028.48811,-17395.96190,-16461.11037,
|
|
866
|
+
7447.621471,2528.844345,-1934.094784,-588.3108359,-32588.88216,
|
|
867
|
+
10894.11453,16238.25044,22925.60557,77251.11274,50375.97787,
|
|
868
|
+
-40763.78048,-39088.60660,15546.53559,3559.617561,-3187.730438,
|
|
869
|
+
309.1487975,88.22153914,-243.0721938,-63.63543051,191.1109142,
|
|
870
|
+
69.94451996,-187.9539415,-49.89923833,104.0902848,-120.2459738,
|
|
871
|
+
253.5572433,89.25456949,-205.6516252,-44.93654156,124.7026309,
|
|
872
|
+
32.53005523,-98.85321751,-36.51904756,98.88241690,24.88493459,
|
|
873
|
+
-55.04058524,61.14493565,-128.4224895,-45.35023460,105.0548704,
|
|
874
|
+
-43.66748755,119.3284161,31.38442798,-92.87946767,-33.52716686,
|
|
875
|
+
89.98992001,25.87341323,-48.86305045,59.69362881,-126.5353789,
|
|
876
|
+
-44.39474251,101.5196856,59.41537992,41.18892281,80.86101200,
|
|
877
|
+
3.066809418,7.893523804,30.56212082,10.36861082,8.222335945,
|
|
878
|
+
19.97575641,2.050148531,4.992657093,2.300564232,.2256245602,-.05841594319])
|
|
879
|
+
|
|
880
|
+
sh12 = np.array([
|
|
881
|
+
210260.4816,-1443587.401,-1468919.281,281939.2993,-1131124.839,
|
|
882
|
+
729331.7943,2573541.307,304616.7457,468887.5847,181554.7517,
|
|
883
|
+
-1300722.650,-257012.8601,645888.8041,-2048126.412,-2529093.041,
|
|
884
|
+
571093.7972,-2115508.353,1122035.951,4489168.802,75234.22743,
|
|
885
|
+
823905.6909,147926.6121,-2276322.876,-155528.5992,-858076.2979,
|
|
886
|
+
3474422.388,3986279.931,-834613.9747,3250625.781,-1818680.377,
|
|
887
|
+
-7040468.986,-414359.6073,-1295117.666,-346320.6487,3565527.409,
|
|
888
|
+
430091.9496,-.1565573462,7.377619826,.4115646037,-6.146078880,
|
|
889
|
+
3.808028815,-.5232034932,1.454841807,-12.32274869,-4.466974237,
|
|
890
|
+
-2.941184626,-.6172620658,12.64613490,1.494922012,-21.35489898,
|
|
891
|
+
-1.652256960,16.81799898,-1.404079922,-24.09369677,-10.99900839,
|
|
892
|
+
45.94237820,2.248579894,31.91234041,7.575026816,-45.80833339,
|
|
893
|
+
-1.507664976,14.60016998,1.348516288,-11.05980247,-5.402866968,
|
|
894
|
+
31.69094514,12.28261196,-37.55354174,4.155626879,-33.70159657,
|
|
895
|
+
-8.437907434,36.22672602,145.0262164,70.73187036,85.51110098,
|
|
896
|
+
21.47490989,24.34554406,31.34405345,4.655207476,5.747889264,
|
|
897
|
+
7.802304187,1.844169801,4.867254550,2.941393119,.1379899178,.06607020029])
|
|
898
|
+
|
|
899
|
+
sh21 = np.array([
|
|
900
|
+
162294.6224,503885.1125,-27057.67122,-531450.1339,84747.05678,
|
|
901
|
+
-237142.1712,84133.61490,259530.0402,69196.05160,-189093.5264,
|
|
902
|
+
-19278.55134,195724.5034,-263082.6367,-818899.6923,43061.10073,
|
|
903
|
+
863506.6932,-139707.9428,389984.8850,-135167.5555,-426286.9206,
|
|
904
|
+
-109504.0387,295258.3531,30415.07087,-305502.9405,100785.3400,
|
|
905
|
+
315010.9567,-15999.50673,-332052.2548,54964.34639,-152808.3750,
|
|
906
|
+
51024.67566,166720.0603,40389.67945,-106257.7272,-11126.14442,
|
|
907
|
+
109876.2047,2.978695024,558.6019011,2.685592939,-338.0004730,
|
|
908
|
+
-81.99724090,-444.1102659,89.44617716,212.0849592,-32.58562625,
|
|
909
|
+
-982.7336105,-35.10860935,567.8931751,-1.917212423,-260.2023543,
|
|
910
|
+
-1.023821735,157.5533477,23.00200055,232.0603673,-36.79100036,
|
|
911
|
+
-111.9110936,18.05429984,447.0481000,15.10187415,-258.7297813,
|
|
912
|
+
-1.032340149,-298.6402478,-1.676201415,180.5856487,64.52313024,
|
|
913
|
+
209.0160857,-53.85574010,-98.52164290,14.35891214,536.7666279,
|
|
914
|
+
20.09318806,-309.7349530,58.54144539,67.45226850,97.92374406,
|
|
915
|
+
4.752449760,10.46824379,32.91856110,12.05124381,9.962933904,
|
|
916
|
+
15.91258637,1.804233877,6.578149088,2.515223491,.1930034238,-.02261109942])
|
|
917
|
+
|
|
918
|
+
sh22 = np.array([
|
|
919
|
+
-131287.8986,-631927.6885,-318797.4173,616785.8782,-50027.36189,
|
|
920
|
+
863099.9833,47680.20240,-1053367.944,-501120.3811,-174400.9476,
|
|
921
|
+
222328.6873,333551.7374,-389338.7841,-1995527.467,-982971.3024,
|
|
922
|
+
1960434.268,297239.7137,2676525.168,-147113.4775,-3358059.979,
|
|
923
|
+
-2106979.191,-462827.1322,1017607.960,1039018.475,520266.9296,
|
|
924
|
+
2627427.473,1301981.763,-2577171.706,-238071.9956,-3539781.111,
|
|
925
|
+
94628.16420,4411304.724,2598205.733,637504.9351,-1234794.298,
|
|
926
|
+
-1372562.403,-2.646186796,-31.10055575,2.295799273,19.20203279,
|
|
927
|
+
30.01931202,-302.1028550,-14.78310655,162.1561899,.4943938056,
|
|
928
|
+
176.8089129,-.2444921680,-100.6148929,9.172262228,137.4303440,
|
|
929
|
+
-8.451613443,-84.20684224,-167.3354083,1321.830393,76.89928813,
|
|
930
|
+
-705.7586223,18.28186732,-770.1665162,-9.084224422,436.3368157,
|
|
931
|
+
-6.374255638,-107.2730177,6.080451222,65.53843753,143.2872994,
|
|
932
|
+
-1028.009017,-64.22739330,547.8536586,-20.58928632,597.3893669,
|
|
933
|
+
10.17964133,-337.7800252,159.3532209,76.34445954,84.74398828,
|
|
934
|
+
12.76722651,27.63870691,32.69873634,5.145153451,6.310949163,
|
|
935
|
+
6.996159733,1.971629939,4.436299219,2.904964304,.1486276863,.06859991529])
|
|
936
|
+
|
|
937
|
+
xkappa=xkappa1 # forwarded in birk_1n2
|
|
938
|
+
x_sc=xkappa1-1.1 # forwarded in birk_shl
|
|
939
|
+
|
|
940
|
+
bx11,by11,bz11, bx12,by12,bz12, bx21,by21,bz21, bx22,by22,bz22 = [0]*12
|
|
941
|
+
|
|
942
|
+
if (iopb == 0) | (iopb == 1):
|
|
943
|
+
fx11,fy11,fz11 = birk_1n2(1,1,ps,x,y,z) # region 1, mode 1
|
|
944
|
+
hx11,hy11,hz11 = birk_shl(sh11,ps,x_sc,x,y,z)
|
|
945
|
+
bx11=fx11+hx11
|
|
946
|
+
by11=fy11+hy11
|
|
947
|
+
bz11=fz11+hz11
|
|
948
|
+
|
|
949
|
+
|
|
950
|
+
fx12,fy12,fz12 = birk_1n2(1,2,ps,x,y,z) # region 1, mode 2
|
|
951
|
+
hx12,hy12,hz12 = birk_shl(sh12,ps,x_sc,x,y,z)
|
|
952
|
+
bx12=fx12+hx12
|
|
953
|
+
by12=fy12+hy12
|
|
954
|
+
bz12=fz12+hz12
|
|
955
|
+
|
|
956
|
+
xkappa=xkappa2 # forwarded in birk_1n2
|
|
957
|
+
x_sc=xkappa2-1.0 # forwarded in birk_shl
|
|
958
|
+
|
|
959
|
+
if (iopb == 0) | (iopb == 2):
|
|
960
|
+
fx21,fy21,fz21 = birk_1n2(2,1,ps,x,y,z) # region 2, mode 1
|
|
961
|
+
hx21,hy21,hz21 = birk_shl(sh21,ps,x_sc,x,y,z)
|
|
962
|
+
bx21=fx21+hx21
|
|
963
|
+
by21=fy21+hy21
|
|
964
|
+
bz21=fz21+hz21
|
|
965
|
+
|
|
966
|
+
fx22,fy22,fz22 = birk_1n2(2,2,ps,x,y,z) # region 2, mode 2
|
|
967
|
+
hx22,hy22,hz22 = birk_shl(sh22,ps,x_sc,x,y,z)
|
|
968
|
+
bx22=fx22+hx22
|
|
969
|
+
by22=fy22+hy22
|
|
970
|
+
bz22=fz22+hz22
|
|
971
|
+
|
|
972
|
+
return bx11,by11,bz11, bx12,by12,bz12, bx21,by21,bz21, bx22,by22,bz22
|
|
973
|
+
|
|
974
|
+
def birk_1n2(numb,mode,ps,x,y,z): # NB# 6, p.60
|
|
975
|
+
"""
|
|
976
|
+
Calculates components of region 1/2 field in spherical coords. Derived from the s/r dipdef2c
|
|
977
|
+
(which does the same job, but input/output there was in spherical coords, while here we use cartesian ones)
|
|
978
|
+
:param numb: numb=1 (2) for region 1 (2) currents
|
|
979
|
+
:param mode: mode=1 yields simple sinusoidal mlt variation, with maximum current at dawn/dusk meridian
|
|
980
|
+
while mode=2 yields the second harmonic.
|
|
981
|
+
:param ps: geo-dipole tilt angle in radius.
|
|
982
|
+
:param x,y,z: GSM coordinates in Re (1 Re = 6371.2 km)
|
|
983
|
+
:return: bx,by,bz. Field components in GSM system, in nT.
|
|
984
|
+
"""
|
|
985
|
+
|
|
986
|
+
# common /dphi_b_rho0/ dphi,b,rho_0,xkappa ! these parameters control day-night asymmetry of f.a.c., as follows:
|
|
987
|
+
# (1) dphi: half-difference (in radians) between day and night latitude of fac oval at ionospheric altitude; typical value: 0.06
|
|
988
|
+
# (2) b: an asymmetry factor at high-altitudes; for b=0, the only asymmetry is that from dphi; typical values: 0.35-0.70
|
|
989
|
+
# (3) rho_0: a fixed parameter, defining the distance rho, at which the latitude shift gradually saturates and stops increasing; its value was assumed fixed, equal to 7.0.
|
|
990
|
+
# (4) xkappa: an overall scaling factor, which can be used for changing the size of the f.a.c. oval
|
|
991
|
+
|
|
992
|
+
|
|
993
|
+
global dtheta, m, dphi, b, rho_0, xkappa
|
|
994
|
+
|
|
995
|
+
# parameters of the tilt-dependent deformation of the untilted F.A.C. field
|
|
996
|
+
beta = 0.9
|
|
997
|
+
rh = 10.
|
|
998
|
+
eps = 3.
|
|
999
|
+
b=0.5
|
|
1000
|
+
rho_0=7.0
|
|
1001
|
+
|
|
1002
|
+
a11 = np.array([
|
|
1003
|
+
.1618068350, -.1797957553, 2.999642482, -.9322708978, -.6811059760,
|
|
1004
|
+
.2099057262, -8.358815746, -14.86033550, .3838362986, -16.30945494,
|
|
1005
|
+
4.537022847, 2.685836007, 27.97833029, 6.330871059, 1.876532361,
|
|
1006
|
+
18.95619213, .9651528100, .4217195118, -.08957770020, -1.823555887,
|
|
1007
|
+
.7457045438, -.5785916524, -1.010200918, .01112389357, .09572927448,
|
|
1008
|
+
-.3599292276, 8.713700514, .9763932955, 3.834602998, 2.492118385, .7113544659])
|
|
1009
|
+
a12 = np.array([
|
|
1010
|
+
.7058026940, -.2845938535, 5.715471266, -2.472820880, -.7738802408,
|
|
1011
|
+
.3478293930, -11.37653694, -38.64768867, .6932927651, -212.4017288,
|
|
1012
|
+
4.944204937, 3.071270411, 33.05882281, 7.387533799, 2.366769108,
|
|
1013
|
+
79.22572682, .6154290178, .5592050551, -.1796585105, -1.654932210,
|
|
1014
|
+
.7309108776, -.4926292779, -1.130266095, -.009613974555, .1484586169,
|
|
1015
|
+
-.2215347198, 7.883592948, .02768251655, 2.950280953, 1.212634762, .5567714182])
|
|
1016
|
+
a21 = np.array([
|
|
1017
|
+
.1278764024, -.2320034273, 1.805623266, -32.37241440, -.9931490648,
|
|
1018
|
+
.3175085630, -2.492465814, -16.21600096, .2695393416, -6.752691265,
|
|
1019
|
+
3.971794901, 14.54477563, 41.10158386, 7.912889730, 1.258297372,
|
|
1020
|
+
9.583547721, 1.014141963, .5104134759, -.1790430468, -1.756358428,
|
|
1021
|
+
.7561986717, -.6775248254, -.04014016420, .01446794851, .1200521731,
|
|
1022
|
+
-.2203584559, 4.508963850, .8221623576, 1.779933730, 1.102649543, .8867880020])
|
|
1023
|
+
a22 = np.array([
|
|
1024
|
+
.4036015198, -.3302974212, 2.827730930, -45.44405830, -1.611103927,
|
|
1025
|
+
.4927112073, -.003258457559, -49.59014949, .3796217108, -233.7884098,
|
|
1026
|
+
4.312666980, 18.05051709, 28.95320323, 11.09948019, .7471649558,
|
|
1027
|
+
67.10246193, .5667096597, .6468519751, -.1560665317, -1.460805289,
|
|
1028
|
+
.7719653528, -.6658988668, .2515179349E-05, .02426021891, .1195003324,
|
|
1029
|
+
-.2625739255, 4.377172556, .2421190547, 2.503482679, 1.071587299, .7247997430])
|
|
1030
|
+
|
|
1031
|
+
|
|
1032
|
+
m=mode
|
|
1033
|
+
if numb == 1:
|
|
1034
|
+
dphi=0.055
|
|
1035
|
+
dtheta=0.06
|
|
1036
|
+
elif numb == 2:
|
|
1037
|
+
dphi=0.030
|
|
1038
|
+
dtheta=0.09
|
|
1039
|
+
else:
|
|
1040
|
+
raise ValueError
|
|
1041
|
+
|
|
1042
|
+
|
|
1043
|
+
xsc=x*xkappa
|
|
1044
|
+
ysc=y*xkappa
|
|
1045
|
+
zsc=z*xkappa
|
|
1046
|
+
rho=np.sqrt(xsc**2+zsc**2)
|
|
1047
|
+
|
|
1048
|
+
rsc=np.sqrt(xsc**2+ysc**2+zsc**2) # scaled
|
|
1049
|
+
rho2=rho_0**2
|
|
1050
|
+
|
|
1051
|
+
if (xsc == 0) & (zsc == 0):
|
|
1052
|
+
phi=0.
|
|
1053
|
+
else:
|
|
1054
|
+
phi=np.arctan2(-zsc,xsc) # from cartesian to cylindrical (rho,phi,y)
|
|
1055
|
+
|
|
1056
|
+
sphic=np.sin(phi)
|
|
1057
|
+
cphic=np.cos(phi) # "c" means "cylindrical", to distinguish from spherical phi
|
|
1058
|
+
|
|
1059
|
+
brack=dphi+b*rho2/(rho2+1)*(rho**2-1)/(rho2+rho**2)
|
|
1060
|
+
r1rh=(rsc-1)/rh
|
|
1061
|
+
psias=beta*ps/(1+r1rh**eps)**(1/eps)
|
|
1062
|
+
|
|
1063
|
+
phis=phi-brack*np.sin(phi) -psias
|
|
1064
|
+
dphisphi=1-brack*np.cos(phi)
|
|
1065
|
+
dphisrho=-2*b*rho2*rho/(rho2+rho**2)**2*np.sin(phi) \
|
|
1066
|
+
+beta*ps*r1rh**(eps-1)*rho/(rh*rsc*(1+r1rh**eps)**(1/eps+1))
|
|
1067
|
+
dphisdy= beta*ps*r1rh**(eps-1)*ysc/(rh*rsc*(1+r1rh**eps)**(1/eps+1))
|
|
1068
|
+
|
|
1069
|
+
sphics=np.sin(phis)
|
|
1070
|
+
cphics=np.cos(phis)
|
|
1071
|
+
|
|
1072
|
+
xs= rho*cphics
|
|
1073
|
+
zs=-rho*sphics
|
|
1074
|
+
|
|
1075
|
+
if numb ==1:
|
|
1076
|
+
if mode == 1: [bxs,byas,bzs] = twocones(a11,xs,ysc,zs)
|
|
1077
|
+
elif mode == 2: [bxs,byas,bzs] = twocones(a12,xs,ysc,zs)
|
|
1078
|
+
else: raise ValueError
|
|
1079
|
+
else:
|
|
1080
|
+
if mode == 1: [bxs,byas,bzs] = twocones(a21,xs,ysc,zs)
|
|
1081
|
+
elif mode == 2: [bxs,byas,bzs] = twocones(a22,xs,ysc,zs)
|
|
1082
|
+
else: raise ValueError
|
|
1083
|
+
|
|
1084
|
+
brhoas = bxs*cphics-bzs*sphics
|
|
1085
|
+
bphias = -bxs*sphics-bzs*cphics
|
|
1086
|
+
|
|
1087
|
+
brho_s=brhoas*dphisphi *xkappa # scaling
|
|
1088
|
+
bphi_s=(bphias-rho*(byas*dphisdy+brhoas*dphisrho)) *xkappa
|
|
1089
|
+
by_s=byas*dphisphi *xkappa
|
|
1090
|
+
|
|
1091
|
+
bx=brho_s*cphic-bphi_s*sphic
|
|
1092
|
+
by=by_s
|
|
1093
|
+
bz=-brho_s*sphic-bphi_s*cphic
|
|
1094
|
+
|
|
1095
|
+
return bx,by,bz
|
|
1096
|
+
|
|
1097
|
+
|
|
1098
|
+
|
|
1099
|
+
def twocones (a,x,y,z):
|
|
1100
|
+
"""
|
|
1101
|
+
Adds fields from two cones (northern and southern), with a proper symmetry of the current and field,
|
|
1102
|
+
corresponding to the region 1 Birkeland currents. (NB #6, p.58).
|
|
1103
|
+
|
|
1104
|
+
:param a:
|
|
1105
|
+
:param x,y,z: GSM coordinates in Re (1 Re = 6371.2 km)
|
|
1106
|
+
:return: bx,by,bz. Field components in GSM system, in nT.
|
|
1107
|
+
"""
|
|
1108
|
+
|
|
1109
|
+
bxn,byn,bzn = one_cone(a,x, y, z)
|
|
1110
|
+
bxs,bys,bzs = one_cone(a,x,-y,-z)
|
|
1111
|
+
bx=bxn-bxs
|
|
1112
|
+
by=byn+bys
|
|
1113
|
+
bz=bzn+bzs
|
|
1114
|
+
|
|
1115
|
+
return bx,by,bz
|
|
1116
|
+
|
|
1117
|
+
def one_cone(a,x,y,z):
|
|
1118
|
+
"""
|
|
1119
|
+
Returns field components for a deformed conical current system, fitted to a Biosavart field.
|
|
1120
|
+
Here only the northern cone is taken into account.
|
|
1121
|
+
|
|
1122
|
+
:param a: dimension a(31)
|
|
1123
|
+
:param x,y,z: GSM coordinates in Re (1 Re = 6371.2 km)
|
|
1124
|
+
:return: bx,by,bz. Field components in GSM system, in nT.
|
|
1125
|
+
"""
|
|
1126
|
+
|
|
1127
|
+
# common /dtheta/ dtheta
|
|
1128
|
+
# common /modenum/ m
|
|
1129
|
+
global dtheta, m
|
|
1130
|
+
|
|
1131
|
+
# just for numerical differentiation
|
|
1132
|
+
dr = 1e-6
|
|
1133
|
+
dt = 1e-6
|
|
1134
|
+
|
|
1135
|
+
theta0=a[30]
|
|
1136
|
+
|
|
1137
|
+
rho2=x**2+y**2
|
|
1138
|
+
rho=np.sqrt(rho2)
|
|
1139
|
+
r=np.sqrt(rho2+z**2)
|
|
1140
|
+
theta=np.arctan2(rho,z)
|
|
1141
|
+
phi=np.arctan2(y,x)
|
|
1142
|
+
|
|
1143
|
+
# make the deformation of coordinates:
|
|
1144
|
+
rs=r_s(a,r,theta)
|
|
1145
|
+
thetas=theta_s(a,r,theta)
|
|
1146
|
+
phis=phi
|
|
1147
|
+
|
|
1148
|
+
# calculate field components at the new position (asterisked):
|
|
1149
|
+
btast,bfast = fialcos(rs,thetas,phis,m,theta0,dtheta) # mode #m
|
|
1150
|
+
|
|
1151
|
+
# now transform b{r,t,f}_ast by the deformation tensor:
|
|
1152
|
+
# first of all, find the derivatives:
|
|
1153
|
+
drsdr=(r_s(a,r+dr,theta)-r_s(a,r-dr,theta))/(2*dr)
|
|
1154
|
+
drsdt=(r_s(a,r,theta+dt)-r_s(a,r,theta-dt))/(2*dt)
|
|
1155
|
+
dtsdr=(theta_s(a,r+dr,theta)-theta_s(a,r-dr,theta))/(2*dr)
|
|
1156
|
+
dtsdt=(theta_s(a,r,theta+dt)-theta_s(a,r,theta-dt))/(2*dt)
|
|
1157
|
+
|
|
1158
|
+
stsst=np.sin(thetas)/np.sin(theta)
|
|
1159
|
+
rsr=rs/r
|
|
1160
|
+
|
|
1161
|
+
br =-rsr/r*stsst*btast*drsdt # NB#6, p.43 brast does not enter here
|
|
1162
|
+
btheta = rsr*stsst*btast*drsdr # (it is identically zero in our case)
|
|
1163
|
+
bphi = rsr*bfast*(drsdr*dtsdt-drsdt*dtsdr)
|
|
1164
|
+
|
|
1165
|
+
s=rho/r
|
|
1166
|
+
c=z/r
|
|
1167
|
+
sf=y/rho
|
|
1168
|
+
cf=x/rho
|
|
1169
|
+
|
|
1170
|
+
be=br*s+btheta*c
|
|
1171
|
+
|
|
1172
|
+
bx=a[0]*(be*cf-bphi*sf)
|
|
1173
|
+
by=a[0]*(be*sf+bphi*cf)
|
|
1174
|
+
bz=a[0]*(br*c-btheta*s)
|
|
1175
|
+
|
|
1176
|
+
return bx,by,bz
|
|
1177
|
+
|
|
1178
|
+
def r_s(a,r,theta):
|
|
1179
|
+
|
|
1180
|
+
# dimension a(31)
|
|
1181
|
+
return r+a[1]/r+a[2]*r/np.sqrt(r**2+a[10]**2)+a[3]*r/(r**2+a[11]**2) \
|
|
1182
|
+
+(a[4]+a[5]/r+a[6]*r/np.sqrt(r**2+a[12]**2)+a[7]*r/(r**2+a[13]**2))*np.cos(theta) \
|
|
1183
|
+
+(a[8]*r/np.sqrt(r**2+a[14]**2)+a[9]*r/(r**2+a[15]**2)**2)*np.cos(2*theta)
|
|
1184
|
+
|
|
1185
|
+
def theta_s(a,r,theta):
|
|
1186
|
+
# dimension a(31)
|
|
1187
|
+
return theta+(a[16]+a[17]/r+a[18]/r**2+a[19]*r/np.sqrt(r**2+a[26]**2))*np.sin(theta) \
|
|
1188
|
+
+(a[20]+a[21]*r/np.sqrt(r**2+a[27]**2)+a[22]*r/(r**2+a[28]**2))*np.sin(2*theta) \
|
|
1189
|
+
+(a[23]+a[24]/r+a[25]*r/(r**2+a[29]**2))*np.sin(3*theta)
|
|
1190
|
+
|
|
1191
|
+
|
|
1192
|
+
def fialcos(r,theta,phi,n,theta0,dt):
|
|
1193
|
+
"""
|
|
1194
|
+
Conical model of Birkeland current field; based on the old s/r fialco (of 1990-91) NB of 1985-86-88,
|
|
1195
|
+
note of March 5, but here both input and output are in spherical CDS.
|
|
1196
|
+
:param r:
|
|
1197
|
+
:param theta:
|
|
1198
|
+
:param phi:
|
|
1199
|
+
:param n:
|
|
1200
|
+
:param theta0:
|
|
1201
|
+
:param dt:
|
|
1202
|
+
:return: btheta,bphi.
|
|
1203
|
+
"""
|
|
1204
|
+
|
|
1205
|
+
# btn, and bpn are the arrays of btheta and bphi (btn(i), bpn(i) correspond to i-th mode).
|
|
1206
|
+
# only first n mode amplitudes are computed (n<=10).
|
|
1207
|
+
# theta0 is the angular half-width of the cone, dt is the angular h.-w. of the current layer
|
|
1208
|
+
# note: br=0 (because only radial currents are present in this model)
|
|
1209
|
+
|
|
1210
|
+
# dimension btn(10),bpn(10),ccos(10),ssin(10)
|
|
1211
|
+
btn = np.empty(10)
|
|
1212
|
+
bpn = np.empty(10)
|
|
1213
|
+
ccos = np.empty(10)
|
|
1214
|
+
ssin = np.empty(10)
|
|
1215
|
+
|
|
1216
|
+
sinte=np.sin(theta)
|
|
1217
|
+
ro=r*sinte
|
|
1218
|
+
coste=np.cos(theta)
|
|
1219
|
+
sinfi=np.sin(phi)
|
|
1220
|
+
cosfi=np.cos(phi)
|
|
1221
|
+
tg=sinte/(1+coste) # tan(theta/2)
|
|
1222
|
+
ctg=sinte/(1-coste) # cot(theta/2)
|
|
1223
|
+
|
|
1224
|
+
|
|
1225
|
+
tetanp=theta0+dt
|
|
1226
|
+
tetanm=theta0-dt
|
|
1227
|
+
if theta >= tetanm:
|
|
1228
|
+
tgp=np.tan(tetanp*0.5)
|
|
1229
|
+
tgm=np.tan(tetanm*0.5)
|
|
1230
|
+
tgm2=tgm*tgm
|
|
1231
|
+
tgp2=tgp*tgp
|
|
1232
|
+
|
|
1233
|
+
[cosm1, sinm1] = [1.,0]
|
|
1234
|
+
tm = 1
|
|
1235
|
+
[tgm2m,tgp2m] = [1.,1]
|
|
1236
|
+
|
|
1237
|
+
for m in range(1,n+1):
|
|
1238
|
+
tm=tm*tg
|
|
1239
|
+
ccos[m-1]=cosm1*cosfi-sinm1*sinfi
|
|
1240
|
+
ssin[m-1]=sinm1*cosfi+cosm1*sinfi
|
|
1241
|
+
cosm1=ccos[m-1]
|
|
1242
|
+
sinm1=ssin[m-1]
|
|
1243
|
+
if theta < tetanm:
|
|
1244
|
+
t=tm
|
|
1245
|
+
dtt=0.5*m*tm*(tg+ctg)
|
|
1246
|
+
dtt0=0
|
|
1247
|
+
elif theta < tetanp:
|
|
1248
|
+
tgm2m=tgm2m*tgm2
|
|
1249
|
+
fc=1/(tgp-tgm)
|
|
1250
|
+
fc1=1/(2*m+1)
|
|
1251
|
+
tgm2m1=tgm2m*tgm
|
|
1252
|
+
tg21=1+tg*tg
|
|
1253
|
+
t=fc*(tm*(tgp-tg)+fc1*(tm*tg-tgm2m1/tm))
|
|
1254
|
+
dtt=0.5*m*fc*tg21*(tm/tg*(tgp-tg)-fc1*(tm-tgm2m1/(tm*tg)))
|
|
1255
|
+
dtt0=0.5*fc*((tgp+tgm)*(tm*tg-fc1*(tm*tg-tgm2m1/tm))+tm*(1-tgp*tgm)-(1+tgm2)*tgm2m/tm)
|
|
1256
|
+
else:
|
|
1257
|
+
tgp2m=tgp2m*tgp2
|
|
1258
|
+
tgm2m=tgm2m*tgm2
|
|
1259
|
+
fc=1/(tgp-tgm)
|
|
1260
|
+
fc1=1/(2*m+1)
|
|
1261
|
+
t=fc*fc1*(tgp2m*tgp-tgm2m*tgm)/tm
|
|
1262
|
+
dtt=-t*m*0.5*(tg+ctg)
|
|
1263
|
+
|
|
1264
|
+
btn[m-1]=m*t*ccos[m-1]/ro
|
|
1265
|
+
bpn[m-1]=-dtt*ssin[m-1]/r
|
|
1266
|
+
|
|
1267
|
+
btheta=btn[n-1] *800.
|
|
1268
|
+
bphi =bpn[n-1] *800.
|
|
1269
|
+
|
|
1270
|
+
return btheta, bphi
|
|
1271
|
+
|
|
1272
|
+
|
|
1273
|
+
|
|
1274
|
+
|
|
1275
|
+
def birk_shl(a,ps,x_sc, x,y,z):
|
|
1276
|
+
"""
|
|
1277
|
+
B due to the Birkeland current shield.
|
|
1278
|
+
:param a: coefficient.
|
|
1279
|
+
:param ps: geo-dipole tilt angle in radius.
|
|
1280
|
+
:param x_sc:
|
|
1281
|
+
:param x,y,z: GSM coordinates in Re (1 Re = 6371.2 km)
|
|
1282
|
+
:return: bx,by,bz. Field components in GSM system, in nT.
|
|
1283
|
+
"""
|
|
1284
|
+
|
|
1285
|
+
cps=np.cos(ps)
|
|
1286
|
+
sps=np.sin(ps)
|
|
1287
|
+
|
|
1288
|
+
s3ps=2*cps
|
|
1289
|
+
|
|
1290
|
+
pst1=ps*a[84]
|
|
1291
|
+
pst2=ps*a[85]
|
|
1292
|
+
|
|
1293
|
+
st1=np.sin(pst1)
|
|
1294
|
+
ct1=np.cos(pst1)
|
|
1295
|
+
st2=np.sin(pst2)
|
|
1296
|
+
ct2=np.cos(pst2)
|
|
1297
|
+
|
|
1298
|
+
x1=x*ct1-z*st1
|
|
1299
|
+
z1=x*st1+z*ct1
|
|
1300
|
+
x2=x*ct2-z*st2
|
|
1301
|
+
z2=x*st2+z*ct2
|
|
1302
|
+
|
|
1303
|
+
l=0
|
|
1304
|
+
[bx,by,bz] = [0,0,0]
|
|
1305
|
+
|
|
1306
|
+
for m in range(1,3): # m=1 is for the 1st sum ("perp." symmetry) and m=2 is for the second sum ("parall." symmetry)
|
|
1307
|
+
for i in range(1,4):
|
|
1308
|
+
p = a[71 + i]
|
|
1309
|
+
q = a[77 + i]
|
|
1310
|
+
cypi = np.cos(y/p)
|
|
1311
|
+
cyqi = np.cos(y/q)
|
|
1312
|
+
sypi = np.sin(y/p)
|
|
1313
|
+
syqi = np.sin(y/q)
|
|
1314
|
+
|
|
1315
|
+
for k in range(1,4):
|
|
1316
|
+
r=a[74+k]
|
|
1317
|
+
s=a[80+k]
|
|
1318
|
+
szrk=np.sin(z1/r)
|
|
1319
|
+
czsk=np.cos(z2/s)
|
|
1320
|
+
czrk=np.cos(z1/r)
|
|
1321
|
+
szsk=np.sin(z2/s)
|
|
1322
|
+
sqpr=np.sqrt(1/p**2+1/r**2)
|
|
1323
|
+
sqqs=np.sqrt(1/q**2+1/s**2)
|
|
1324
|
+
epr=np.exp(x1*sqpr)
|
|
1325
|
+
eqs=np.exp(x2*sqqs)
|
|
1326
|
+
|
|
1327
|
+
for n in range(1,3): # n=1 is for the first part of each coefficient and n=2 is for the second one
|
|
1328
|
+
for nn in range(1,3): # nn = 1,2 further splits the coefficients into 2 parts, to take into account the scale factor dependence
|
|
1329
|
+
if m == 1:
|
|
1330
|
+
fx = -sqpr*epr*cypi*szrk
|
|
1331
|
+
fy = epr*sypi*szrk/p
|
|
1332
|
+
fz = -epr*cypi*czrk/r
|
|
1333
|
+
if n == 1:
|
|
1334
|
+
if nn == 1:
|
|
1335
|
+
[hx,hy,hz] = [fx,fy,fz]
|
|
1336
|
+
else:
|
|
1337
|
+
[hx,hy,hz] = [fx*x_sc, fy*x_sc, fz*x_sc]
|
|
1338
|
+
else:
|
|
1339
|
+
if nn == 1:
|
|
1340
|
+
[hx,hy,hz] = [fx*cps, fy*cps, fz*cps]
|
|
1341
|
+
else:
|
|
1342
|
+
[hx,hy,hz] = [fx*cps*x_sc, fy*cps*x_sc, fz*cps*x_sc]
|
|
1343
|
+
else: # m == 2
|
|
1344
|
+
fx = -sps*sqqs*eqs*cyqi*czsk
|
|
1345
|
+
fy = sps/q*eqs*syqi*czsk
|
|
1346
|
+
fz = sps/s*eqs*cyqi*szsk
|
|
1347
|
+
if n == 1:
|
|
1348
|
+
if nn == 1:
|
|
1349
|
+
[hx,hy,hz] = [fx,fy,fz]
|
|
1350
|
+
else:
|
|
1351
|
+
[hx,hy,hz] = [fx*x_sc, fy*x_sc, fz*x_sc]
|
|
1352
|
+
else:
|
|
1353
|
+
if nn == 1:
|
|
1354
|
+
[hx,hy,hz] = [fx*s3ps,fy*s3ps,fz*s3ps]
|
|
1355
|
+
else:
|
|
1356
|
+
[hx,hy,hz] = [fx*s3ps*x_sc, fy*s3ps*x_sc, fz*s3ps*x_sc]
|
|
1357
|
+
l=l+1
|
|
1358
|
+
if m == 1:
|
|
1359
|
+
hxr = hx*ct1+hz*st1
|
|
1360
|
+
hzr = -hx*st1+hz*ct1
|
|
1361
|
+
else:
|
|
1362
|
+
hxr = hx*ct2+hz*st2
|
|
1363
|
+
hzr = -hx*st2+hz*ct2
|
|
1364
|
+
|
|
1365
|
+
bx = bx+hxr*a[l-1]
|
|
1366
|
+
by = by+hy *a[l-1]
|
|
1367
|
+
bz = bz+hzr*a[l-1]
|
|
1368
|
+
|
|
1369
|
+
return bx,by,bz
|
|
1370
|
+
|
|
1371
|
+
|
|
1372
|
+
|
|
1373
|
+
def full_rc(iopr,ps,x,y,z):
|
|
1374
|
+
"""
|
|
1375
|
+
Calculates GSM field components of the symmetric (src) and partial (prc) components of the ring current
|
|
1376
|
+
:param iopr: a ring current calculation flag (for least-squares fitting only):
|
|
1377
|
+
iopr=0 - both src and prc fields are calculated; opr=1 - src only; opr=2 - prc only
|
|
1378
|
+
:param ps: geo-dipole tilt angle in radius.
|
|
1379
|
+
:param x,y,z: GSM coordinates in Re (1 Re = 6371.2 km)
|
|
1380
|
+
:return:
|
|
1381
|
+
"""
|
|
1382
|
+
|
|
1383
|
+
# src provides a depression of -28 nt at earth
|
|
1384
|
+
# prc corresponds to the pressure difference of 2 npa between midnight and noon ring current particle pressure and yields a depression of -17 nt at x=-6re
|
|
1385
|
+
|
|
1386
|
+
# sc_sy and sc_pr are scaling factors for the symmetric and partial components: values larger than 1 result in spatially larger currents
|
|
1387
|
+
# phi is the rotation angle in radians of the partial ring current (measured from midnight toward dusk)
|
|
1388
|
+
# common /rcpar/ sc_sy,sc_pr,phi
|
|
1389
|
+
global sc_sy, sc_pr, phi
|
|
1390
|
+
|
|
1391
|
+
|
|
1392
|
+
# corrected values(as of may 2006)
|
|
1393
|
+
|
|
1394
|
+
c_sy = np.array([ # sy short for symmetric
|
|
1395
|
+
-957.2534900,-817.5450246,583.2991249,758.8568270,
|
|
1396
|
+
13.17029064,68.94173502,-15.29764089,-53.43151590,27.34311724,
|
|
1397
|
+
149.5252826,-11.00696044,-179.7031814,953.0914774,817.2340042,
|
|
1398
|
+
-581.0791366,-757.5387665,-13.10602697,-68.58155678,15.22447386,
|
|
1399
|
+
53.15535633,-27.07982637,-149.1413391,10.91433279,179.3251739,
|
|
1400
|
+
-6.028703251,1.303196101,-1.345909343,-1.138296330,-0.06642634348,
|
|
1401
|
+
-0.3795246458,.07487833559,.2891156371,-.5506314391,-.4443105812,
|
|
1402
|
+
0.2273682152,0.01086886655,-9.130025352,1.118684840,1.110838825,
|
|
1403
|
+
.1219761512,-.06263009645,-.1896093743,.03434321042,.01523060688,
|
|
1404
|
+
-.4913171541,-.2264814165,-.04791374574,.1981955976,-68.32678140,
|
|
1405
|
+
-48.72036263,14.03247808,16.56233733,2.369921099,6.200577111,
|
|
1406
|
+
-1.415841250,-0.8184867835,-3.401307527,-8.490692287,3.217860767,
|
|
1407
|
+
-9.037752107,66.09298105,48.23198578,-13.67277141,-16.27028909,
|
|
1408
|
+
-2.309299411,-6.016572391,1.381468849,0.7935312553,3.436934845,
|
|
1409
|
+
8.260038635,-3.136213782,8.833214943,8.041075485,8.024818618,
|
|
1410
|
+
35.54861873,12.55415215,1.738167799,3.721685353,23.06768025,
|
|
1411
|
+
6.871230562,6.806229878,21.35990364,1.687412298,3.500885177,
|
|
1412
|
+
0.3498952546,0.6595919814 ])
|
|
1413
|
+
|
|
1414
|
+
|
|
1415
|
+
c_pr = np.array([ # pr short for partial
|
|
1416
|
+
-64820.58481, -63965.62048, 66267.93413, 135049.7504, -36.56316878,
|
|
1417
|
+
124.6614669, 56.75637955, -87.56841077, 5848.631425, 4981.097722,
|
|
1418
|
+
-6233.712207, -10986.40188, 68716.52057, 65682.69473, -69673.32198,
|
|
1419
|
+
-138829.3568, 43.45817708, -117.9565488, -62.14836263, 79.83651604,
|
|
1420
|
+
-6211.451069, -5151.633113, 6544.481271, 11353.03491, 23.72352603,
|
|
1421
|
+
-256.4846331, 25.77629189, 145.2377187, -4.472639098, -3.554312754,
|
|
1422
|
+
2.936973114, 2.682302576, 2.728979958, 26.43396781, -9.312348296,
|
|
1423
|
+
-29.65427726, -247.5855336, -206.9111326, 74.25277664, 106.4069993,
|
|
1424
|
+
15.45391072, 16.35943569, -5.965177750, -6.079451700, 115.6748385,
|
|
1425
|
+
-35.27377307, -32.28763497, -32.53122151, 93.74409310, 84.25677504,
|
|
1426
|
+
-29.23010465, -43.79485175, -6.434679514, -6.620247951, 2.443524317,
|
|
1427
|
+
2.266538956, -43.82903825, 6.904117876, 12.24289401, 17.62014361,
|
|
1428
|
+
152.3078796, 124.5505289, -44.58690290, -63.02382410, -8.999368955,
|
|
1429
|
+
-9.693774119, 3.510930306, 3.770949738, -77.96705716, 22.07730961,
|
|
1430
|
+
20.46491655, 18.67728847, 9.451290614, 9.313661792, 644.7620970,
|
|
1431
|
+
418.2515954, 7.183754387, 35.62128817, 19.43180682, 39.57218411,
|
|
1432
|
+
15.69384715, 7.123215241, 2.300635346, 21.90881131, -.01775839370, .3996346710])
|
|
1433
|
+
|
|
1434
|
+
|
|
1435
|
+
hxsrc,hysrc,hzsrc, hxprc,hyprc,hzprc = src_prc(iopr, sc_sy,sc_pr, phi, ps, x,y,z)
|
|
1436
|
+
|
|
1437
|
+
x_sc=sc_sy-1
|
|
1438
|
+
fsx,fsy,fsz = [0.]*3
|
|
1439
|
+
if (iopr == 0) | (iopr == 1):
|
|
1440
|
+
fsx,fsy,fsz = rc_shield(c_sy,ps,x_sc, x,y,z)
|
|
1441
|
+
|
|
1442
|
+
x_sc=sc_pr-1
|
|
1443
|
+
fpx,fpy,fpz = [0.]*3
|
|
1444
|
+
if (iopr == 0) | (iopr == 2):
|
|
1445
|
+
fpx,fpy,fpz = rc_shield(c_pr,ps,x_sc, x,y,z)
|
|
1446
|
+
|
|
1447
|
+
bxsrc=hxsrc+fsx
|
|
1448
|
+
bysrc=hysrc+fsy
|
|
1449
|
+
bzsrc=hzsrc+fsz
|
|
1450
|
+
|
|
1451
|
+
bxprc=hxprc+fpx
|
|
1452
|
+
byprc=hyprc+fpy
|
|
1453
|
+
bzprc=hzprc+fpz
|
|
1454
|
+
|
|
1455
|
+
return bxsrc,bysrc,bzsrc,bxprc,byprc,bzprc
|
|
1456
|
+
|
|
1457
|
+
|
|
1458
|
+
|
|
1459
|
+
def src_prc(iopr,sc_sy,sc_pr,phi,ps, x,y,z):
|
|
1460
|
+
"""
|
|
1461
|
+
Returns field components from a model ring current, including its symmetric part and a partial ring current,
|
|
1462
|
+
closed via birkeland currents. based on results, described in a paper "modeling the inner magnetosphere:
|
|
1463
|
+
asymmetric ring current and region 2 birkeland currents revisited" (jgr, dec.2000).
|
|
1464
|
+
:param iopr: a ring current calculation flag (for least-squares fitting only):
|
|
1465
|
+
iopr=0 - both src and prc fields are calculated; opr=1 - src only; opr=2 - prc only
|
|
1466
|
+
:param sc_sy, sc_pr: scale factors for the above components; taking sc<1 or sc>1 makes the currents shrink or expand, respectively.
|
|
1467
|
+
:param phi: the rotation angle (radians) of the partial ring current (measured from midnight toward dusk)
|
|
1468
|
+
:param ps: geo-dipole tilt angle in radius.
|
|
1469
|
+
:param x,y,z: GSM coordinates in Re (1 Re = 6371.2 km)
|
|
1470
|
+
:return: bxsrc,bysrc,bzsrc, bxprc,byprc,bzprc. Field components in GSM system, in nT. For the symmetric part and partial ring current.
|
|
1471
|
+
"""
|
|
1472
|
+
|
|
1473
|
+
# 1. transform to tilted coordinates (i.e., sm coordinates):
|
|
1474
|
+
cps=np.cos(ps)
|
|
1475
|
+
sps=np.sin(ps)
|
|
1476
|
+
|
|
1477
|
+
xt=x*cps-z*sps
|
|
1478
|
+
zt=z*cps+x*sps
|
|
1479
|
+
|
|
1480
|
+
# 2. scale the coordinates for the symmetric and partial rc components:
|
|
1481
|
+
xts=xt/sc_sy # symmetric
|
|
1482
|
+
yts=y /sc_sy
|
|
1483
|
+
zts=zt/sc_sy
|
|
1484
|
+
|
|
1485
|
+
xta=xt/sc_pr # partial
|
|
1486
|
+
yta=y /sc_pr
|
|
1487
|
+
zta=zt/sc_pr
|
|
1488
|
+
|
|
1489
|
+
# 3. calculate components of the total field in the tilted (solar-magnetic) coordinate system:
|
|
1490
|
+
|
|
1491
|
+
# only for least squares fitting:
|
|
1492
|
+
bxs,bys,bzs = [0.]*3
|
|
1493
|
+
bxa_s,bya_s,bza_s = [0.]*3
|
|
1494
|
+
bxa_qr,bya_qr,bza_q = [0.]*3
|
|
1495
|
+
|
|
1496
|
+
# 3a. symmetric field:
|
|
1497
|
+
if iopr <= 1:
|
|
1498
|
+
bxs,bys,bzs = rc_symm(xts,yts,zts)
|
|
1499
|
+
if (iopr == 0) | (iopr == 2):
|
|
1500
|
+
bxa_s,bya_s,bza_s = prc_symm(xta,yta,zta)
|
|
1501
|
+
|
|
1502
|
+
# 3b. rotate the scaled sm coordinates by phi around zsm axis and calculate quadrupole prc field in those coords:
|
|
1503
|
+
cp=np.cos(phi)
|
|
1504
|
+
sp=np.sin(phi)
|
|
1505
|
+
xr=xta*cp-yta*sp
|
|
1506
|
+
yr=xta*sp+yta*cp
|
|
1507
|
+
if (iopr == 0) | (iopr == 2):
|
|
1508
|
+
bxa_qr,bya_qr,bza_q = prc_quad(xr,yr,zta)
|
|
1509
|
+
|
|
1510
|
+
# 3c.transform the quadrupole field components back to the sm coords:
|
|
1511
|
+
bxa_q= bxa_qr*cp+bya_qr*sp
|
|
1512
|
+
bya_q=-bxa_qr*sp+bya_qr*cp
|
|
1513
|
+
|
|
1514
|
+
# 3d. find the total field of prc (symm.+quadr.) in the sm coords:
|
|
1515
|
+
bxp=bxa_s+bxa_q
|
|
1516
|
+
byp=bya_s+bya_q
|
|
1517
|
+
bzp=bza_s+bza_q
|
|
1518
|
+
|
|
1519
|
+
# 4. transform the fields of both parts of the ring current back to the gsm system:
|
|
1520
|
+
bxsrc=bxs*cps+bzs*sps # symmetric rc
|
|
1521
|
+
bysrc=bys
|
|
1522
|
+
bzsrc=bzs*cps-bxs*sps
|
|
1523
|
+
|
|
1524
|
+
bxprc=bxp*cps+bzp*sps # partial rc
|
|
1525
|
+
byprc=byp
|
|
1526
|
+
bzprc=bzp*cps-bxp*sps
|
|
1527
|
+
|
|
1528
|
+
return bxsrc,bysrc,bzsrc, bxprc,byprc,bzprc
|
|
1529
|
+
|
|
1530
|
+
|
|
1531
|
+
def rc_symm(x,y,z):
|
|
1532
|
+
"""
|
|
1533
|
+
Calculates the field components from a model ring current, due to its symmetric part.
|
|
1534
|
+
:param x,y,z: GSM coordinates in Re (1 Re = 6371.2 km)
|
|
1535
|
+
:return: bx,by,bz. Field components in GSM system, in nT.
|
|
1536
|
+
"""
|
|
1537
|
+
|
|
1538
|
+
# ds=sin(theta) at the boundary of the linearity region; dc=sqrt(1-ds**2); drd=1/(2*d)
|
|
1539
|
+
ds = 1e-2
|
|
1540
|
+
dc = 0.99994999875
|
|
1541
|
+
d = 1e-4
|
|
1542
|
+
drd = 5e3
|
|
1543
|
+
|
|
1544
|
+
rho2=x**2+y**2
|
|
1545
|
+
r2=rho2+z**2
|
|
1546
|
+
r=np.sqrt(r2)
|
|
1547
|
+
rp=r+d
|
|
1548
|
+
rm=r-d
|
|
1549
|
+
sint=np.sqrt(rho2)/r
|
|
1550
|
+
cost=z/r
|
|
1551
|
+
|
|
1552
|
+
# too close to the z-axis; using a linear approximation a_phi~sint to avoid the singularity problem
|
|
1553
|
+
if sint < ds:
|
|
1554
|
+
a=ap(r,ds,dc)/ds
|
|
1555
|
+
dardr=(rp*ap(rp,ds,dc)-rm*ap(rm,ds,dc))*drd
|
|
1556
|
+
fxy=z*(2*a-dardr)/(r*r2)
|
|
1557
|
+
bx=fxy*x
|
|
1558
|
+
by=fxy*y
|
|
1559
|
+
bz=(2*a*cost**2+dardr*sint**2)/r
|
|
1560
|
+
else:
|
|
1561
|
+
theta=np.arctan2(sint,cost)
|
|
1562
|
+
tp=theta+d
|
|
1563
|
+
tm=theta-d
|
|
1564
|
+
sintp=np.sin(tp)
|
|
1565
|
+
sintm=np.sin(tm)
|
|
1566
|
+
costp=np.cos(tp)
|
|
1567
|
+
costm=np.cos(tm)
|
|
1568
|
+
br=(sintp*ap(r,sintp,costp)-sintm*ap(r,sintm,costm))/(r*sint)*drd
|
|
1569
|
+
bt=(rm*ap(rm,sint,cost)-rp*ap(rp,sint,cost))/r*drd
|
|
1570
|
+
fxy=(br+bt*cost/sint)/r
|
|
1571
|
+
bx=fxy*x
|
|
1572
|
+
by=fxy*y
|
|
1573
|
+
bz=br*cost-bt*sint
|
|
1574
|
+
|
|
1575
|
+
return bx, by, bz
|
|
1576
|
+
|
|
1577
|
+
def ap(r,sint,cost):
|
|
1578
|
+
"""
|
|
1579
|
+
Calculates azimuthal component of the vector potential of the symmetric part of the model ring current.
|
|
1580
|
+
:param r:
|
|
1581
|
+
:param sint:
|
|
1582
|
+
:param cost:
|
|
1583
|
+
:return:
|
|
1584
|
+
"""
|
|
1585
|
+
|
|
1586
|
+
# Updated 04/20/06 (nb#9, p.37)
|
|
1587
|
+
a1,a2,rrc1,dd1,rrc2,dd2,p1,r1,dr1,dla1,p2,r2,dr2,dla2,p3,r3,dr3 = [
|
|
1588
|
+
-456.5289941,375.9055332,4.274684950,2.439528329,3.367557287,
|
|
1589
|
+
3.146382545,-0.2291904607,3.746064740,1.508802177,0.5873525737,
|
|
1590
|
+
0.1556236119,4.993638842,3.324180497,0.4368407663,0.1855957207,
|
|
1591
|
+
2.969226745,2.243367377]
|
|
1592
|
+
|
|
1593
|
+
|
|
1594
|
+
# indicates whether we are too close to the axis of symmetry, where the inversion of dipolar coordinates becomes inaccurate
|
|
1595
|
+
prox = False
|
|
1596
|
+
sint1=sint
|
|
1597
|
+
cost1=cost
|
|
1598
|
+
# too close to z-axis; use linear interpolation between sint=0 & sint=0.01
|
|
1599
|
+
if (sint1 < 1.e-2):
|
|
1600
|
+
sint1=1.e-2
|
|
1601
|
+
cost1=0.99994999875
|
|
1602
|
+
prox=True
|
|
1603
|
+
|
|
1604
|
+
alpha=sint1**2/r # r,theta -> alpha,gamma
|
|
1605
|
+
gamma=cost1/r**2
|
|
1606
|
+
|
|
1607
|
+
arg1=-((r-r1)/dr1)**2-(cost1/dla1)**2
|
|
1608
|
+
arg2=-((r-r2)/dr2)**2-(cost1/dla2)**2
|
|
1609
|
+
arg3=-((r-r3)/dr3)**2
|
|
1610
|
+
|
|
1611
|
+
if arg1 < -500: # to prevent "floating underflow" crashes
|
|
1612
|
+
dexp1=0.
|
|
1613
|
+
else:
|
|
1614
|
+
dexp1=np.exp(arg1)
|
|
1615
|
+
|
|
1616
|
+
if arg2 < -500: # to prevent "floating underflow" crashes
|
|
1617
|
+
dexp2=0.
|
|
1618
|
+
else:
|
|
1619
|
+
dexp2=np.exp(arg2)
|
|
1620
|
+
|
|
1621
|
+
if arg3 < -500: # to prevent "floating underflow" crashes
|
|
1622
|
+
dexp3=0.
|
|
1623
|
+
else:
|
|
1624
|
+
dexp3=np.exp(arg3)
|
|
1625
|
+
|
|
1626
|
+
# alpha -> alpha_s (deformed)
|
|
1627
|
+
alpha_s=alpha*(1+p1*dexp1+p2*dexp2+p3*dexp3)
|
|
1628
|
+
gamma_s=gamma
|
|
1629
|
+
gammas2=gamma_s**2
|
|
1630
|
+
|
|
1631
|
+
# alpha_s,gamma_s -> rs,sints,costs
|
|
1632
|
+
alsqh=alpha_s**2/2
|
|
1633
|
+
f=64/27*gammas2+alsqh**2
|
|
1634
|
+
q=(np.sqrt(f)+alsqh)**(1/3)
|
|
1635
|
+
c=q-4*gammas2**(1/3)/(3*q)
|
|
1636
|
+
if c < 0: c=0
|
|
1637
|
+
g=np.sqrt(c**2+4*gammas2**(1/3))
|
|
1638
|
+
rs=4/((np.sqrt(2*g-c)+np.sqrt(c))*(g+c))
|
|
1639
|
+
costs=gamma_s*rs**2
|
|
1640
|
+
sints=np.sqrt(1-costs**2)
|
|
1641
|
+
rhos=rs*sints
|
|
1642
|
+
rhos2=rhos**2
|
|
1643
|
+
zs=rs*costs
|
|
1644
|
+
|
|
1645
|
+
# TODO looks like this part is repetative.
|
|
1646
|
+
p=(rrc1+rhos)**2+zs**2+dd1**2
|
|
1647
|
+
xk2=4*rrc1*rhos/p
|
|
1648
|
+
xk=np.sqrt(xk2)
|
|
1649
|
+
xkrho12=xk*np.sqrt(rhos) # see nb#4, p.3
|
|
1650
|
+
|
|
1651
|
+
xk2s = 1-xk2
|
|
1652
|
+
dl = np.log(1/xk2s)
|
|
1653
|
+
elk = 1.38629436112 + xk2s*(0.09666344259+xk2s*(0.03590092383+xk2s*(0.03742563713+xk2s*0.01451196212))) \
|
|
1654
|
+
+ dl*(0.5+xk2s*(0.12498593597+xk2s*(0.06880248576+xk2s*(0.03328355346+xk2s*0.00441787012))))
|
|
1655
|
+
ele = 1+xk2s*(0.44325141463+xk2s*(0.0626060122+xk2s*(0.04757383546+xk2s*0.01736506451))) \
|
|
1656
|
+
+ dl*xk2s*(0.2499836831+xk2s*(0.09200180037+xk2s*(0.04069697526+xk2s*0.00526449639)))
|
|
1657
|
+
aphi1=((1-xk2*0.5)*elk-ele)/xkrho12
|
|
1658
|
+
|
|
1659
|
+
|
|
1660
|
+
p=(rrc2+rhos)**2+zs**2+dd2**2
|
|
1661
|
+
xk2=4*rrc2*rhos/p
|
|
1662
|
+
xk=np.sqrt(xk2)
|
|
1663
|
+
xkrho12=xk*np.sqrt(rhos) # see nb#4, p.3
|
|
1664
|
+
|
|
1665
|
+
xk2s = 1-xk2
|
|
1666
|
+
dl = np.log(1/xk2s)
|
|
1667
|
+
elk = 1.38629436112 + xk2s*(0.09666344259+xk2s*(0.03590092383+xk2s*(0.03742563713+xk2s*0.01451196212))) \
|
|
1668
|
+
+ dl*(0.5+xk2s*(0.12498593597+xk2s*(0.06880248576+xk2s*(0.03328355346+xk2s*0.00441787012))))
|
|
1669
|
+
ele = 1+xk2s*(0.44325141463+xk2s*(0.0626060122+xk2s*(0.04757383546+xk2s*0.01736506451))) \
|
|
1670
|
+
+ dl*xk2s*(0.2499836831+xk2s*(0.09200180037+xk2s*(0.04069697526+xk2s*0.00526449639)))
|
|
1671
|
+
aphi2=((1-xk2*0.5)*elk-ele)/xkrho12
|
|
1672
|
+
|
|
1673
|
+
ap=a1*aphi1+a2*aphi2
|
|
1674
|
+
if prox:
|
|
1675
|
+
ap=ap*sint/sint1 # linear interpolation, if too close to the z-axis
|
|
1676
|
+
|
|
1677
|
+
return ap
|
|
1678
|
+
|
|
1679
|
+
|
|
1680
|
+
def prc_symm(x,y,z):
|
|
1681
|
+
"""
|
|
1682
|
+
Calculates the field components from a model ring current, due to a partial ring current.
|
|
1683
|
+
:param x,y,z: GSM coordinates in Re (1 Re = 6371.2 km)
|
|
1684
|
+
:return: bx,by,bz. Field components in GSM system, in nT.
|
|
1685
|
+
"""
|
|
1686
|
+
|
|
1687
|
+
# ds=sin(theta) at the boundary of the linearity region; dc=sqrt(1-ds**2); drd=1/(2*d)
|
|
1688
|
+
ds = 1e-2
|
|
1689
|
+
dc = 0.99994999875
|
|
1690
|
+
d = 1e-4
|
|
1691
|
+
drd = 5e3
|
|
1692
|
+
|
|
1693
|
+
rho2=x**2+y**2
|
|
1694
|
+
r2=rho2+z**2
|
|
1695
|
+
r=np.sqrt(r2)
|
|
1696
|
+
rp=r+d
|
|
1697
|
+
rm=r-d
|
|
1698
|
+
sint=np.sqrt(rho2)/r
|
|
1699
|
+
cost=z/r
|
|
1700
|
+
|
|
1701
|
+
# too close to the z-axis; using a linear approximation a_phi~sint to avoid the singularity problem
|
|
1702
|
+
if sint < ds:
|
|
1703
|
+
a=apprc(r,ds,dc)/ds
|
|
1704
|
+
dardr=(rp*apprc(rp,ds,dc)-rm*apprc(rm,ds,dc))*drd
|
|
1705
|
+
fxy=z*(2*a-dardr)/(r*r2)
|
|
1706
|
+
bx=fxy*x
|
|
1707
|
+
by=fxy*y
|
|
1708
|
+
bz=(2*a*cost**2+dardr*sint**2)/r
|
|
1709
|
+
else:
|
|
1710
|
+
theta=np.arctan2(sint,cost)
|
|
1711
|
+
tp=theta+d
|
|
1712
|
+
tm=theta-d
|
|
1713
|
+
sintp=np.sin(tp)
|
|
1714
|
+
sintm=np.sin(tm)
|
|
1715
|
+
costp=np.cos(tp)
|
|
1716
|
+
costm=np.cos(tm)
|
|
1717
|
+
br=(sintp*apprc(r,sintp,costp)-sintm*apprc(r,sintm,costm))/(r*sint)*drd
|
|
1718
|
+
bt=(rm*apprc(rm,sint,cost)-rp*apprc(rp,sint,cost))/r*drd
|
|
1719
|
+
fxy=(br+bt*cost/sint)/r
|
|
1720
|
+
bx=fxy*x
|
|
1721
|
+
by=fxy*y
|
|
1722
|
+
bz=br*cost-bt*sint
|
|
1723
|
+
|
|
1724
|
+
return bx, by, bz
|
|
1725
|
+
|
|
1726
|
+
def apprc(r,sint,cost):
|
|
1727
|
+
"""
|
|
1728
|
+
Calculates azimuthal component of the vector potential of the symmetric part of the model partial ring current.
|
|
1729
|
+
:param r:
|
|
1730
|
+
:param sint:
|
|
1731
|
+
:param cost:
|
|
1732
|
+
:return:
|
|
1733
|
+
"""
|
|
1734
|
+
|
|
1735
|
+
a1,a2,rrc1,dd1,rrc2,dd2,p1,alpha1,dal1,beta1,dg1,p2,alpha2,dal2,beta2,dg2,beta3,p3, \
|
|
1736
|
+
alpha3,dal3,beta4,dg3,beta5,q0,q1,alpha4,dal4,dg4,q2,alpha5,dal5,dg5,beta6,beta7 = [
|
|
1737
|
+
-80.11202281,12.58246758,6.560486035,1.930711037,3.827208119,
|
|
1738
|
+
.7789990504,.3058309043,.1817139853,.1257532909,3.422509402,
|
|
1739
|
+
.04742939676,-4.800458958,-.02845643596,.2188114228,2.545944574,
|
|
1740
|
+
.00813272793,.35868244,103.1601001,-.00764731187,.1046487459,
|
|
1741
|
+
2.958863546,.01172314188,.4382872938,.01134908150,14.51339943,
|
|
1742
|
+
.2647095287,.07091230197,.01512963586,6.861329631,.1677400816,
|
|
1743
|
+
.04433648846,.05553741389,.7665599464,.7277854652]
|
|
1744
|
+
|
|
1745
|
+
prox=False
|
|
1746
|
+
sint1=sint
|
|
1747
|
+
cost1=cost
|
|
1748
|
+
# too close to z-axis; use linear interpolation between sint=0 & sint=0.01
|
|
1749
|
+
if (sint1 < 1.e-2):
|
|
1750
|
+
sint1=1.e-2
|
|
1751
|
+
cost1=0.99994999875
|
|
1752
|
+
prox=True
|
|
1753
|
+
|
|
1754
|
+
alpha=sint1**2/r # r,theta -> alpha,gamma
|
|
1755
|
+
gamma=cost1/r**2
|
|
1756
|
+
|
|
1757
|
+
arg1=-(gamma/dg1)**2
|
|
1758
|
+
arg2=-((alpha-alpha4)/dal4)**2-(gamma/dg4)**2
|
|
1759
|
+
|
|
1760
|
+
if arg1 < -500: # to prevent "floating underflow" crashes
|
|
1761
|
+
dexp1=0.
|
|
1762
|
+
else:
|
|
1763
|
+
dexp1=np.exp(arg1)
|
|
1764
|
+
|
|
1765
|
+
if arg2 < -500: # to prevent "floating underflow" crashes
|
|
1766
|
+
dexp2=0.
|
|
1767
|
+
else:
|
|
1768
|
+
dexp2=np.exp(arg2)
|
|
1769
|
+
|
|
1770
|
+
# alpha -> alpha_s (deformed)
|
|
1771
|
+
alpha_s = alpha*(1 + p1/(1+((alpha-alpha1)/dal1)**2)**beta1*dexp1
|
|
1772
|
+
+ p2*(alpha-alpha2)/(1+((alpha-alpha2)/dal2)**2)**beta2/(1+(gamma/dg2)**2)**beta3
|
|
1773
|
+
+ p3*(alpha-alpha3)**2/(1.+((alpha-alpha3)/dal3)**2)**beta4/(1+(gamma/dg3)**2)**beta5)
|
|
1774
|
+
# gamma -> gamma_s (deformed)
|
|
1775
|
+
gamma_s = gamma*(1 + q0 + q1*(alpha-alpha4)*dexp2
|
|
1776
|
+
+ q2*(alpha-alpha5)/(1+((alpha-alpha5)/dal5)**2)**beta6/(1+(gamma/dg5)**2)**beta7)
|
|
1777
|
+
|
|
1778
|
+
gammas2 = gamma_s**2
|
|
1779
|
+
|
|
1780
|
+
# alpha_s,gamma_s -> rs,sints,costs
|
|
1781
|
+
alsqh=alpha_s**2/2.
|
|
1782
|
+
f=64./27.*gammas2+alsqh**2
|
|
1783
|
+
q=(np.sqrt(f)+alsqh)**(1/3)
|
|
1784
|
+
c=q-4.*gammas2**(1/3)/(3.*q)
|
|
1785
|
+
if c < 0: c=0
|
|
1786
|
+
g=np.sqrt(c**2+4*gammas2**(1/3))
|
|
1787
|
+
rs=4./((np.sqrt(2*g-c)+np.sqrt(c))*(g+c))
|
|
1788
|
+
costs=gamma_s*rs**2
|
|
1789
|
+
sints=np.sqrt(1-costs**2)
|
|
1790
|
+
rhos=rs*sints
|
|
1791
|
+
rhos2=rhos**2
|
|
1792
|
+
zs=rs*costs
|
|
1793
|
+
|
|
1794
|
+
|
|
1795
|
+
# TODO looks like this part is repetative.
|
|
1796
|
+
p=(rrc1+rhos)**2+zs**2+dd1**2
|
|
1797
|
+
xk2=4*rrc1*rhos/p
|
|
1798
|
+
xk=np.sqrt(xk2)
|
|
1799
|
+
xkrho12=xk*np.sqrt(rhos) # see nb#4, p.3
|
|
1800
|
+
|
|
1801
|
+
xk2s = 1-xk2
|
|
1802
|
+
dl = np.log(1/xk2s)
|
|
1803
|
+
elk = 1.38629436112 + xk2s*(0.09666344259+xk2s*(0.03590092383+xk2s*(0.03742563713+xk2s*0.01451196212))) \
|
|
1804
|
+
+ dl*(0.5+xk2s*(0.12498593597+xk2s*(0.06880248576+xk2s*(0.03328355346+xk2s*0.00441787012))))
|
|
1805
|
+
ele = 1 + xk2s*(0.44325141463+xk2s*(0.0626060122+xk2s*(0.04757383546+xk2s*0.01736506451))) \
|
|
1806
|
+
+ dl*xk2s*(0.2499836831+xk2s*(0.09200180037+xk2s*(0.04069697526+xk2s*0.00526449639)))
|
|
1807
|
+
aphi1=((1-xk2*0.5)*elk-ele)/xkrho12
|
|
1808
|
+
|
|
1809
|
+
|
|
1810
|
+
p=(rrc2+rhos)**2+zs**2+dd2**2
|
|
1811
|
+
xk2=4*rrc2*rhos/p
|
|
1812
|
+
xk=np.sqrt(xk2)
|
|
1813
|
+
xkrho12=xk*np.sqrt(rhos) # see nb#4, p.3
|
|
1814
|
+
|
|
1815
|
+
xk2s = 1-xk2
|
|
1816
|
+
dl = np.log(1/xk2s)
|
|
1817
|
+
elk = 1.38629436112 + xk2s*(0.09666344259+xk2s*(0.03590092383+xk2s*(0.03742563713+xk2s*0.01451196212))) \
|
|
1818
|
+
+ dl*(0.5+xk2s*(0.12498593597+xk2s*(0.06880248576+xk2s*(0.03328355346+xk2s*0.00441787012))))
|
|
1819
|
+
ele = 1 + xk2s*(0.44325141463+xk2s*(0.0626060122+xk2s*(0.04757383546+xk2s*0.01736506451))) \
|
|
1820
|
+
+ dl*xk2s*(0.2499836831+xk2s*(0.09200180037+xk2s*(0.04069697526+xk2s*0.00526449639)))
|
|
1821
|
+
aphi2=((1-xk2*0.5)*elk-ele)/xkrho12
|
|
1822
|
+
|
|
1823
|
+
apprc=a1*aphi1+a2*aphi2
|
|
1824
|
+
if prox:
|
|
1825
|
+
apprc=apprc*sint/sint1 # linear interpolation, if too close to the z-axis
|
|
1826
|
+
|
|
1827
|
+
return apprc
|
|
1828
|
+
|
|
1829
|
+
|
|
1830
|
+
def prc_quad(x,y,z):
|
|
1831
|
+
"""
|
|
1832
|
+
Calculates components of the field from the "quadrupole" component of the partial ring current.
|
|
1833
|
+
:param x,y,z: GSM coordinates in Re (1 Re = 6371.2 km)
|
|
1834
|
+
:return: bx,by,bz. Field components in GSM system, in nT.
|
|
1835
|
+
"""
|
|
1836
|
+
d = 1e-4
|
|
1837
|
+
dd = 2e-4
|
|
1838
|
+
ds = 1e-2
|
|
1839
|
+
dc = 0.99994999875
|
|
1840
|
+
|
|
1841
|
+
rho2=x**2+y**2
|
|
1842
|
+
r=np.sqrt(rho2+z**2)
|
|
1843
|
+
rho=np.sqrt(rho2)
|
|
1844
|
+
sint=rho/r
|
|
1845
|
+
cost=z/r
|
|
1846
|
+
rp=r+d
|
|
1847
|
+
rm=r-d
|
|
1848
|
+
|
|
1849
|
+
if sint > ds:
|
|
1850
|
+
cphi=x/rho
|
|
1851
|
+
sphi=y/rho
|
|
1852
|
+
br=br_prc_q(r,sint,cost)
|
|
1853
|
+
bt=bt_prc_q(r,sint,cost)
|
|
1854
|
+
dbrr=(br_prc_q(rp,sint,cost)-br_prc_q(rm,sint,cost))/dd
|
|
1855
|
+
theta=np.arctan2(sint,cost)
|
|
1856
|
+
tp=theta+d
|
|
1857
|
+
tm=theta-d
|
|
1858
|
+
sintp=np.sin(tp)
|
|
1859
|
+
costp=np.cos(tp)
|
|
1860
|
+
sintm=np.sin(tm)
|
|
1861
|
+
costm=np.cos(tm)
|
|
1862
|
+
dbtt=(bt_prc_q(r,sintp,costp)-bt_prc_q(r,sintm,costm))/dd
|
|
1863
|
+
bx=sint*(br+(br+r*dbrr+dbtt)*sphi**2)+cost*bt
|
|
1864
|
+
by=-sint*sphi*cphi*(br+r*dbrr+dbtt)
|
|
1865
|
+
bz=(br*cost-bt*sint)*cphi
|
|
1866
|
+
else:
|
|
1867
|
+
st=ds
|
|
1868
|
+
ct=dc
|
|
1869
|
+
if z < 0: ct=-dc
|
|
1870
|
+
theta=np.arctan2(st,ct)
|
|
1871
|
+
tp=theta+d
|
|
1872
|
+
tm=theta-d
|
|
1873
|
+
sintp=np.sin(tp)
|
|
1874
|
+
costp=np.cos(tp)
|
|
1875
|
+
sintm=np.sin(tm)
|
|
1876
|
+
costm=np.cos(tm)
|
|
1877
|
+
br=br_prc_q(r,st,ct)
|
|
1878
|
+
bt=bt_prc_q(r,st,ct)
|
|
1879
|
+
dbrr=(br_prc_q(rp,st,ct)-br_prc_q(rm,st,ct))/dd
|
|
1880
|
+
dbtt=(bt_prc_q(r,sintp,costp)-bt_prc_q(r,sintm,costm))/dd
|
|
1881
|
+
fcxy=r*dbrr+dbtt
|
|
1882
|
+
bx=(br*(x**2+2.*y**2)+fcxy*y**2)/(r*st)**2+bt*cost
|
|
1883
|
+
by=-(br+fcxy)*x*y/(r*st)**2
|
|
1884
|
+
bz=(br*cost/st-bt)*x/r
|
|
1885
|
+
|
|
1886
|
+
return bx,by,bz
|
|
1887
|
+
|
|
1888
|
+
def br_prc_q(r,sint,cost):
|
|
1889
|
+
"""
|
|
1890
|
+
Calculates the radial component of the "quadrupole" part of the model partial ring current.
|
|
1891
|
+
:param r:
|
|
1892
|
+
:param sint:
|
|
1893
|
+
:param cost:
|
|
1894
|
+
:return:
|
|
1895
|
+
"""
|
|
1896
|
+
|
|
1897
|
+
a1 = -21.2666329
|
|
1898
|
+
a2 = 32.24527521
|
|
1899
|
+
a3 = -6.062894078
|
|
1900
|
+
a4 = 7.515660734
|
|
1901
|
+
a5 = 233.7341288
|
|
1902
|
+
a6 = -227.1195714
|
|
1903
|
+
a7 = 8.483233889
|
|
1904
|
+
a8 = 16.80642754
|
|
1905
|
+
a9 = -24.63534184
|
|
1906
|
+
a10 = 9.067120578
|
|
1907
|
+
a11 = -1.052686913
|
|
1908
|
+
a12 = -12.08384538
|
|
1909
|
+
a13 = 18.61969572
|
|
1910
|
+
a14 = -12.71686069
|
|
1911
|
+
a15 = 47017.35679
|
|
1912
|
+
a16 = -50646.71204
|
|
1913
|
+
a17 = 7746.058231
|
|
1914
|
+
a18 = 1.531069371
|
|
1915
|
+
xk1 = 2.318824273
|
|
1916
|
+
al1 = 0.1417519429
|
|
1917
|
+
dal1 = 0.6388013110e-02
|
|
1918
|
+
b1 = 5.303934488
|
|
1919
|
+
be1 = 4.213397467
|
|
1920
|
+
xk2 = 0.7955534018
|
|
1921
|
+
al2 = 0.1401142771
|
|
1922
|
+
dal2 = 0.2306094179e-01
|
|
1923
|
+
b2 = 3.462235072
|
|
1924
|
+
be2 = 2.568743010
|
|
1925
|
+
xk3 = 3.477425908
|
|
1926
|
+
xk4 = 1.922155110
|
|
1927
|
+
al3 = 0.1485233485
|
|
1928
|
+
dal3 = 0.2319676273e-01
|
|
1929
|
+
b3 = 7.830223587
|
|
1930
|
+
be3 = 8.492933868
|
|
1931
|
+
al4 = 0.1295221828
|
|
1932
|
+
dal4 = 0.01753008801
|
|
1933
|
+
dg1 = 0.01125504083
|
|
1934
|
+
al5 = 0.1811846095
|
|
1935
|
+
dal5 = 0.04841237481
|
|
1936
|
+
dg2 = 0.01981805097
|
|
1937
|
+
c1 = 6.557801891
|
|
1938
|
+
c2 = 6.348576071
|
|
1939
|
+
c3 = 5.744436687
|
|
1940
|
+
al6 = 0.2265212965
|
|
1941
|
+
dal6 = 0.1301957209
|
|
1942
|
+
drm = 0.5654023158
|
|
1943
|
+
|
|
1944
|
+
sint2=sint**2
|
|
1945
|
+
cost2=cost**2
|
|
1946
|
+
sc=sint*cost
|
|
1947
|
+
alpha=sint2/r
|
|
1948
|
+
gamma=cost/r**2
|
|
1949
|
+
|
|
1950
|
+
f,fa,fs = ffs(alpha,al1,dal1)
|
|
1951
|
+
d1=sc*f**xk1/((r/b1)**be1+1.)
|
|
1952
|
+
d2=d1*cost2
|
|
1953
|
+
|
|
1954
|
+
f,fa,fs = ffs(alpha,al2,dal2)
|
|
1955
|
+
d3=sc*fs**xk2/((r/b2)**be2+1.)
|
|
1956
|
+
d4=d3*cost2
|
|
1957
|
+
|
|
1958
|
+
f,fa,fs = ffs(alpha,al3,dal3)
|
|
1959
|
+
d5=sc*(alpha**xk3)*(fs**xk4)/((r/b3)**be3+1.)
|
|
1960
|
+
d6=d5*cost2
|
|
1961
|
+
|
|
1962
|
+
arga=((alpha-al4)/dal4)**2+1.
|
|
1963
|
+
argg=1.+(gamma/dg1)**2
|
|
1964
|
+
|
|
1965
|
+
d7=sc/arga/argg
|
|
1966
|
+
d8=d7/arga
|
|
1967
|
+
d9=d8/arga
|
|
1968
|
+
d10=d9/arga
|
|
1969
|
+
|
|
1970
|
+
arga=((alpha-al5)/dal5)**2+1.
|
|
1971
|
+
argg=1.+(gamma/dg2)**2
|
|
1972
|
+
|
|
1973
|
+
d11=sc/arga/argg
|
|
1974
|
+
d12=d11/arga
|
|
1975
|
+
d13=d12/arga
|
|
1976
|
+
d14=d13/arga
|
|
1977
|
+
|
|
1978
|
+
d15=sc/(r**4+c1**4)
|
|
1979
|
+
d16=sc/(r**4+c2**4)*cost2
|
|
1980
|
+
d17=sc/(r**4+c3**4)*cost2**2
|
|
1981
|
+
|
|
1982
|
+
f,fa,fs = ffs(alpha,al6,dal6)
|
|
1983
|
+
d18=sc*fs/(1.+((r-1.2)/drm)**2)
|
|
1984
|
+
|
|
1985
|
+
br_prc_q=a1*d1+a2*d2+a3*d3+a4*d4+a5*d5+a6*d6+a7*d7+a8*d8+a9*d9+ \
|
|
1986
|
+
a10*d10+a11*d11+a12*d12+a13*d13+a14*d14+a15*d15+a16*d16+a17*d17+a18*d18
|
|
1987
|
+
|
|
1988
|
+
return br_prc_q
|
|
1989
|
+
|
|
1990
|
+
def bt_prc_q(r,sint,cost):
|
|
1991
|
+
"""
|
|
1992
|
+
Calculates the theta component of the "quadrupole" part of the model partial ring current.
|
|
1993
|
+
|
|
1994
|
+
:param r:
|
|
1995
|
+
:param sint:
|
|
1996
|
+
:param cost:
|
|
1997
|
+
:return:
|
|
1998
|
+
"""
|
|
1999
|
+
|
|
2000
|
+
# all linear parameters here were multiplied by 0.1, so that they correspond to p_0=1 npa,
|
|
2001
|
+
# rather than the original value of 10 npa assumed in the biot-savart integral.
|
|
2002
|
+
a1 = 12.74640393
|
|
2003
|
+
a2 = -7.516393516
|
|
2004
|
+
a3 = -5.476233865
|
|
2005
|
+
a4 = 3.212704645
|
|
2006
|
+
a5 = -59.10926169
|
|
2007
|
+
a6 = 46.62198189
|
|
2008
|
+
a7 = -.01644280062
|
|
2009
|
+
a8 = 0.1234229112
|
|
2010
|
+
a9 = -.08579198697
|
|
2011
|
+
a10 = 0.01321366966
|
|
2012
|
+
a11 = 0.8970494003
|
|
2013
|
+
a12 = 9.136186247
|
|
2014
|
+
a13 = -38.19301215
|
|
2015
|
+
a14 = 21.73775846
|
|
2016
|
+
a15 = -410.0783424
|
|
2017
|
+
a16 = -69.90832690
|
|
2018
|
+
a17 = -848.8543440
|
|
2019
|
+
xk1 = 1.243288286
|
|
2020
|
+
al1 = 0.2071721360
|
|
2021
|
+
dal1 = 0.05030555417
|
|
2022
|
+
b1 = 7.471332374
|
|
2023
|
+
be1 = 3.180533613
|
|
2024
|
+
xk2 = 1.376743507
|
|
2025
|
+
al2 = 0.1568504222
|
|
2026
|
+
dal2 = 0.02092910682
|
|
2027
|
+
be2 = 1.985148197
|
|
2028
|
+
xk3 = 0.3157139940
|
|
2029
|
+
xk4 = 1.056309517
|
|
2030
|
+
al3 = 0.1701395257
|
|
2031
|
+
dal3 = 0.1019870070
|
|
2032
|
+
b3 = 6.293740981
|
|
2033
|
+
be3 = 5.671824276
|
|
2034
|
+
al4 = 0.1280772299
|
|
2035
|
+
dal4 = 0.02189060799
|
|
2036
|
+
dg1 = 0.01040696080
|
|
2037
|
+
al5 = 0.1648265607
|
|
2038
|
+
dal5 = 0.04701592613
|
|
2039
|
+
dg2 = 0.01526400086
|
|
2040
|
+
c1 = 12.88384229
|
|
2041
|
+
c2 = 3.361775101
|
|
2042
|
+
c3 = 23.44173897
|
|
2043
|
+
|
|
2044
|
+
sint2=sint**2
|
|
2045
|
+
cost2=cost**2
|
|
2046
|
+
sc=sint*cost
|
|
2047
|
+
alpha=sint2/r
|
|
2048
|
+
gamma=cost/r**2
|
|
2049
|
+
|
|
2050
|
+
f,fa,fs = ffs(alpha,al1,dal1)
|
|
2051
|
+
d1=f**xk1/((r/b1)**be1+1.)
|
|
2052
|
+
d2=d1*cost2
|
|
2053
|
+
|
|
2054
|
+
f,fa,fs = ffs(alpha,al2,dal2)
|
|
2055
|
+
d3=fa**xk2/r**be2
|
|
2056
|
+
d4=d3*cost2
|
|
2057
|
+
|
|
2058
|
+
f,fa,fs = ffs(alpha,al3,dal3)
|
|
2059
|
+
d5=fs**xk3*alpha**xk4/((r/b3)**be3+1.)
|
|
2060
|
+
d6=d5*cost2
|
|
2061
|
+
|
|
2062
|
+
f,fa,fs = ffs(gamma,0.,dg1)
|
|
2063
|
+
fcc=(1.+((alpha-al4)/dal4)**2)
|
|
2064
|
+
d7 =1./fcc*fs
|
|
2065
|
+
d8 =d7/fcc
|
|
2066
|
+
d9 =d8/fcc
|
|
2067
|
+
d10=d9/fcc
|
|
2068
|
+
|
|
2069
|
+
arg=1.+((alpha-al5)/dal5)**2
|
|
2070
|
+
d11=1./arg/(1.+(gamma/dg2)**2)
|
|
2071
|
+
d12=d11/arg
|
|
2072
|
+
d13=d12/arg
|
|
2073
|
+
d14=d13/arg
|
|
2074
|
+
|
|
2075
|
+
d15=1./(r**4+c1**2)
|
|
2076
|
+
d16=cost2/(r**4+c2**2)
|
|
2077
|
+
d17=cost2**2/(r**4+c3**2)
|
|
2078
|
+
|
|
2079
|
+
bt_prc_q = a1*d1+a2*d2+a3*d3+a4*d4+a5*d5+a6*d6+a7*d7+a8*d8+a9*d9+ \
|
|
2080
|
+
a10*d10+a11*d11+a12*d12+a13*d13+a14*d14+a15*d15+a16*d16+a17*d17
|
|
2081
|
+
|
|
2082
|
+
return bt_prc_q
|
|
2083
|
+
|
|
2084
|
+
def ffs(a, a0, da):
|
|
2085
|
+
sq1 = np.sqrt((a + a0) ** 2 + da ** 2)
|
|
2086
|
+
sq2 = np.sqrt((a - a0) ** 2 + da ** 2)
|
|
2087
|
+
fa = 2. / (sq1 + sq2)
|
|
2088
|
+
f = fa * a
|
|
2089
|
+
fs = 0.5 * (sq1 + sq2) / (sq1 * sq2) * (1.-f * f)
|
|
2090
|
+
|
|
2091
|
+
return f, fa, fs
|
|
2092
|
+
|
|
2093
|
+
|
|
2094
|
+
def rc_shield(a,ps,x_sc,x,y,z):
|
|
2095
|
+
"""
|
|
2096
|
+
B due to the ring current shield.
|
|
2097
|
+
:param a: coefficient.
|
|
2098
|
+
:param ps: geo-dipole tilt angle in radius.
|
|
2099
|
+
:param x_sc: scaling factors.
|
|
2100
|
+
:param x,y,z: GSM coordinates in Re (1 Re = 6371.2 km)
|
|
2101
|
+
:return: bx,by,bz. Field components in GSM system, in nT.
|
|
2102
|
+
"""
|
|
2103
|
+
|
|
2104
|
+
fac_sc = (x_sc+1)**3
|
|
2105
|
+
|
|
2106
|
+
cps = np.cos(ps)
|
|
2107
|
+
sps = np.sin(ps)
|
|
2108
|
+
|
|
2109
|
+
s3ps=2*cps
|
|
2110
|
+
|
|
2111
|
+
pst1=ps*a[84]
|
|
2112
|
+
pst2=ps*a[85]
|
|
2113
|
+
|
|
2114
|
+
st1=np.sin(pst1)
|
|
2115
|
+
ct1=np.cos(pst1)
|
|
2116
|
+
st2=np.sin(pst2)
|
|
2117
|
+
ct2=np.cos(pst2)
|
|
2118
|
+
|
|
2119
|
+
x1=x*ct1-z*st1
|
|
2120
|
+
z1=x*st1+z*ct1
|
|
2121
|
+
x2=x*ct2-z*st2
|
|
2122
|
+
z2=x*st2+z*ct2
|
|
2123
|
+
|
|
2124
|
+
l=0
|
|
2125
|
+
[bx,by,bz] = [0.]*3
|
|
2126
|
+
|
|
2127
|
+
for m in range(2): # m=1 is for the 1st sum ("perp." symmetry) and m=2 is for the second sum ("parall." symmetry)
|
|
2128
|
+
for i in range(3):
|
|
2129
|
+
p=a[72+i]
|
|
2130
|
+
q=a[78+i]
|
|
2131
|
+
cypi=np.cos(y/p)
|
|
2132
|
+
cyqi=np.cos(y/q)
|
|
2133
|
+
sypi=np.sin(y/p)
|
|
2134
|
+
syqi=np.sin(y/q)
|
|
2135
|
+
|
|
2136
|
+
for k in range(3):
|
|
2137
|
+
r=a[75+k]
|
|
2138
|
+
s=a[81+k]
|
|
2139
|
+
szrk=np.sin(z1/r)
|
|
2140
|
+
czsk=np.cos(z2/s)
|
|
2141
|
+
czrk=np.cos(z1/r)
|
|
2142
|
+
szsk=np.sin(z2/s)
|
|
2143
|
+
sqpr=np.sqrt(1/p**2+1/r**2)
|
|
2144
|
+
sqqs=np.sqrt(1/q**2+1/s**2)
|
|
2145
|
+
epr=np.exp(x1*sqpr)
|
|
2146
|
+
eqs=np.exp(x2*sqqs)
|
|
2147
|
+
|
|
2148
|
+
for n in range(2): # n=1 is for the first part of each coefficient and n=2 is for the second one
|
|
2149
|
+
for nn in range(2): # nn = 1,2 further splits the coefficients into 2 parts, to take into account the scale factor dependence
|
|
2150
|
+
if m == 0:
|
|
2151
|
+
fx = -sqpr*epr*cypi*szrk*fac_sc
|
|
2152
|
+
fy = epr*sypi*szrk/p *fac_sc
|
|
2153
|
+
fz = -epr*cypi*czrk/r *fac_sc
|
|
2154
|
+
if n == 0:
|
|
2155
|
+
if nn == 0:
|
|
2156
|
+
[hx,hy,hz] = [fx,fy,fz]
|
|
2157
|
+
else:
|
|
2158
|
+
[hx,hy,hz] = [fx*x_sc, fy*x_sc, fz*x_sc]
|
|
2159
|
+
else:
|
|
2160
|
+
if nn == 0:
|
|
2161
|
+
[hx,hy,hz] = [fx*cps, fy*cps, fz*cps]
|
|
2162
|
+
else:
|
|
2163
|
+
[hx,hy,hz] = [fx*cps*x_sc, fy*cps*x_sc, fz*cps*x_sc]
|
|
2164
|
+
else: # m == 2
|
|
2165
|
+
fx = -sps*sqqs*eqs*cyqi*czsk*fac_sc
|
|
2166
|
+
fy = sps/q*eqs*syqi*czsk *fac_sc
|
|
2167
|
+
fz = sps/s*eqs*cyqi*szsk *fac_sc
|
|
2168
|
+
if n == 0:
|
|
2169
|
+
if nn == 0:
|
|
2170
|
+
[hx,hy,hz] = [fx,fy,fz]
|
|
2171
|
+
else:
|
|
2172
|
+
[hx,hy,hz] = [fx*x_sc,fy*x_sc,fz*x_sc]
|
|
2173
|
+
else:
|
|
2174
|
+
if nn == 0:
|
|
2175
|
+
[hx,hy,hz] = [fx*s3ps,fy*s3ps,fz*s3ps]
|
|
2176
|
+
else:
|
|
2177
|
+
[hx,hy,hz] = [fx*s3ps*x_sc, fy*s3ps*x_sc, fz*s3ps*x_sc]
|
|
2178
|
+
|
|
2179
|
+
if m == 0:
|
|
2180
|
+
hxr = hx*ct1+hz*st1
|
|
2181
|
+
hzr = -hx*st1+hz*ct1
|
|
2182
|
+
else:
|
|
2183
|
+
hxr = hx*ct2+hz*st2
|
|
2184
|
+
hzr = -hx*st2+hz*ct2
|
|
2185
|
+
|
|
2186
|
+
bx = bx+hxr*a[l]
|
|
2187
|
+
by = by+hy *a[l]
|
|
2188
|
+
bz = bz+hzr*a[l]
|
|
2189
|
+
l=l+1
|
|
2190
|
+
|
|
2191
|
+
return bx, by, bz
|
|
2192
|
+
|
|
2193
|
+
|
|
2194
|
+
def dipole(ps, x,y,z):
|
|
2195
|
+
"""
|
|
2196
|
+
Calculates GSM components of a geo-dipole field with the dipole moment corresponding to the epoch of 2000.
|
|
2197
|
+
|
|
2198
|
+
:param ps: geo-dipole tilt angle in radius.
|
|
2199
|
+
:param x,y,z: GSM coordinates in Re (1 Re = 6371.2 km)
|
|
2200
|
+
:return: bx,by,bz. Field components in GSM system, in nT.
|
|
2201
|
+
"""
|
|
2202
|
+
|
|
2203
|
+
sps = np.sin(ps)
|
|
2204
|
+
cps = np.cos(ps)
|
|
2205
|
+
|
|
2206
|
+
p = x**2
|
|
2207
|
+
u = z**2
|
|
2208
|
+
v = 3*z*x
|
|
2209
|
+
t = y**2
|
|
2210
|
+
q = 30115./np.sqrt(p+t+u)**5
|
|
2211
|
+
bx = q*((t+u-2*p)*sps-v*cps)
|
|
2212
|
+
by = -3*y*q*(x*sps+z*cps)
|
|
2213
|
+
bz = q*((p+t-2*u)*cps-v*sps)
|
|
2214
|
+
|
|
2215
|
+
return bx,by,bz
|