pro morbit, param, dt=dt, planet=planet, nmax=nmax, oerr=oerr, result=result, $
norbit=norbit, oplot=oplot, tplot=tplot, orient=orient, $
flythru=flythru, shock=shock, ps=ps, xyrange=xyrange
if (size(param,/type) ne 8) then begin
print, 'You must specify an orbit parameter structure.'
return
endif
dtor = !dpi/180D
if (size(orient,/type) eq 8) then begin
str_element, orient, 'lon', lon, success=ok
if (ok) then lon = double(lon)*dtor else lon = 0D
str_element, orient, 'lat', lat, success=ok
if (ok) then lat = double(lat)*dtor else lat = 0D
str_element, orient, 'incl', incl, success=ok
if (ok) then incl = double(incl)*dtor else incl = !dpi/2D
endif else begin
lon = 0D
lat = 0D
incl = !dpi/2D
endelse
indx = where(abs(lat) gt abs(incl), count)
if (count gt 0L) then begin
print, 'Periapsis latitude is greater than orbit inclination!'
print, 'Fix the ORIENT keyword and try again.'
return
endif
lat = lat < (0.99999D*incl)
lat = lat > (-0.99999D*incl)
nlon = n_elements(lon)
nlat = n_elements(lat)
lon = lon # replicate(1.,nlat)
lat = replicate(1.,nlon) # lat
swfrac = replicate(0.,nlon,nlat)
if (size(planet,/type) eq 8) then begin
str_element, planet, 'mass', M, success=ok
if (not ok) then begin
print, 'You must specify the planet''s mass (g).'
return
endif
M = double(M)
str_element, planet, 'radius', R, success=ok
if (not ok) then begin
print, 'You must specify the planet''s radius (km).'
return
endif
R = double(R)
str_element, planet, 'name', Name, success=ok
if (not ok) then Name = ''
planet = 'USERDEF'
endif
if (size(planet,/type) ne 7) then planet = 'MARS' $
else planet = strupcase(planet)
if not keyword_set(norbit) then norbit = 1D else norbit = double(norbit)
if not keyword_set(nmax) then nmax = 400L else nmax = long(nmax)
if not keyword_set(oerr) then oerr = 1.d-6 else oerr = double(oerr)
oerr = oerr*oerr
if keyword_set(ps) then begin
psflg = 1
scol = 0
endif else begin
psflg = 0
scol = 3
endelse
wsave = !d.window
if (size(oplot,/type) ne 0) then begin
oflg = 1
window,oplot,xsize=326,ysize=920,xpos=25,ypos=25
endif else oflg = 0
if (size(tplot,/type) ne 0) then begin
tflg = 1
if (oflg) then if (tplot eq oplot) then tplot = oplot + 1
window,tplot,xsize=720,ysize=500
endif else tflg = 0
sflg = 0
mflg = 0
case (planet) of
'SUN' : begin
M = 1.9891d33
R = 6.96d5
end
'MERCURY' : begin
M = 3.302d26
R = 2440D
end
'VENUS' : begin
M = 4.8685d27
R = 6051.84D
end
'EARTH' : begin
M = 5.9736d27
R = 6371.01D
x0 = 3.5
psi = 1.02
L = 22.1
sflg = 1
end
'MOON' : begin
M = 7.349d25
R = 1737.53D
end
'MARS' : begin
M = 6.4185d26
R = 3389.9D
x0 = 0.64
psi = 1.03
L = 2.04
x0_p1 = 0.640
psi_p1 = 0.770
L_p1 = 1.080
x0_p2 = 1.600
psi_p2 = 1.009
L_p2 = 0.528
sflg = 1
mflg = 1
end
'CERES' : begin
M = 9.43d23
R = 476.2D
end
'JUPITER' : begin
M = 1.8986d30
R = 69911D
end
'SATURN' : begin
M = 5.6846d29
R = 58232D
end
'URANUS' : begin
M = 8.6832d28
R = 25362D
end
'NEPTUNE' : begin
M = 1.0243d29
R = 24624D
end
'PLUTO' : begin
M = 1.309d25
R = 1151D
end
'CHARON' : begin
M = 1.90d24
R = 593D
end
'ERIS' : begin
M = 1.67d25
R = 1163D
end
'USERDEF' : begin
planet = strupcase(Name)
end
else : begin
print, 'Unrecognized planet.'
planet = strupcase(planet)
M = 0D
R = 0D
print, 'Mass (g) ', format='(a,$)'
read, M, format='(f)'
print, 'Radius (km) ', format='(a,$)'
read, R, format='(f)'
end
endcase
if not keyword_set(SHOCK) then begin
sflg = 0
mflg = 0
endif
twopi = 2D*!dpi
GM = (6.67259d-8)*M
pflg = [0, 0, 0, 0, 0]
str_element, param, 'period', period, success=ok
if (ok) then pflg[0] = 1
str_element, param, 'sma', sma, success=ok
if (ok) then pflg[1] = 1
str_element, param, 'ecc', ecc, success=ok
if (ok) then pflg[2] = 1
str_element, param, 'palt', palt, success=ok
if (ok) then pflg[3] = 1
str_element, param, 'aalt', aalt, success=ok
if (ok) then pflg[4] = 1
if (pflg[0]) then begin
period = double(period)*3600D
k = twopi/period
sma = (GM/(k*k))^(1D/3D)
sma = sma/1.d5
goto, OSHAPE
endif
if (pflg[1]) then begin
sma = double(sma)
k = sqrt(GM/(sma*1.d5)^3D)
period = twopi/k
goto, OSHAPE
endif
if (pflg[2] eq 0) then begin
if ((pflg[3] eq 0) or (pflg[4] eq 0)) then begin
print, 'Insufficient orbit parameters.'
return
endif
palt = double(palt)
aalt = double(aalt)
sma = R + (palt + aalt)/2D
k = sqrt(GM/(sma*1.d5)^3D)
period = twopi/k
goto, OSHAPE
endif
if (pflg[3] eq 0) then begin
if ((pflg[2] eq 0) or (pflg[4] eq 0)) then begin
print, 'Insufficient orbit parameters.'
return
endif
ecc = double(ecc)
aalt = double(aalt)
sma = (aalt + R)/(1D + ecc)
k = sqrt(GM/(sma*1.d5)^3D)
period = twopi/k
goto, OSHAPE
endif
if (pflg[4] eq 0) then begin
if ((pflg[2] eq 0) or (pflg[3] eq 0)) then begin
print, 'Insufficient orbit parameters.'
return
endif
ecc = double(ecc)
palt = double(palt)
sma = (palt + R)/(1D - ecc)
k = sqrt(GM/(sma*1.d5)^3D)
period = twopi/k
endif
OSHAPE:
if (pflg[2]) then begin
ecc = double(ecc)
palt = sma*(1D - ecc) - R
aalt = sma*(1D + ecc) - R
endif else begin
if (pflg[3]) then begin
palt = double(palt)
ecc = 1D - (palt + R)/sma
aalt = sma*(1D + ecc) - R
endif else begin
if (pflg[4]) then begin
aalt = double(aalt)
ecc = (aalt + R)/sma - 1D
palt = sma*(1D - ecc) - R
endif else begin
print, 'Insufficient orbit parameters.'
return
endelse
endelse
endelse
sre = sqrt((1D + ecc)/(1D - ecc))
if not keyword_set(dt) then dt = period/1000D else dt = double(dt)
npts = round(norbit*period/dt) + 1L
t = dt*dindgen(npts)
dist = dblarr(npts)
thet = dist
for i=0L,(npts-1L) do begin
m = k*t[i] - !dpi
eps1 = m + ecc*(sin(m) + ecc*sin(2D*m)/2D)
eps = m + ecc*sin(eps1)
x = eps - eps1
n = 0
while (x*x gt oerr) do begin
eps1 = eps
n = n + 1
if (n gt nmax) then begin
print, "Not converging!"
print, "Percent complete: ", round(100D*double(i)/double(npts))
print, "oerr = ", x*x
return
endif
eps = m + ecc*sin(eps1)
x = eps - eps1
endwhile
dist[i] = sma*(1D - ecc*cos(eps))
thet[i] = 2D*atan(sre*tan(eps/2D))
endfor
v = sqrt(GM*(2D/dist - 1D/sma)/1.d15)
Vesc = sqrt(2D*GM/(1.d15*dist))
sc = replicate(0D,3,npts)
sc[0,*] = dist*cos(thet)
sc[1,*] = dist*sin(thet)
for i=0L,(nlon-1L) do begin
for j=0L,(nlat-1L) do begin
cphi = cos(lon[i,j])
sphi = sin(lon[i,j])
r1 = dblarr(3,3)
r1[*,0] = [ cphi , sphi , 0D ]
r1[*,1] = [ -sphi , cphi , 0D ]
r1[*,2] = [ 0D , 0D , 1D ]
cphi = cos(lat[i,j])
sphi = sin(lat[i,j])
r2 = dblarr(3,3)
r2[*,0] = [ cphi , 0D , sphi ]
r2[*,1] = [ 0D , 1D , 0D ]
r2[*,2] = [ -sphi , 0D , cphi ]
cphi = cos(incl)/cos(lat[i,j])
sphi = sqrt(1D - cphi*cphi)
r3 = dblarr(3,3)
r3[*,0] = [ 1D , 0D , 0D ]
r3[*,1] = [ 0D , cphi , sphi ]
r3[*,2] = [ 0D , -sphi , cphi ]
ss = ((r1 # r2) # r3) # sc
ss = transpose(ss)
if (size(flythru,/type) eq 7) then begin
openw, lun, flythru, /get_lun
for k=0L,(npts-1L) do $
printf,lun,t[k],ss[k,0],ss[k,1],ss[k,2],v[k],$
format='(4(f7.1,3x),f9.7)'
free_lun,lun
endif
if (oflg) then begin
phi = findgen(361)*!dtor
xm = cos(phi)
ym = sin(phi)
rmin = min(dist, imin)
imin = imin[0]
rmax = ceil(aalt/R + 1D)
if keyword_set(xyrange) then begin
xrange = [-xyrange,xyrange]
yrange = xrange
endif else begin
xrange = [-rmax,rmax]
yrange = xrange
endelse
if (psflg) then begin
popen,'morbit_oplot'
!p.multi = [3,2,2]
endif else begin
wset, oplot
!p.multi = [3,1,3]
endelse
x = ss[*,0]/R
y = ss[*,1]/R
z = ss[*,2]/R
s = sqrt(x*x + y*y)
xo = x
yo = y
mndx = where((z lt 0.) and (s lt 1.), mcnt)
if (mcnt gt 0L) then begin
x[mndx] = !values.f_nan
y[mndx] = !values.f_nan
endif
if (psflg) then begin
plot,[xrange[0]],[yrange[0]],xrange=xrange,yrange=yrange,$
/xsty,/ysty, xtitle='X (Rp)',ytitle='Y (Rp)',charsize=1.0, $
ymargin=[8,9],title=planet
oplot,xm,ym,color=6,thick=2
oplot,x,y
oplot,[x[imin]],[y[imin]],psym=4,color=4,thick=2
endif else begin
plot,xm,ym,xrange=xrange,yrange=yrange,/xsty,/ysty, $
xtitle='X (Rp)',ytitle='Y (Rp)',charsize=2.0,title=planet
oplot,xm,ym,color=6
oplot,x,y
oplot,[x[imin]],[y[imin]],psym=4,color=4,thick=2
endelse
if (sflg) then begin
phm = 160.*!dtor
phi = (-150. + findgen(301))*!dtor
rho = L/(1. + psi*cos(phi))
xs = x0 + rho*cos(phi)
ys = rho*sin(phi)
oplot,xs,ys,color=scol,line=1
s = sqrt(yo*yo + z*z)
phi = atan(s,(xo - x0))
rho = sqrt((xo - x0)^2. + s*s)
indx = where(rho lt L/(1. + psi*cos(phi < phm)), count)
if (count gt 0L) then oplot, x[indx], y[indx], color=4, psym=3
swfrac[i,j] = float(npts - count)/float(npts)
endif
if (mflg) then begin
phi = (-160. + findgen(160))*!dtor
rho = L_p1/(1. + psi_p1*cos(phi))
x1 = x0_p1 + rho*cos(phi)
y1 = rho*sin(phi)
rho = L_p2/(1. + psi_p2*cos(phi))
x2 = x0_p2 + rho*cos(phi)
y2 = rho*sin(phi)
indx = where(x1 ge 0)
jndx = where(x2 lt 0)
xpileup = [x2[jndx], x1[indx]]
ypileup = [y2[jndx], y1[indx]]
phi = findgen(161)*!dtor
rho = L_p1/(1. + psi_p1*cos(phi))
x1 = x0_p1 + rho*cos(phi)
y1 = rho*sin(phi)
rho = L_p2/(1. + psi_p2*cos(phi))
x2 = x0_p2 + rho*cos(phi)
y2 = rho*sin(phi)
indx = where(x1 ge 0)
jndx = where(x2 lt 0)
xpileup = [xpileup, x1[indx], x2[jndx]]
ypileup = [ypileup, y1[indx], y2[jndx]]
oplot,xpileup,ypileup,color=scol,line=1
endif
x = ss[*,0]/R
y = ss[*,1]/R
z = ss[*,2]/R
s = sqrt(x*x + z*z)
indx = where((y gt 0.) and (s lt 1.), count)
if (count gt 0L) then begin
x[indx] = !values.f_nan
z[indx] = !values.f_nan
endif
if (psflg) then begin
plot,[xrange[0]],[yrange[0]],xrange=xrange,yrange=yrange,$
/xsty,/ysty,xtitle='X (Rp)',ytitle='Z (Rp)',charsize=1.0,$
ymargin=[16,1]
oplot,xm,ym,color=6, thick=2
oplot,x,z
oplot,[x[imin]],[z[imin]],psym=4,color=4,thick=2
endif else begin
plot,xm,ym,xrange=xrange,yrange=yrange,/xsty,/ysty, $
xtitle='X (Rp)',ytitle='Z (Rp)',charsize=2.0
oplot,xm,ym,color=6
oplot,x,z
oplot,[x[imin]],[z[imin]],psym=4,color=4,thick=2
endelse
if (sflg) then begin
phm = 160.*!dtor
phi = (-150. + findgen(301))*!dtor
rho = L/(1. + psi*cos(phi))
xs = x0 + rho*cos(phi)
zs = rho*sin(phi)
oplot,xs,zs,color=scol,line=1
s = sqrt(y*y + z*z)
phi = atan(s,(x - x0))
rho = sqrt((x - x0)^2. + s*s)
indx = where(rho lt L/(1. + psi*cos(phi < phm)), count)
if (count gt 0L) then oplot, x[indx], z[indx], color=4, psym=3
endif
if (mflg) then begin
phi = (-160. + findgen(160))*!dtor
rho = L_p1/(1. + psi_p1*cos(phi))
x1 = x0_p1 + rho*cos(phi)
y1 = rho*sin(phi)
rho = L_p2/(1. + psi_p2*cos(phi))
x2 = x0_p2 + rho*cos(phi)
y2 = rho*sin(phi)
indx = where(x1 ge 0)
jndx = where(x2 lt 0)
xpileup = [x2[jndx], x1[indx]]
ypileup = [y2[jndx], y1[indx]]
phi = findgen(161)*!dtor
rho = L_p1/(1. + psi_p1*cos(phi))
x1 = x0_p1 + rho*cos(phi)
y1 = rho*sin(phi)
rho = L_p2/(1. + psi_p2*cos(phi))
x2 = x0_p2 + rho*cos(phi)
y2 = rho*sin(phi)
indx = where(x1 ge 0)
jndx = where(x2 lt 0)
xpileup = [xpileup, x1[indx], x2[jndx]]
ypileup = [ypileup, y1[indx], y2[jndx]]
oplot,xpileup,ypileup,color=scol,line=1
endif
x = ss[*,0]/R
y = ss[*,1]/R
z = ss[*,2]/R
s = sqrt(y*y + z*z)
indx = where((x lt 0.) and (s lt 1.), count)
if (count gt 0L) then begin
y[indx] = !values.f_nan
z[indx] = !values.f_nan
endif
if (psflg) then begin
plot,[xrange[0]],[yrange[0]],xrange=xrange,yrange=yrange,$
/xsty,/ysty,xtitle='Y (Rp)',ytitle='Z (Rp)',charsize=1.0, $
ymargin=[16,1]
oplot,xm,ym,color=6,thick=2
oplot,y,z
oplot,[y[imin]],[z[imin]],psym=4,color=4,thick=2
endif else begin
plot,xm,ym,xrange=xrange,yrange=yrange,/xsty,/ysty, $
xtitle='Y (Rp)',ytitle='Z (Rp)',charsize=2.0
oplot,xm,ym,color=6
oplot,y,z
oplot,[y[imin]],[z[imin]],psym=4,color=4,thick=2
endelse
if (sflg) then begin
phm = 160.*!dtor
L0 = sqrt((L + psi*x0)^2. - x0*x0)
oplot,L0*xm,L0*ym,color=scol,line=1
s = sqrt(y*y + z*z)
phi = atan(s,(x - x0))
rho = sqrt((x - x0)^2. + s*s)
indx = where(rho lt L/(1. + psi*cos(phi < phm)), count)
if (count gt 0L) then oplot, y[indx], z[indx], color=4, psym=3
endif
if (mflg) then begin
L0 = sqrt((L_p1 + psi_p1*x0_p1)^2. - x0_p1*x0_p1)
oplot,L0*xm,L0*ym,color=scol,line=1
endif
if (psflg) then pclose
!p.multi = 0
endif
if (tflg) then begin
store_data,'alt',data={x:t, y:(dist-R)}
ylim,'alt',0,0,0
options,'alt','ynozero',1
options,'alt','ytitle','Altitude (km)'
if (aalt/palt gt 10D) then ylim,'alt',0,0,1
store_data,'vel',data={x:t, y:v}
options,'vel','ynozero',1
options,'vel','ytitle','Velocity (km/s)'
store_data,'Vesc',data={x:t, y:Vesc}
options,'Vesc','color',6
options,'Vesc','linestyle',2
store_data,'Velocity',data=['vel','Vesc']
tplot_options,'charsize',1.2
tplot_options,'title',planet
wset, tplot
timespan,[min(t),max(t)],/sec
tplot,['alt','Velocity']
tplot_options,'title',''
tplot_options,'charsize',1.0
endif
endfor
endfor
wset, wsave
period = period/3600D
lon = lon/dtor
lat = lat/dtor
incl = incl/dtor
result = {t : t , $
dist : dist , $
thet : thet , $
x : ss , $
alt : dist - R , $
vel : v , $
period : period , $
sma : sma , $
palt : palt , $
plon : lon , $
plat : lat , $
aalt : aalt , $
ecc : ecc , $
incl : incl , $
swfrac : swfrac , $
planet : planet , $
radius : R , $
Vesc : Vesc }
return
end