常微分方程-python中初始值未知的Odeint,jupyter

常微分方程-python中初始值未知的Odeint,jupyter,python,jupyter-notebook,ode,odeint,Python,Jupyter Notebook,Ode,Odeint,我正在尝试用python中的odeint解决ODE。我在做一个物理项目。 我的目标是在球坐标系下计算出轨道的方向和角度,当我计算出物质的速度、位置和着陆点时 例如,当我将参数-800m/s,(S50°E135°)(我的位置)设置为向南10km(着陆点)。然后结果是这样的-拍摄180°(0°为北),海拔37° 当我知道初始值时,我可以计算轨迹,我可以计算结果和它的轨迹,但我不知道如何完成我的目标 G=6.673*10**(-11) # gravity constant M=5.972*10**

我正在尝试用python中的odeint解决ODE。我在做一个物理项目。 我的目标是在球坐标系下计算出轨道的方向和角度,当我计算出物质的速度、位置和着陆点时

例如,当我将参数-800m/s,(S50°E135°)(我的位置)设置为向南10km(着陆点)。然后结果是这样的-拍摄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
min=np.pi*2
对于范围(0360)内的i:
i=i/180*np.pi
对于范围(0,91)内的j:
j=j/180*np.pi
ODE(i,j)#计算所有方向
对于范围内的k(032760):
比较=np.arccos(np.sin(dt)*np.sin(thlist[k])*np.cos(ddp[k]-pilist[k])+np.cos(dt)*np.cos(thlist[k]))

如果比较,您会遇到已知的
posA
posB
的形式问题,并且
velA
的长度限制
v0
。从
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):返回T*np.asarray(derivs(s*T,u))
def bvp_bc(uA、uB、T):
pA,vA=uA[:3],uA[3:]#或uA[0::2],uA[1::2]
pB,vB=uB[:3],uB[3:]#或uB[0::2],uB[1::2]
返回np.连接(pA posA,pB posB,[sum(velA**2)-v0**2])
s_init=[0,1]
u_init=np.asarray([np.concatenate(pos[0,0,0]),用于(posA,posB)].T中的pos
T=100#或距离(位置A、位置B)/v0
res=solve_bvp(bvp_ode,bvp_bc,s_init,u_init,p=[T])
打印(res.message)
T=res.p[0]
velA=res.y[3:0]
打印(“T=,T=,velA=,velA”)

使用函数scipy.optimize.fsolve解决此问题。初始条件和飞行时间的可变组件是变量,与目标的差异是要求解的函数的函数值。当然,您也可以使用边界值解算器,将飞行时间作为可变参数,并在标准间隔[0,1]上对时间进行参数化。谢谢Lutz博士!你能更具体地解释一下你的方法吗?我认为当我知道飞行时间时,你们的方法是有效的,但飞行时间取决于初始值。若这是一个平台轨道问题,我可以用方程计算飞行时间,但这是球形地面。我最近开始学习编码,所以我不擅长它。对不起,您可以更改代码,使其使用更具描述性的名称吗?或者记录$y$的组成部分是什么?在这种形式下,很难看出初始点的固定变量是什么。您还没有包括如何计算目标位置的坐标。我更改了代码。如果你有任何问题,请让我知道在这个代码-做s,u,T,velA平均半径,速度,时间,最终速度分别?另外,我想知道位置A,B的意思。我需要三个力的分量。或者这只是您的方法的一个示例?s是[0,1]中编码时间段[0,T]的参数。u(s)=y(sT)是轨迹的重新参数化。T是积分时间,最后是从地面到地面的时间。pos和vel是所选坐标系中的位置和速度,可以是笛卡尔坐标系或球面坐标系。代码中的力或加速度计算是不变的,除了组件重新排序以便于向量拆分。您好!很抱歉,我没有及时回复。我忙着为期末考试学习数学、物理。谢谢你们,我完成了我的代码和项目,并获得了一个等级!非常感谢你。祝你年终愉快!
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