[关闭]
@Guozhongzhi 2016-10-16T10:40:40.000000Z 字数 4160 阅读 879

第五次作业

计算物理 郭忠智2014301020087


一、摘要

本次作业完成了计算物理课本上第二章炮弹发射抛物线运动的近似计算,用Euler Method进行数值近似运算,并用解析的方法求得常微分方程的解析解,将两种方法所得的结果画图、以及计算出物体的落地点水平位移及最大高度,将之进行比较,可以看到,用Euler Method可以求得较好的近似结果。

二、背景

2.6 Use the Euler Method to calculate cannon shell trajectories ignoring both air drag and the effect of air density(actually,ignoring the former automatically rules out the latter).Compare your results with those in Figure 2.4,and with the exact solution.

三、正文

(一)题目相当于解常微分方程:



引入速度有:


应用欧拉方法,得到:


用解析的求法得到(1)和(2)的解析解为:


(二)用Python编写代码,计算欧拉方法给出的结果:

  1. import numpy
  2. import math
  3. import pylab as pl
  4. class cannon_shell:
  5. def __init__(self, x_0, y_0, initial_velocity, theta_0, \
  6. time_step, total_time):
  7. self.theta = theta_0
  8. self.x = [x_0]
  9. self.y = [y_0]
  10. self.v_x = [math.cos(theta_0 * math.pi / 180) * initial_velocity]
  11. self.v_y = [math.sin(theta_0 * math.pi / 180) * initial_velocity]
  12. self.g = 9.8
  13. self.dt = time_step
  14. self.time = total_time
  15. def run(self):
  16. for i in range(self.time):
  17. self.v_x.append(self.v_x[i])
  18. self.x.append(self.x[i] + self.dt * self.v_x[i])
  19. self.v_y.append(self.v_y[i] - self.g * self.dt)
  20. self.y.append(self.y[i] + self.dt * self.v_y[i])
  21. if self.y[i] >= 0 and self.y[i + 1] <= 0:
  22. break
  23. r = - self.y[-2] / self.y[-1]
  24. self.x[-1] = (self.x[-2] + r * self.x[-1]) / (r + 1)
  25. for j in range(len(self.x)):
  26. self.x[j] = self.x[j] / 1000
  27. for j in range(len(self.y)):
  28. self.y[j] = self.y[j] / 1000
  29. print "在初射角为", str(self.theta), "度时:"
  30. print "炮弹在水平方向的位移为:", self.x[-1], 'km'
  31. print "炮弹在竖直方向的最大高度为:", max(self.y), 'km'
  32. def show_results(self):
  33. font = {'family': 'serif',
  34. 'color': 'darkred',
  35. 'weight': 'normal',
  36. 'size': 16,
  37. }
  38. pl.plot(self.x, self.y)
  39. pl.title('Trajectory of cannon shell', fontdict = font)
  40. pl.ylim(0, 20)
  41. pl.xlabel('x ($km$)')
  42. pl.ylabel('y ($km$)')
  43. pl.text(self.x[450], self.y[500],\
  44. str(self.theta) +'$\degree$', fontdict = font)
  45. pl.text(35, 18,\
  46. 'Euler Method', fontdict = font)
  47. a = cannon_shell(0 , 0, 700, 30, 0.1, 1500)
  48. a.run()
  49. a.show_results()
  50. a = cannon_shell(0 , 0, 700, 35, 0.1, 1500)
  51. a.run()
  52. a.show_results()
  53. a = cannon_shell(0 , 0, 700, 40, 0.1, 1500)
  54. a.run()
  55. a.show_results()
  56. a = cannon_shell(0 , 0, 700, 45, 0.1, 1500)
  57. a.run()
  58. a.show_results()
  59. a = cannon_shell(0 , 0, 700, 50, 0.1, 1500)
  60. a.run()
  61. a.show_results()
  62. a = cannon_shell(0 , 0, 700, 55, 0.1, 1500)
  63. a.run()
  64. a.show_results()
  65. pl.show()

Python编写代码,给出解析解的计算结果,代码如下:

  1. #exact solution
  2. class exact_solution:
  3. def __init__(self, x_0, y_0, initial_velocity, theta_0):
  4. self.theta = theta_0
  5. self.x = [x_0]
  6. self.y = [y_0]
  7. self.v_x = math.cos(theta_0 * math.pi / 180) * initial_velocity
  8. self.v_y = math.sin(theta_0 * math.pi / 180) * initial_velocity
  9. self.t = numpy.linspace(0, 150)
  10. def run(self):
  11. for i in self.t:
  12. self.x.append(exact_solution.xshift(self, i))
  13. self.y.append(exact_solution.yshift(self, i))
  14. r = - self.y[-2] / self.y[-1]
  15. self.x[-1] = (self.x[-2] + r * self.x[-1]) / (r + 1)
  16. for j in range(len(self.x)):
  17. self.x[j] = self.x[j] / 1000
  18. for j in range(len(self.y)):
  19. self.y[j] = self.y[j] / 1000
  20. print "在初射角为", str(self.theta), "度时:"
  21. print "炮弹在水平方向的位移为:", self.x[-1], 'km'
  22. print "炮弹在竖直方向的最大高度为:", max(self.y), 'km'
  23. def show_results(self):
  24. font = {'family': 'serif',
  25. 'color': 'darkred',
  26. 'weight': 'normal',
  27. 'size': 16,
  28. }
  29. pl.plot(self.x, self.y)
  30. pl.title('Trajectory of cannon shell', fontdict = font)
  31. pl.ylim(0, 20)
  32. pl.xlim(0, 60)
  33. pl.xlabel('x ($km$)')
  34. pl.ylabel('y ($km$)')
  35. pl.text(self.x[15], self.y[15],\
  36. str(self.theta) +'$\degree$', fontdict = font)
  37. pl.text(35, 18,\
  38. 'Exact Solution', fontdict = font)
  39. def xshift(self, t):
  40. return self.v_x * t + self.x[0]
  41. def yshift(self, t):
  42. return -(9.8 * t ** 2) / 2 + self.v_y * t + self.y[0]
  43. b = exact_solution(0, 0, 700, 30)
  44. b.run()
  45. b.show_results()
  46. b = exact_solution(0, 0, 700, 35)
  47. b.run()
  48. b.show_results()
  49. b = exact_solution(0, 0, 700, 40)
  50. b.run()
  51. b.show_results()
  52. b = exact_solution(0, 0, 700, 45)
  53. b.run()
  54. b.show_results()
  55. b = exact_solution(0, 0, 700, 50)
  56. b.run()
  57. b.show_results()
  58. b = exact_solution(0, 0, 700, 55)
  59. b.run()
  60. b.show_results()
  61. pl.show()

四、结论

欧拉方法给出的结果如下:
2 6
problem2 6euler method
用解析解计算,得到的结果如下:
2 6

problem2 6exact solution
可以得到两种方法得到的水平位移结果对比:

初射角度 欧拉方法 精确解
30 43.3618746816 km 43.2838451308 km
35 47.0419549851 km 46.972669456 km
40 49.2939993236 km 49.240204593 km
45 50.0494911508 km 49.999920421 km
50 49.2853734504 km 49.2330367646 km
55 47.024775564 km 46.9790669971 km

可以看到用两种方法得到的结果有一定误差,这是用数值算法的必然结果,可以根据实际需要,进行数据的取舍,如果对所考虑问题的精度造成的影响不大,则可以选择欧拉方法进行近似计算。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注