![](/img/trans.png)
[英]solve ordinary differential equation with time dependent coefficients in python (odeint)
[英]Ordinary differential equation - Odeint with unknown initial value in python, jupyter
我正在嘗試用 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 將不起作用。 我該怎么辦? 當我知道如何繼續時,我將迭代錯誤。
你有以下形式的問題,你知道posA
和posB
,以及長度約束v0
為velA
。 從A
到B
的時間是未知的。 您有一個函數derivs
(在您的情況下保持通用,或nodrag
)來根據物理原理計算pos
和vel
的組合狀態的導數。
有了這個,您可以在區間 [0,1] 上設置邊界值求解器,使用參數T
進行縮放以獲得具有可變端點的實際區間 [0,T]。 因此,如果u(s)=y(T*s)
導數是u'(s)=T*y'(T*s)=T*derivs(T*s,u(s))
。
def bvp_ode(s,u,T): return T*np.asarray(derivs(s*T,u))
def bvp_bc(uA,uB,T):
pA, vA=uA[:3],uA[3:] # or uA[0::2],uA[1::2]
pB, vB=uB[:3],uB[3:] # or uB[0::2],uB[1::2]
return np.concatenate(pA-posA, pB-posB, [sum(velA**2)-v0**2])
s_init = [0,1]
u_init = np.asarray([np.concatenate(pos,[0,0,0]) for pos in (posA, posB) ]).T
T = 100 # or dist(posA,posB)/v0
res = solve_bvp(bvp_ode, bvp_bc, s_init, u_init, p=[T])
print(res.message)
T=res.p[0]
velA = res.y[3:,0]
print("T=",T,", velA=",velA)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.