orbel_flon.f 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. ***********************************************************************
  2. c ORBEL_FLON.F
  3. ***********************************************************************
  4. * PURPOSE: Solves Kepler's eqn. for hyperbola using hybrid approach.
  5. *
  6. * Input:
  7. * e ==> eccentricity anomaly. (real scalar)
  8. * capn ==> hyperbola mean anomaly. (real scalar)
  9. * Returns:
  10. * orbel_flon ==> eccentric anomaly. (real scalar)
  11. *
  12. * ALGORITHM: Uses power series for N in terms of F and Newton,s method
  13. * REMARKS: ONLY GOOD FOR LOW VALUES OF N (N < 0.636*e -0.6)
  14. * AUTHOR: M. Duncan
  15. * DATE WRITTEN: May 26, 1992.
  16. * REVISIONS:
  17. ***********************************************************************
  18. real*8 function orbel_flon(e,capn)
  19. include '../swift.inc'
  20. c... Inputs Only:
  21. real*8 e,capn
  22. c... Internals:
  23. integer iflag,i,IMAX
  24. real*8 a,b,sq,biga,bigb
  25. real*8 x,x2
  26. real*8 f,fp,dx
  27. real*8 diff
  28. real*8 a0,a1,a3,a5,a7,a9,a11
  29. real*8 b1,b3,b5,b7,b9,b11
  30. PARAMETER (IMAX = 10)
  31. PARAMETER (a11 = 156.d0,a9 = 17160.d0,a7 = 1235520.d0)
  32. PARAMETER (a5 = 51891840.d0,a3 = 1037836800.d0)
  33. PARAMETER (b11 = 11.d0*a11,b9 = 9.d0*a9,b7 = 7.d0*a7)
  34. PARAMETER (b5 = 5.d0*a5, b3 = 3.d0*a3)
  35. c----
  36. c... Executable code
  37. c Function to solve "Kepler's eqn" for F (here called
  38. c x) for given e and CAPN. Only good for smallish CAPN
  39. iflag = 0
  40. if( capn .lt. 0.d0) then
  41. iflag = 1
  42. capn = -capn
  43. endif
  44. a1 = 6227020800.d0 * (1.d0 - 1.d0/e)
  45. a0 = -6227020800.d0*capn/e
  46. b1 = a1
  47. c Set iflag nonzero if capn < 0., in which case solve for -capn
  48. c and change the sign of the final answer for F.
  49. c Begin with a reasonable guess based on solving the cubic for small F
  50. a = 6.d0*(e-1.d0)/e
  51. b = -6.d0*capn/e
  52. sq = sqrt(0.25*b*b +a*a*a/27.d0)
  53. biga = (-0.5*b + sq)**0.3333333333333333d0
  54. bigb = -(+0.5*b + sq)**0.3333333333333333d0
  55. x = biga + bigb
  56. c write(6,*) 'cubic = ',x**3 +a*x +b
  57. orbel_flon = x
  58. c If capn is tiny (or zero) no need to go further than cubic even for
  59. c e =1.
  60. if( capn .lt. TINY) go to 100
  61. do i = 1,IMAX
  62. x2 = x*x
  63. f = a0 +x*(a1+x2*(a3+x2*(a5+x2*(a7+x2*(a9+x2*(a11+x2))))))
  64. fp = b1 +x2*(b3+x2*(b5+x2*(b7+x2*(b9+x2*(b11 + 13.d0*x2)))))
  65. dx = -f/fp
  66. c write(6,*) 'i,dx,x,f : '
  67. c write(6,432) i,dx,x,f
  68. 432 format(1x,i3,3(2x,1p1e22.15))
  69. orbel_flon = x + dx
  70. c If we have converged here there's no point in going on
  71. if(abs(dx) .le. TINY) go to 100
  72. x = orbel_flon
  73. enddo
  74. c Abnormal return here - we've gone thru the loop
  75. c IMAX times without convergence
  76. if(iflag .eq. 1) then
  77. orbel_flon = -orbel_flon
  78. capn = -capn
  79. endif
  80. write(6,*) 'FLON : RETURNING WITHOUT COMPLETE CONVERGENCE'
  81. diff = e*sinh(orbel_flon) - orbel_flon - capn
  82. write(6,*) 'N, F, ecc*sinh(F) - F - N : '
  83. write(6,*) capn,orbel_flon,diff
  84. return
  85. c Normal return here, but check if capn was originally negative
  86. 100 if(iflag .eq. 1) then
  87. orbel_flon = -orbel_flon
  88. capn = -capn
  89. endif
  90. return
  91. end ! orbel_flon
  92. c------------------------------------------------------------------