Advertisement
Guest User

Untitled

a guest
Feb 29th, 2024
260
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.27 KB | None | 0 0
  1.  
  2.  
  3. def RK45(x, v, t, n, h, F, tolx, varistep=False):
  4.    
  5.     # I can't guarantee these are all correct, better check them yourself
  6.     a11 = 1./1.  # not used
  7.     a21 = 1./4.
  8.     a31 = 3./8.
  9.     a41 = 12./13.
  10.     a51 = 1./1.
  11.     a61 = 1./2.
  12.  
  13.     b21 = 1./4.
  14.  
  15.     b31 = 3./32.
  16.     b32 = 9./32.
  17.  
  18.     b41 = 1932./2197.
  19.     b42 = -7200./2197.
  20.     b43 = 7296./2197.
  21.  
  22.     b51 = 439./216.
  23.     b52 = -8./1.
  24.     b53 = 3680./513.
  25.     b54 = -845./4104.
  26.  
  27.     b61 = -8./27.
  28.     b62 = 2./1.
  29.     b63 = -3544./2565.
  30.     b64 = 1859./4104.
  31.     b65 = -11./40.
  32.  
  33.     c1 = 25./216.
  34.     # no c2
  35.     c3 = 1408./2565.
  36.     c4 = 2197./4104.  
  37.     c5 = -1./5.
  38.  
  39.     d1 = 16./135.
  40.     #no d2
  41.     d3 = 6656./12825.
  42.     d4 = 28561./56430.
  43.     d5 = -9./50.
  44.     d6 = 2./55.
  45.  
  46.     sm = np.zeros_like(t)
  47.    
  48.     for i in range(n):  # written for readability, not speed
  49.  
  50.         kv1 = h * F( x[i] )
  51.         kx1 = h *  ( v[i] )
  52.  
  53.         kv2 = h * F( x[i] + b21*kx1 )
  54.         kx2 = h *  ( v[i] + b21*kv1 )
  55.  
  56.         kv3 = h * F( x[i] + b31*kx1 + b32*kx2 )
  57.         kx3 = h *  ( v[i] + b31*kv1 + b32*kv2 )
  58.  
  59.         kv4 = h * F( x[i] + b41*kx1 + b42*kx2 + b43*kx3 )
  60.         kx4 = h *  ( v[i] + b41*kv1 + b42*kv2 + b43*kv3 )
  61.  
  62.         kv5 = h * F( x[i] + b51*kx1 + b52*kx2 + b53*kx3 + b54*kx4 )
  63.         kx5 = h *  ( v[i] + b51*kv1 + b52*kv2 + b53*kv3 + b54*kv4 )
  64.  
  65.         kv6 = h * F( x[i] + b61*kx1 + b62*kx2 + b63*kx3 + b64*kx4 + b65*kx5 )
  66.         kx6 = h *  ( v[i] + b61*kv1 + b62*kv2 + b63*kv3 + b64*kv4 + b65*kv5 )
  67.  
  68.         xx  = x[i] + c1*kx1 + c3*kx3 + c4*kx4 + c5*kx5  # no c2
  69.         vv  = v[i] + c1*kv1 + c3*kv3 + c4*kv4 + c5*kv5
  70.  
  71.         xx5  = x[i] + d1*kx1 + d3*kx3 + d4*kx4 + d5*kx5 + d6*kx6  # no c2
  72.         vv5 =  v[i] + d1*kv1 + d3*kv3 + d4*kv4 + d5*kv5 + d6*kv6
  73.  
  74.         x[i+1]  = xx
  75.         v[i+1]  = vv
  76.  
  77.         s = np.sqrt(np.sqrt(tolx * h / (2.*abs(xx5 - xx))))  # faster than **0.25
  78.  
  79.         smin = s.min()
  80.  
  81.         sm[i] = smin
  82.  
  83.         t[i+1] = t[i] + h
  84.  
  85.         if varistep:
  86.             h *= smin  # usually you do this more carefully.
  87.            
  88.     return sm
  89.  
  90.  
  91. def RK4(x, v, t, n, h, F):
  92.  
  93.     h_over_two = 0.5 * h
  94.     h_over_six = (1./6.) * h
  95.  
  96.     for i in range(n):  # written for readability, not speed
  97.  
  98.         kv1 = F( x[i]                   )
  99.         kx1 =    v[i]
  100.  
  101.         kv2 = F( x[i] + kx1 * h_over_two )
  102.         kx2 =    v[i] + kv1 * h_over_two
  103.  
  104.         kv3 = F( x[i] + kx2 * h_over_two )
  105.         kx3 =    v[i] + kv2 * h_over_two
  106.  
  107.         kv4 = F( x[i] + kx3 * h          )
  108.         kx4 =    v[i] + kv3 * h
  109.  
  110.         v[i+1] = v[i] + h_over_six * (kv1 + 2.*(kv2 + kv3) + kv4)
  111.         x[i+1] = x[i] + h_over_six * (kx1 + 2.*(kx2 + kx3) + kx4)
  112.  
  113.         t[i+1] = t[i] + h
  114.  
  115.  
  116. def RK4_new(x0, v0, n, h, F):
  117.     """RK4 based orbit integrator n time steps of fixed size h
  118.       using the function F for acceleration"""
  119.  
  120.     hov2, hov6 = h / 2., h / 6.
  121.  
  122.     x, v, t = x0, v0, 0.
  123.    
  124.     results = [(t, x.copy(), v.copy())]
  125.     for i in range(n):  # written for readability, not speed
  126.  
  127.         kv1 = F(x)
  128.         kx1 = v
  129.  
  130.         kv2 = F(x + kx1 * hov2)
  131.         kx2 =   v + kv1 * hov2
  132.  
  133.         kv3 = F(x + kx2 * hov2)
  134.         kx3 =   v + kv2 * hov2
  135.  
  136.         kv4 = F(x + kx3 * h)
  137.         kx4 =   v + kv3 * h
  138.  
  139.         v += hov6 * (kv1 + 2. * (kv2 + kv3) + kv4)
  140.         x += hov6 * (kx1 + 2. * (kx2 + kx3) + kx4)
  141.         t += h
  142.        
  143.         results.append((t, x.copy(), v.copy()))
  144.  
  145.     t, x, v = [np.array(thing) for thing in zip(*results)]
  146.  
  147.     return t, x, v
  148.        
  149.  
  150.  
  151. def acc(x):
  152.     """ acceleration due to the sun's gravity (NumPy version) """
  153.     return -Gm * x / (x**2).sum()**1.5
  154.  
  155.  
  156. import matplotlib.pyplot as plt
  157. import matplotlib.cm as cm
  158. import numpy as np
  159.  
  160. Gm = 1.3271244002E+20  # m^3 s^-2               (Wikipedia)
  161. e = 0.01671123         # earth eccentricity     (Wikipedia)
  162. a = 1.49598261E+11     # earth semi-major axis  (Wikipedia)
  163.  
  164. # r = a(1-e^2)/(1+e*cos(theta)) an equation for an ellipse
  165. r_aphelion   = a * (1. + e)
  166. r_perihelion = a * (1. - e)
  167.  
  168. # using vis-viva equation v^2 = Gm * (2./r - 1./a) (Wikipedia)
  169. # (this is really just conservation of energy: Kinetic + Potential = const)
  170. v_aphelion = np.sqrt(Gm * (2./(1.+e) - 1.) / a)
  171.  
  172. t_year = 2. * np.pi * np.sqrt(a**3/Gm)
  173.  
  174. nstep = 500   # CHANGE THIS TO SEE WHAT HAPPENS!
  175.  
  176. Dt = t_year / float(nstep)   # time step
  177.  
  178.  
  179.  
  180. X4 = np.zeros((1000,3))
  181. V4 = np.zeros((1000,3))
  182. T4 = np.zeros((1000))
  183.  
  184. V4[0] = 0.0, 0.5*v_aphelion, 0.0
  185. X4[0] = r_aphelion, 0.0, 0.0
  186. T4[0] = 0.0
  187.  
  188. X45 = X4.copy()
  189. V45 = V4.copy()
  190. T45 = T4.copy()
  191.  
  192.  
  193. RK4( X4,  V4,  T4,  nstep, Dt, acc)  
  194.  
  195.  
  196. vary = True  # try both
  197. s = RK45(X45, V45, T45, nstep, Dt, acc, 1E-04, varistep=vary)
  198.  
  199.  
  200. plt.figure()
  201.  
  202. plt.subplot(2, 3, 1)
  203. plt.plot(X4[:nstep,0], X4[:nstep,1])
  204. plt.title("RK4 x, y orbit")
  205.  
  206. plt.subplot(2, 3, 2)
  207. plt.plot(X45[:nstep,0], X45[:nstep,1])
  208. plt.title("RK45 x, y orbit")
  209.  
  210. if not vary:
  211.     plt.subplot(2, 3, 4)
  212.     plt.plot(X4[:nstep,0] - X45[:nstep,0])
  213.     plt.plot(X4[:nstep,1] - X45[:nstep,1])
  214.     plt.title("RK4-RK45 diff. x, y")
  215.  
  216. plt.subplot(2, 3, 5)
  217. plt.plot(s[:nstep])
  218. plt.title("RK45 s, vari = " + str(vary))
  219.  
  220. if vary:
  221.     plt.subplot(2, 3, 6)
  222.     plt.plot(T45[1:nstep]-T45[:nstep-1])
  223.     plt.title("RK45 dT, vari = " + str(vary))
  224.  
  225. plt.show()
  226.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement