[关闭]
@zy-0815 2016-10-16T15:30:11.000000Z 字数 6593 阅读 1017

计算物理第五次作业

计算物理


摘要

本次作业主要解决Exercises 2.7的相关问题,即在课本得出Figure 1.4 的基础上,考虑两种模型,即绝热(adiabatic)和等温(isothermal)模型条件下的炮弹运动轨迹,并进一步在引入地表温度变量的情况下,得到更加真实的运动轨迹。

背景介绍

经过上次课程和相关作业的练习,我们初步掌握了欧勒法(Euler Method)的使用。但很显然,在实际应用中,我们之前掌握的欧勒法存在不足,如课本Figure 2.1所示,毕竟是一个理想模型,在解决实际问题的时候会得到背离日常经验的结论。因此下一步的工作便是考虑各种外界因素对物体运动的影响,并随之更改欧勒法的方程,使之得到更为贴合实际的运动轨迹。

正文

1. 经过课上的学习,我们可以通过下面的程序,得到Figure 1.4的运动轨迹

  1. import pylab as pl
  2. import math
  3. class cannon :
  4. def __init__(self,i=0,air_resistance=0.00004,power=10,mass = 1,time_step=0.1,\
  5. total_time=10, initial_velocity=50,initial_x=0,initial_y=0,\
  6. initial_velocity_x=50*math.cos(math.pi/4),\
  7. initial_velocity_y=50*math.sin(math.pi/4)):
  8. self.x = [initial_x]
  9. self.y = [initial_y]
  10. self.vx = [initial_velocity_x]
  11. self.vy = [initial_velocity_y]
  12. self.v = [initial_velocity]
  13. self.t = [0]
  14. self.m = mass
  15. self.p = power
  16. self.B_2 = air_resistance
  17. self.dt = time_step
  18. self.time = total_time
  19. def run(self):
  20. _time = 0
  21. while(_time < self.time):
  22. self.x.append(self.x[-1] + self.vx[-1]*self.dt)
  23. self.y.append(self.y[-1] + self.vy[-1]*self.dt)
  24. self.v.append(math.sqrt(self.vx[-1]*self.vx[-1] + self.vy[-1]*self.vy[-1]))
  25. self.vx.append(self.vx[-1] - self.dt *(self.B_2 / self.m) *\
  26. self.v[-1] * self.vx[-1])
  27. self.vy.append(self.vy[-1] - 9.8*self.dt - self.dt *(self.B_2 / self.m) *\
  28. self.v[-1] * self.vx[-1])
  29. self.t.append(_time)
  30. _time += self.dt
  31. def show_results(self):
  32. pl.plot(self.x,self.y)
  33. pl.ylim(0,)
  34. pl.xlabel('X')
  35. pl.ylabel('Y')
  36. pl.show()
  37. a = cannon()
  38. a.run()
  39. a.show_results()

可以通过改变程序中的出射角,从而得到一系列轨迹,最终结果如下:
image_1av71nhea1dupldm49mg681k8p5v.png-45.7kB
下面开始考虑实际情况
(2)首先考虑等温模型,我们有公式:


又因为考虑空气密度变化之后存在

故而我们将此前的公式做如下变换:

以上,得到了x方向速度的修正函数,其中,y方向同理可写出:

于是我们可以修改程序如下,但为了便于比较,此处只给出=45°时的轨迹

  1. import pylab as pl
  2. import math
  3. class cannon :
  4. def __init__(self,i=0,air_resistance=0.00004,power=10,mass = 1,time_step=0.1,\
  5. total_time=10, initial_velocity=50,initial_x=0,initial_y=0,\
  6. initial_velocity_x=50*math.cos(math.pi/4),\
  7. initial_velocity_y=50*math.sin(math.pi/4)):
  8. self.x = [initial_x]
  9. self.y = [initial_y]
  10. self.vx = [initial_velocity_x]
  11. self.vy = [initial_velocity_y]
  12. self.v = [initial_velocity]
  13. self.t = [0]
  14. self.m = mass
  15. self.p = power
  16. self.B_2 = air_resistance
  17. self.dt = time_step
  18. self.time = total_time
  19. def run(self):
  20. _time = 0
  21. while(_time < self.time):
  22. self.x.append(self.x[-1] + self.vx[-1]*self.dt)
  23. self.y.append(self.y[-1] + self.vy[-1]*self.dt)
  24. self.v.append(math.sqrt(self.vx[-1]*self.vx[-1] + self.vy[-1]*self.vy[-1]))
  25. self.vx.append(self.vx[-1] - self.dt *(self.y[-1]/10000)*(self.B_2 / self.m) *\
  26. self.v[-1] * self.vx[-1])
  27. self.vy.append(self.vy[-1] - 9.8*self.dt - self.dt *(self.y[-1]/10000)*(self.B_2 / self.m) *\
  28. self.v[-1] * self.vx[-1])
  29. self.t.append(_time)
  30. _time += self.dt
  31. def show_results(self):
  32. pl.plot(self.x,self.y,'b')
  33. pl.ylim(0,)
  34. pl.xlabel('X')
  35. pl.ylabel('Y')
  36. pl.show()
  37. a = cannon()
  38. a.run()
  39. a.show_results()

此时我们可得轨迹:
image_1av71is8jq9tkis1a3rovg1frp5i.png-38.3kB
考虑等温模型后的轨迹,可见比之前要略远一点。
3.那么,当我们使用绝热模型时又会有哪些不同?
我们已知绝热模型下


其中,类似上一问的讨论,我们很快写出此时的方程如下:

此时我们将程序进一步改写,得到:

  1. import pylab as pl
  2. import math
  3. class cannon :
  4. def __init__(self,i=0,air_resistance=0.00004,power=10,mass = 1,time_step=0.1,\
  5. total_time=10, initial_velocity=50,initial_x=0,initial_y=0,\
  6. initial_velocity_x=50*math.cos(math.pi/4),\
  7. initial_velocity_y=50*math.sin(math.pi/4)):
  8. self.x = [initial_x]
  9. self.y = [initial_y]
  10. self.vx = [initial_velocity_x]
  11. self.vy = [initial_velocity_y]
  12. self.v = [initial_velocity]
  13. self.t = [0]
  14. self.m = mass
  15. self.p = power
  16. self.B_2 = air_resistance
  17. self.dt = time_step
  18. self.time = total_time
  19. def run(self):
  20. _time = 0
  21. while(_time < self.time):
  22. self.x.append(self.x[-1] + self.vx[-1]*self.dt)
  23. self.y.append(self.y[-1] + self.vy[-1]*self.dt)
  24. self.v.append(math.sqrt(self.vx[-1]*self.vx[-1] + self.vy[-1]*self.vy[-1]))
  25. self.vx.append(self.vx[-1] - self.dt *pow((1-(0.0065*self.y[-1])/300),2.5)*\
  26. (self.B_2 / self.m) *self.v[-1] * self.vx[-1])
  27. self.vy.append(self.vy[-1] - 9.8*self.dt - self.dt *\
  28. pow((1-(0.0065*self.y[-1])/300),2.5)*(self.B_2 / self.m) *\
  29. self.v[-1] * self.vx[-1])
  30. self.t.append(_time)
  31. _time += self.dt
  32. def show_results(self):
  33. pl.plot(self.x,self.y,'g')
  34. pl.ylim(0,)
  35. pl.xlabel('X')
  36. pl.ylabel('Y')
  37. pl.show()
  38. a = cannon()
  39. a.run()
  40. a.show_results()

得到如下图像,发现与不考虑空气密度情况的差别很小,几乎看不出来(关于此处差异如此之小后面会有进一步讨论):
image_1av71ffi3qu212du11tm1047iao55.png-36kB

4.在此基础上(绝热模型),我们继续考虑地表温差造成的影响,我们有:来取代公式中的,因此模型可以进一步写成如下形式:


我们可以进一步更改程序如下:

  1. import pylab as pl
  2. import math
  3. class cannon :
  4. def __init__(self,i=0,air_resistance=0.00004,power=10,mass = 1,time_step=0.1,\
  5. total_time=10, initial_velocity=50,initial_x=0,initial_y=0,\
  6. initial_velocity_x=50*math.cos(math.pi/4),\
  7. initial_velocity_y=50*math.sin(math.pi/4)):
  8. self.x = [initial_x]
  9. self.y = [initial_y]
  10. self.vx = [initial_velocity_x]
  11. self.vy = [initial_velocity_y]
  12. self.v = [initial_velocity]
  13. self.t = [0]
  14. self.m = mass
  15. self.p = power
  16. self.B_2 = air_resistance
  17. self.dt = time_step
  18. self.time = total_time
  19. def run(self):
  20. _time = 0
  21. while(_time < self.time):
  22. self.x.append(self.x[-1] + self.vx[-1]*self.dt)
  23. self.y.append(self.y[-1] + self.vy[-1]*self.dt)
  24. self.v.append(math.sqrt(self.vx[-1]*self.vx[-1] + self.vy[-1]*self.vy[-1]))
  25. self.vx.append(self.vx[-1] - self.dt *pow((1-(0.0065*self.y[-1])/300),2.5)*\
  26. (self.B_2 / self.m)*pow((263/300),2.5) *self.v[-1] * self.vx[-1])
  27. self.vy.append(self.vy[-1] - 9.8*self.dt - self.dt *\
  28. pow((1-(0.0065*self.y[-1])/300),2.5)*(self.B_2 / self.m) *pow((263/300),2.5)*\
  29. self.v[-1] * self.vx[-1])
  30. self.t.append(_time)
  31. _time += self.dt
  32. def show_results(self):
  33. pl.plot(self.x,self.y,'y')
  34. pl.ylim(0,)
  35. pl.xlabel('X')
  36. pl.ylabel('Y')
  37. pl.show()
  38. a = cannon()
  39. a.run()
  40. a.show_results()

得到如下图像:
image_1av717uod59211q4rm1pfa3fd4o.png-38.5kB
其中黄线为此时轨迹,注此时取地表温度为-10℃ 即263K,蓝线依然为不考虑空气密度情况下的轨迹
5. 我们可以在此基础上更改初射角,得到一系列轨迹,同时又可改变地表温度,从而获得如下两组图像:
image_1av6vlble13nnj361np8bl114o12n.png-48.7kB
image_1av6vssg0lgr14ct15p6vj312gv3h.png-48.6kB
可见两组图有细微差别。

结论

我们可以通过对原有程序的修改,进一步得到更符合实际的运动轨迹,如上图。
反思:1.在写程序时遇到过如下问题,在此提出以防止日后再错,首先是用Python写程序时,尤其在打公式的时候,极容易犯错,在作业过程中多次出现如下提示image_1av6r9forbc41fuh1p60hdj8up2a.png-1.9kB
其实就是忘记在v的后面注明v[-1],诸如此类,所以可以考虑现在纸上将其写清楚再编辑。
   2.轨迹图像差异过小导致无法明显看出差异,其实可以更改系数的数值,在以上程序中,我们采用的是书中提出的数值,为,当我们将其改为,则结果会有明显不同,以最后两组图为例,我们可以得到修改后的图像如下:
image_1av703bfo1eubqmu1kod18ba14cs4b.png-48.7kB
image_1av6vv6u7i2p140h189k1qj7l893u.png-44.8kB
这样我们得到的差别就很明显了

致谢

老师的PPT:Chapter 2 Realistic Projectile Motion和Matplotlib Tutorial。
张梓桐同学帮忙指出之前提到的小错误。

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