Guest User

Untitled

a guest
May 23rd, 2018
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.60 KB | None | 0 0
  1. #!/usr/bin/env python
  2. """
  3. Find the solution for the second order differential equation
  4.  
  5. u'' = -u
  6.  
  7. with u(0) = 10 and u'(0) = -5
  8.  
  9. using the Euler and the Runge-Kutta methods.
  10.  
  11. This works by splitting the problem into 2 first order differential equations
  12.  
  13. u' = v
  14. v' = f(t,u)
  15.  
  16. with u(0) = 10 and v(0) = -5
  17.  
  18. """
  19.  
  20. from math import cos, sin
  21.  
  22. def f(t, u):
  23. return -u
  24.  
  25. def exact(u0, du0, t):
  26. # analytical solution
  27. return u0 * cos(t) + du0 * sin(t)
  28.  
  29. def iterate(func, u, v, tmax, n):
  30. dt = tmax/(n-1)
  31. t = 0.0
  32.  
  33. for i in range(n):
  34. u,v = func(u,v,t,dt)
  35. t += dt
  36.  
  37. return u
  38.  
  39. def euler_iter(u, v, t, dt):
  40. v_new = v + dt * f(t, u)
  41. u_new = u + dt * v
  42. return u_new, v_new
  43.  
  44. def rk_iter(u, v, t, dt):
  45. k1 = f(t,u)
  46. k2 = f(t+dt*0.5,u+k1*0.5*dt)
  47. k3 = f(t+dt*0.5,u+k2*0.5*dt)
  48. k4 = f(t+dt,u+k3*dt)
  49.  
  50. v += dt * (k1+2*k2+2*k3+k4)/6
  51.  
  52. # v doesn't explicitly depend on other variables
  53. k1 = k2 = k3 = k4 = v
  54.  
  55. u += dt * (k1+2*k2+2*k3+k4)/6
  56.  
  57. return u,v
  58.  
  59. euler = lambda u, v, tmax, n: iterate(euler_iter, u, v, tmax, n)
  60. runge_kutta = lambda u, v, tmax, n: iterate(rk_iter, u, v, tmax, n)
  61.  
  62. def plot_result(u, v, tmax, n):
  63. dt = tmax/(n-1)
  64. t = 0.0
  65. allt = []
  66. error_euler = []
  67. error_rk = []
  68. r_exact = []
  69. r_euler = []
  70. r_rk = []
  71.  
  72. u0 = u_euler = u_rk = u
  73. v0 = v_euler = v_rk = v
  74.  
  75. for i in range(n):
  76. u = exact(u0, v0, t)
  77. u_euler, v_euler = euler_iter(u_euler, v_euler, t, dt)
  78. u_rk, v_rk = rk_iter(u_rk, v_rk, t, dt)
  79. allt.append(t)
  80. error_euler.append(abs(u_euler-u))
  81. error_rk.append(abs(u_rk-u))
  82. r_exact.append(u)
  83. r_euler.append(u_euler)
  84. r_rk.append(u_rk)
  85. t += dt
  86.  
  87. _plot("error.png", "Error", "time t", "error e", allt, error_euler, error_rk)
  88. #_plot("result.png", "Result", "time t", "u(t)", allt, r_euler, r_rk, r_exact)
  89.  
  90. def _plot(out, title, xlabel, ylabel, allt, euler, rk, exact=None):
  91. import matplotlib.pyplot as plt
  92.  
  93. plt.title(title)
  94.  
  95. plt.ylabel(ylabel)
  96. plt.xlabel(xlabel)
  97.  
  98. plt.plot(allt, euler, 'b-', label="Euler")
  99. plt.plot(allt, rk, 'r--', label="Runge-Kutta")
  100.  
  101. if exact:
  102. plt.plot(allt, exact, 'g.', label='Exact')
  103.  
  104. plt.legend(loc=4)
  105. plt.grid(True)
  106.  
  107. plt.savefig(out, dpi=None, facecolor='w', edgecolor='w',
  108. orientation='portrait', papertype=None, format=None,
  109. transparent=False)
  110.  
  111. u0 = 10
  112. du0 = v0 = -5
  113. tmax = 10.0
  114. n = 2000
  115.  
  116. print "t=", tmax
  117. print "euler =", euler(u0, v0, tmax, n)
  118. print "runge_kutta=", runge_kutta(u0, v0, tmax, n)
  119. print "exact=", exact(u0, v0, tmax)
  120.  
  121. plot_result(u0, v0, tmax*2, n*2)
Add Comment
Please, Sign In to add comment