@zy-0815
2016-10-16T23:30:11.000000Z
字数 6593
阅读 1118
计算物理
本次作业主要解决Exercises 2.7的相关问题,即在课本得出Figure 1.4 的基础上,考虑两种模型,即绝热(adiabatic)和等温(isothermal)模型条件下的炮弹运动轨迹,并进一步在引入地表温度变量的情况下,得到更加真实的运动轨迹。
经过上次课程和相关作业的练习,我们初步掌握了欧勒法(Euler Method)的使用。但很显然,在实际应用中,我们之前掌握的欧勒法存在不足,如课本Figure 2.1所示,毕竟是一个理想模型,在解决实际问题的时候会得到背离日常经验的结论。因此下一步的工作便是考虑各种外界因素对物体运动的影响,并随之更改欧勒法的方程,使之得到更为贴合实际的运动轨迹。
1. 经过课上的学习,我们可以通过下面的程序,得到Figure 1.4的运动轨迹
import pylab as pl
import math
class cannon :
def __init__(self,i=0,air_resistance=0.00004,power=10,mass = 1,time_step=0.1,\
total_time=10, initial_velocity=50,initial_x=0,initial_y=0,\
initial_velocity_x=50*math.cos(math.pi/4),\
initial_velocity_y=50*math.sin(math.pi/4)):
self.x = [initial_x]
self.y = [initial_y]
self.vx = [initial_velocity_x]
self.vy = [initial_velocity_y]
self.v = [initial_velocity]
self.t = [0]
self.m = mass
self.p = power
self.B_2 = air_resistance
self.dt = time_step
self.time = total_time
def run(self):
_time = 0
while(_time < self.time):
self.x.append(self.x[-1] + self.vx[-1]*self.dt)
self.y.append(self.y[-1] + self.vy[-1]*self.dt)
self.v.append(math.sqrt(self.vx[-1]*self.vx[-1] + self.vy[-1]*self.vy[-1]))
self.vx.append(self.vx[-1] - self.dt *(self.B_2 / self.m) *\
self.v[-1] * self.vx[-1])
self.vy.append(self.vy[-1] - 9.8*self.dt - self.dt *(self.B_2 / self.m) *\
self.v[-1] * self.vx[-1])
self.t.append(_time)
_time += self.dt
def show_results(self):
pl.plot(self.x,self.y)
pl.ylim(0,)
pl.xlabel('X')
pl.ylabel('Y')
pl.show()
a = cannon()
a.run()
a.show_results()
可以通过改变程序中的出射角,从而得到一系列轨迹,最终结果如下:
下面开始考虑实际情况
(2)首先考虑等温模型,我们有公式:
import pylab as pl
import math
class cannon :
def __init__(self,i=0,air_resistance=0.00004,power=10,mass = 1,time_step=0.1,\
total_time=10, initial_velocity=50,initial_x=0,initial_y=0,\
initial_velocity_x=50*math.cos(math.pi/4),\
initial_velocity_y=50*math.sin(math.pi/4)):
self.x = [initial_x]
self.y = [initial_y]
self.vx = [initial_velocity_x]
self.vy = [initial_velocity_y]
self.v = [initial_velocity]
self.t = [0]
self.m = mass
self.p = power
self.B_2 = air_resistance
self.dt = time_step
self.time = total_time
def run(self):
_time = 0
while(_time < self.time):
self.x.append(self.x[-1] + self.vx[-1]*self.dt)
self.y.append(self.y[-1] + self.vy[-1]*self.dt)
self.v.append(math.sqrt(self.vx[-1]*self.vx[-1] + self.vy[-1]*self.vy[-1]))
self.vx.append(self.vx[-1] - self.dt *(self.y[-1]/10000)*(self.B_2 / self.m) *\
self.v[-1] * self.vx[-1])
self.vy.append(self.vy[-1] - 9.8*self.dt - self.dt *(self.y[-1]/10000)*(self.B_2 / self.m) *\
self.v[-1] * self.vx[-1])
self.t.append(_time)
_time += self.dt
def show_results(self):
pl.plot(self.x,self.y,'b')
pl.ylim(0,)
pl.xlabel('X')
pl.ylabel('Y')
pl.show()
a = cannon()
a.run()
a.show_results()
此时我们可得轨迹:
考虑等温模型后的轨迹,可见比之前要略远一点。
3.那么,当我们使用绝热模型时又会有哪些不同?
我们已知绝热模型下
import pylab as pl
import math
class cannon :
def __init__(self,i=0,air_resistance=0.00004,power=10,mass = 1,time_step=0.1,\
total_time=10, initial_velocity=50,initial_x=0,initial_y=0,\
initial_velocity_x=50*math.cos(math.pi/4),\
initial_velocity_y=50*math.sin(math.pi/4)):
self.x = [initial_x]
self.y = [initial_y]
self.vx = [initial_velocity_x]
self.vy = [initial_velocity_y]
self.v = [initial_velocity]
self.t = [0]
self.m = mass
self.p = power
self.B_2 = air_resistance
self.dt = time_step
self.time = total_time
def run(self):
_time = 0
while(_time < self.time):
self.x.append(self.x[-1] + self.vx[-1]*self.dt)
self.y.append(self.y[-1] + self.vy[-1]*self.dt)
self.v.append(math.sqrt(self.vx[-1]*self.vx[-1] + self.vy[-1]*self.vy[-1]))
self.vx.append(self.vx[-1] - self.dt *pow((1-(0.0065*self.y[-1])/300),2.5)*\
(self.B_2 / self.m) *self.v[-1] * self.vx[-1])
self.vy.append(self.vy[-1] - 9.8*self.dt - self.dt *\
pow((1-(0.0065*self.y[-1])/300),2.5)*(self.B_2 / self.m) *\
self.v[-1] * self.vx[-1])
self.t.append(_time)
_time += self.dt
def show_results(self):
pl.plot(self.x,self.y,'g')
pl.ylim(0,)
pl.xlabel('X')
pl.ylabel('Y')
pl.show()
a = cannon()
a.run()
a.show_results()
得到如下图像,发现与不考虑空气密度情况的差别很小,几乎看不出来(关于此处差异如此之小后面会有进一步讨论):
4.在此基础上(绝热模型),我们继续考虑地表温差造成的影响,我们有:来取代公式中的,因此模型可以进一步写成如下形式:
import pylab as pl
import math
class cannon :
def __init__(self,i=0,air_resistance=0.00004,power=10,mass = 1,time_step=0.1,\
total_time=10, initial_velocity=50,initial_x=0,initial_y=0,\
initial_velocity_x=50*math.cos(math.pi/4),\
initial_velocity_y=50*math.sin(math.pi/4)):
self.x = [initial_x]
self.y = [initial_y]
self.vx = [initial_velocity_x]
self.vy = [initial_velocity_y]
self.v = [initial_velocity]
self.t = [0]
self.m = mass
self.p = power
self.B_2 = air_resistance
self.dt = time_step
self.time = total_time
def run(self):
_time = 0
while(_time < self.time):
self.x.append(self.x[-1] + self.vx[-1]*self.dt)
self.y.append(self.y[-1] + self.vy[-1]*self.dt)
self.v.append(math.sqrt(self.vx[-1]*self.vx[-1] + self.vy[-1]*self.vy[-1]))
self.vx.append(self.vx[-1] - self.dt *pow((1-(0.0065*self.y[-1])/300),2.5)*\
(self.B_2 / self.m)*pow((263/300),2.5) *self.v[-1] * self.vx[-1])
self.vy.append(self.vy[-1] - 9.8*self.dt - self.dt *\
pow((1-(0.0065*self.y[-1])/300),2.5)*(self.B_2 / self.m) *pow((263/300),2.5)*\
self.v[-1] * self.vx[-1])
self.t.append(_time)
_time += self.dt
def show_results(self):
pl.plot(self.x,self.y,'y')
pl.ylim(0,)
pl.xlabel('X')
pl.ylabel('Y')
pl.show()
a = cannon()
a.run()
a.show_results()
得到如下图像:
其中黄线为此时轨迹,注此时取地表温度为-10℃ 即263K,蓝线依然为不考虑空气密度情况下的轨迹
5. 我们可以在此基础上更改初射角,得到一系列轨迹,同时又可改变地表温度,从而获得如下两组图像:
可见两组图有细微差别。
我们可以通过对原有程序的修改,进一步得到更符合实际的运动轨迹,如上图。
反思:1.在写程序时遇到过如下问题,在此提出以防止日后再错,首先是用Python写程序时,尤其在打公式的时候,极容易犯错,在作业过程中多次出现如下提示
其实就是忘记在v的后面注明v[-1],诸如此类,所以可以考虑现在纸上将其写清楚再编辑。
2.轨迹图像差异过小导致无法明显看出差异,其实可以更改系数的数值,在以上程序中,我们采用的是书中提出的数值,为,当我们将其改为,则结果会有明显不同,以最后两组图为例,我们可以得到修改后的图像如下:
这样我们得到的差别就很明显了
老师的PPT:Chapter 2 Realistic Projectile Motion和Matplotlib Tutorial。
张梓桐同学帮忙指出之前提到的小错误。