我正在尝试用python中的odeint解决ODE。我正在做一个物理项目。 我的目标是当我把物质的速度,我的位置,着陆点放进去时,在球坐标系中计算轨迹的方向和角度。
例如,当我输入参数-800m / s时,(S50°E135°)(我的位置),向南10公里(着陆点)。然后结果像这样-射击180°(向北0°),海拔37°。
我可以在知道初始值时计算轨迹,可以计算结果及其轨迹,但是我不知道该怎么做才能完成我的对象。
G=6.673*10**(-11) # gravity constant
M=5.972*10**(24) # mass of earth
R=6374916 # radius of earth
w=7.3*10**-5 # angular velocity of earth's ratation
L=np.pi*7/9 # my longitude
l=float(input('Input your latitude(-90~90):'))
m=float(input('Input direction(0~360):'))
d=float(input('How far do you want to fire?(In meter):'))
v=int(input('How fast your matter?(In m/s):'))
dt=l+d*np.sin(m/180*np.pi)/R #target latitude
dp=L+d*np.cos(m/180*np.pi)/R #target longitude
Enter some parameter so far
def nodrag(y,t):
dydt0=y[1]
dydt1=y[0]*(y[3]**2)+y[0]*(y[5]**2)*(np.sin(y[2])**2)-G*M/(y[0]**2)
dydt2=y[3]
dydt3=-2*y[1]/y[0]*y[3]+(y[5]**2)*np.sin(y[2])*np.cos(y[2])
dydt4=y[5]
dydt5=-2*y[1]/y[0]*y[5]-2*y[3]*y[5]*np.cos(y[2])/np.sin(y[2])
return [dydt0,dydt1,dydt2,dydt3,dydt4,dydt5]
rlist=[]
thlist=[]
pilist=[]
ddp=[]
def ODE(azimuth,angle):
yini=np.array([R,v*np.sin(angle),np.pi/2-l*np.pi/180,-v*np.cos(angle)*np.cos(azimuth)/R,np.pi*135/180,w+v*np.cos(angle)*np.sin(azimuth)/R])
t=np.linspace(0,v,v*1000)
result=odeint(nodrag,yini,t)
r=result[:,0] # value of radius
th=result[:,2] # value of theta
pi=result[:,4] # value of pi
rr=list(r)
tt=list(th)
pp=list(pi) # change array to list
for i in range (1,v*1000):
if rr[i]<R:
number=i
break # find time when it reach r=R again
for i in range (number,v*1000):
tt.pop(-1)
pp.pop(-1) # remove extra
thlist.append(tt[-1])
pilist.append(pp[-1]) # save last values (r=R)
move=dp+w*t[number] # displacement of landing point of pi because of rotation of the earth
ddp.append(move)
So far soving ODE,my next part is brute force
min=np.pi*2
for i in range (0,360):
i=i/180*np.pi
for j in range (0,91):
j=j/180*np.pi
ODE(i,j) #calculate all directions
for k in range (0,32760):
compare=np.arccos(np.sin(dt)*np.sin(thlist[k])*np.cos(ddp[k]-pilist[k])+np.cos(dt)*np.cos(thlist[k]))
if compare<=min:
min=compare
azi=k//360
ang=k-azi*360
此代码效率很低。大约需要40分钟
这是我的代码示例-当我输入一些初始值时。 但是如果我在初始值中输入未知值,则odeint无法正常工作。我该怎么办? 当我知道如何继续时,我将遍历该错误。