orbel_el2xv.f 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. *****************************************************************************
  2. * ORBEL_EL2XV.F
  3. *****************************************************************************
  4. * PURPOSE: To compute cartesian positions and velocities given
  5. * central mass, ialpha ( = +1 for hyp., 0 for para. and
  6. * -1 for ellipse), and orbital elements.
  7. C input:
  8. c gm ==> G times central mass (real scalar)
  9. c ialpha ==> conic section type ( see PURPOSE, integer scalar)
  10. C a ==> semi-major axis or pericentric distance if a parabola
  11. c (real scalar)
  12. c e ==> eccentricity (real scalar)
  13. C inc ==> inclination (real scalar)
  14. C capom ==> longitude of ascending node (real scalar)
  15. C omega ==> argument of perihelion (real scalar)
  16. C capm ==> mean anomoly(real scalar)
  17. *
  18. c Output:
  19. c x,y,z ==> position of object (real scalars)
  20. c vx,vy,vz ==> velocity of object (real scalars)
  21. c
  22. * ALGORITHM: See Fitzpatrick "Principles of Cel. Mech."
  23. * REMARKS: All angles are in RADIANS
  24. *
  25. * AUTHOR: M. Duncan.
  26. * DATE WRITTEN: May 11, 1992.
  27. * REVISIONS: May 26 - now use better Kepler solver for ellipses
  28. * and hyperbolae called EHYBRID.F and FHYBRID.F
  29. ***********************************************************************
  30. subroutine orbel_el2xv(gm,ialpha,a,e,inc,capom,omega,capm,
  31. & x,y,z,vx,vy,vz)
  32. include '../swift.inc'
  33. c... Inputs Only:
  34. integer ialpha
  35. real*8 gm,a,e,inc,capom,omega,capm
  36. c... Outputs:
  37. real*8 x,y,z,vx,vy,vz
  38. c... Internals:
  39. real*8 cape,capf,zpara,em1
  40. real*8 sp,cp,so,co,si,ci
  41. real*8 d11,d12,d13,d21,d22,d23
  42. real*8 scap,ccap,shcap,chcap
  43. real*8 sqe,sqgma,xfac1,xfac2,ri,vfac1,vfac2
  44. real*8 orbel_ehybrid,orbel_fhybrid,orbel_zget
  45. c----
  46. c... Executable code
  47. if(e.lt.0.0) then
  48. write(*,*) ' ERROR in orbel_el2xv: e<0, setting e=0!!1'
  49. e = 0.0
  50. endif
  51. c... check for inconsistencies between ialpha and e
  52. em1 = e - 1.d0
  53. if(
  54. & ((ialpha.eq.0) .and. (abs(em1).gt.TINY)) .or.
  55. & ((ialpha.lt.0) .and. (e.gt.1.0d0)) .or.
  56. & ((ialpha.gt.0) .and. (e.lt.1.0d0)) ) then
  57. write(*,*) 'ERROR in orbel_el2xv: ialpha and e inconsistent'
  58. write(*,*) ' ialpha = ',ialpha
  59. write(*,*) ' e = ',e
  60. endif
  61. C Generate rotation matrices (on p. 42 of Fitzpatrick)
  62. C
  63. call orbel_scget(omega,sp,cp)
  64. call orbel_scget(capom,so,co)
  65. call orbel_scget(inc,si,ci)
  66. d11 = cp*co - sp*so*ci
  67. d12 = cp*so + sp*co*ci
  68. d13 = sp*si
  69. d21 = -sp*co - cp*so*ci
  70. d22 = -sp*so + cp*co*ci
  71. d23 = cp*si
  72. C--
  73. C Get the other quantities depending on orbit type ( i.e. IALPHA)
  74. C
  75. if (ialpha .eq. -1) then
  76. cape = orbel_ehybrid(e,capm)
  77. call orbel_scget(cape,scap,ccap)
  78. sqe = sqrt(1.d0 -e*e)
  79. sqgma = sqrt(gm*a)
  80. xfac1 = a*(ccap - e)
  81. xfac2 = a*sqe*scap
  82. ri = 1.d0/(a*(1.d0 - e*ccap))
  83. vfac1 = -ri * sqgma * scap
  84. vfac2 = ri * sqgma * sqe * ccap
  85. endif
  86. c--
  87. if (ialpha .eq. +1) then
  88. capf = orbel_fhybrid(e,capm)
  89. call orbel_schget(capf,shcap,chcap)
  90. sqe = sqrt(e*e - 1.d0 )
  91. sqgma = sqrt(gm*a)
  92. xfac1 = a*(e - chcap)
  93. xfac2 = a*sqe*shcap
  94. ri = 1.d0/(a*(e*chcap - 1.d0))
  95. vfac1 = -ri * sqgma * shcap
  96. vfac2 = ri * sqgma * sqe * chcap
  97. endif
  98. C--
  99. if (ialpha .eq. 0) then
  100. zpara = orbel_zget(capm)
  101. sqgma = sqrt(2.d0*gm*a)
  102. xfac1 = a*(1.d0 - zpara*zpara)
  103. xfac2 = 2.d0*a*zpara
  104. ri = 1.d0/(a*(1.d0 + zpara*zpara))
  105. vfac1 = -ri * sqgma * zpara
  106. vfac2 = ri * sqgma
  107. endif
  108. C--
  109. x = d11*xfac1 + d21*xfac2
  110. y = d12*xfac1 + d22*xfac2
  111. z = d13*xfac1 + d23*xfac2
  112. vx = d11*vfac1 + d21*vfac2
  113. vy = d12*vfac1 + d22*vfac2
  114. vz = d13*vfac1 + d23*vfac2
  115. return
  116. end ! orbel_el2xv
  117. c-----------------------------------------------------------------------