求解轨道力学二体意义下的Lambert方程(兰伯特方程)的Fortran程序
轨道力学中二体问题下求解兰伯特方程。
老外写的Matlab程序,我把它转成了Fortran程序。
!*****************************************************************
subroutine solve_lambert(r1,r2,tt,GM,lw,N,nBranch,v1,v2)
implicit real(8)(A-H,O-Z)
dimension r1(3),r2(3),v1(3),v2(3),tmp3(3),wih(3),r1p(3),r2p(3)
external x2tof,fnorm
!This routine implements a new algorithm that solves Lambert's problem. The
!algorithm has two major characteristics that makes it favorable to other
!existing ones.
!
! 1) It describes the generic orbit solution of the boundary condition
! problem through the variable X=log(1+cos(alpha/2)). By doing so the
! graphs of the time of flight become defined in the entire real axis and
! resembles a straight line. Convergence is granted within few iterations
! for all the possible geometries (except, of course, when the transfer
! angle is zero). When multiple revolutions are considered the variable is
! X=tan(cos(alpha/2)*pi/2).
!
! 2) Once the orbit has been determined in the plane, this routine
! evaluates the velocity vectors at the two points in a way that is not
! singular for the transfer angle approaching to pi (Lagrange coefficient
! based methods are numerically not well suited for this purpose).
!
! As a result Lambert's problem is solved (with multiple revolutions
! being accounted for) with the same computational effort for all
! possible geometries. The case of near 180 transfers is also solved
! efficiently.
!
! We note here that even when the transfer angle is exactly equal to pi
! the algorithm does solve the problem in the plane (it finds X), but it
! is not able to evaluate the plane in which the orbit lies. A solution
! to this would be to provide the direction of the plane containing the
! transfer orbit from outside. This has not been implemented in this
! routine since such a direction would depend on which application the
! transfer is going to be used in.
!
!Usage: [v1,v2,a,p,theta,iter]=lambertI(r1,r2,t,GM,lw,N,nBranch)
!
!Inputs:
! r1=Position vector at departure (column,km)
! r2=Position vector at arrival (column, same units as r1,km)
! t=Transfer time (scalar,s)
! GM=gravitational parameter (scalar, units have to be
! consistent with r1,t units,km^3/s^2)
! lw=1 if long way is chosen
! nBranch='1' if the left nBranch is selected in a problem where N
! is not 0 (multirevolution)
! 天体运行是由分支.所以nBranch一般选择0
! N=number of revolutions
!
! 说明:当N~=0时,旋转方向不光用lw来控制还要先用nBranch来控制.
!Outputs:
! v1=Velocity at departure (consistent units)(km/s)
! v2=Velocity at arrival (km/s)
! iter=number of iteration made by the newton solver (usually 6)
!
! 当需要时可以加上.
!补充说明:
! [v1,v2,a,p,theta,iter]=lambertI(r1,r2,t,GM,lw,N,nBranch)
!nBranch=1!here 1 is represent left
!Preliminary control on the function call
pi = 3.141592653589793D0
if (tt<=0) then
v1=1/0D0
v2=1/0D0
return
end if
tol=1D-11 !Increasing the tolerance does not bring any advantage as the
!precision is usually greater anyway (due to the rectification of the tof
!graph) except near particular cases such as parabolas in which cases a
!lower precision allow for usual convergence.
!Non dimensional units
R=sqrt(r1(1)**2+r1(2)**2+r1(3)**2)
V=sqrt(GM/R)
T=R/V
!working with non-dimensional radii and time-of-flight
r1p=r1/R
r2p=r2/R
t=tt/T
!Evaluation of the relevant geometry parameters in non dimensional units
r2mod=sqrt(r2p(1)**2+r2p(2)**2+r2p(3)**2)
theta=acos((r1p(1)*r2p(1)+r1p(2)*r2p(2)+r1p(3)*r2p(3))/r2mod)
!close to pi and the acos function could return complex numbers
!计算夹角,并确定是大弧还是小弧.
if (lw>=1) theta=2*pi-theta
c=sqrt(1D0+r2mod**2-2D0*r2mod*cos(theta)) !non dimensional chord
s=(1D0+r2mod+c)/2D0 !non dimensional semi-perimeter
am=s/2D0 !minimum energy ellipse semi major axis
wlambda=sqrt(r2mod)*cos(theta/2D0)/s !lambda parameter defined in BATTIN's book
!We start finding the log(x+1) value of the solution conic:
!!NO MULTI REV --> (1 SOL)
if (N==0) then
winn1=-0.5233D0 !first guess point
winn2=0.5233D0 !second guess point
x1=log(1D0+winn1)
x2=log(1D0+winn2)
y1=log(x2tof(winn1*1D0,s,c,lw,N))-log(t)
y2=log(x2tof(winn2*1D0,s,c,lw,N))-log(t)
!Newton iterations
err=1
i=0
do while ((err>tol) .and. (y1/=y2))
i=i+1
xnew=(x1*y2-y1*x2)/(y2-y1)
ynew=log(x2tof(exp(xnew)-1,s,c,lw,N))-log(t)
x1=x2
y1=y2
x2=xnew
y2=ynew
err=abs(x1-xnew)
end do
iter=i
x=exp(xnew)-1
!!MULTI REV --> (2 SOL) SEPARATING RIGHT AND LEFT BRANCH
else
if (nBranch==1) then
winn1=-0.5234D0
winn2=-0.2234D0
else
winn1=0.2D0
winn2=0.5234D0
end if
x1=tan(winn1*pi/2)
x2=tan(winn2*pi/2)
y1=x2tof(winn1,s,c,lw,N)-t
y2=x2tof(winn2,s,c,lw,N)-t
err=1
i=0
!Newton Iteration
do while ((err>tol) .and. (i<90) .and. (y1/=y2))
i=i+1
xnew=(x1*y2-y1*x2)/(y2-y1)
ynew=x2tof(atan(xnew)*2/pi,s,c,lw,N)-t
x1=x2
y1=y2
x2=xnew
y2=ynew
err=abs(x1-xnew)
end do
x=atan(xnew)*2/pi
iter=i
end if
!The solution has been evaluated in terms of log(x+1) or tan(x*pi/2), we
!now need the conic. As for transfer angles near to pi the lagrange
!coefficient technique goes singular (dg approaches a zero/zero that is
!numerically bad) we here use a different technique for those cases. When
!the transfer angle is exactly equal to pi, then the wih unit vector is not
!determined. The remaining equations, though, are still valid.
a=am/(1-x**2) !solution semimajor axis
!calcolo psi
if (x<1D0) then !ellisse
beta=2D0*asin(sqrt((s-c)/2D0/a))
if (lw>=1) beta=-beta
alfa=2D0*acos(x)
psi=(alfa-beta)/2D0
eta2=2*a*sin(psi)**2/s
eta=sqrt(eta2)
else !iperbole
beta=2*asinh(sqrt((c-s)/2/a))
if (lw>=1) beta=-beta
alfa=2*acosh(x)
psi=(alfa-beta)/2
eta2=-2*a*sinh(psi)**2/s
eta=sqrt(eta2)
end if
p=r2mod/am/eta2*sin(theta/2)**2 !parameter of the solution
sigma1=1/eta/sqrt(am)*(2*wlambda*am-(wlambda+x*eta))
call cross(r1p,r2p,tmp3)
wih=tmp3/fnorm(tmp3,3)
if (lw>=1) wih=-wih
vr1 = sigma1
vt1 = sqrt(p)
call cross(wih,r1p,tmp3)
v1 = vr1 * r1p + vt1 * tmp3
vt2=vt1/r2mod
vr2=-vr1+(vt1-vt2)/tan(theta/2)
call cross(wih,r2p/r2mod,tmp3)
v2=vr2*r2p/r2mod+vt2*tmp3
v1=v1*V
v2=v2*V
if (err>tol) then
v1=(/100D0,100D0,100D0/)
v2=(/100D0,100D0,100D0/)
end if
end subroutine
!*****************************************************************
real(8) function x2tof(x,s,c,lw,N)
implicit real(8)(A-H,O-Z)
external tofabn
!Subfunction that evaluates the time of flight as a function of x
am=s/2D0
a=am/(1D0-x**2)
if (x<1D0) then
beta=2D0*asin(sqrt((s-c)/2D0/a))
if (lw>=1) beta=-beta
alfa=2*acos(x)
else !!IPERBOLE
alfa=2*acosh(x)
beta=2*asinh(sqrt((s-c)/(-2D0*a)))
if (lw>=1) beta=-beta
end if
x2tof=tofabn(a,alfa,beta,N)
end function
!*****************************************************************
real(8) function tofabn(sigma,alfa,beta,N)
implicit real(8)(A-H,O-Z)
!subfunction that evaluates the time of flight via Lagrange expression
pi = 3.141592653589793D0
if (sigma>0D0) then
tofabn=sigma*sqrt(sigma)*((alfa-sin(alfa))-(beta-sin(beta))+N*2D0*pi)
else
tofabn=-sigma*sqrt(-sigma)*((sinh(alfa)-alfa)-(sinh(beta)-beta))
end if
end function
!*****************************************************************
subroutine cross(A,B,C)
implicit none
real(8) :: A(3),B(3),C(3)
!----------------------------------------------------------------
! **计算矢量A(三维)与B的叉乘,C为返回的矢量**
!----------------------------------------------------------------
C(1)=A(2)*B(3)-A(3)*B(2)
C(2)=A(3)*B(1)-A(1)*B(3)
C(3)=A(1)*B(2)-A(2)*B(1)
end subroutine
!*****************************************************************
real(8) function fnorm(X,N)
implicit none
integer(4) :: N
real(8) :: X(N)
!----------------------------------------------------------------
! 求数组X的二范数
!----------------------------------------------------------------
fnorm = sqrt(dot_product(X(1:N),X(1:N)))
return
end function
!*****************************************************************
求解轨道力学二体意义下的Lambert方程(兰伯特方程)的Fortran程序的更多相关文章
- 李雅普诺夫函数 LyapunovFunction 李雅普诺夫意义下的稳定性
https://zh.wikipedia.org/zh-hans/李亞普諾夫函數 李雅普诺夫函数(Lyapunov function)是用来证明一动力系统或自治微分方程稳定性的函数.其名称来自俄罗斯数 ...
- coreseek实战(二):windows下mysql数据源部分配置说明
coreseek实战(二):windows下mysql数据源部分配置说明 关于coreseek在windows使用mysql数据源的配置,以及中文分词的详细说明,请参考官方文档: mysql数据源配置 ...
- HDU - 5755:Gambler Bo (开关问题,%3意义下的高斯消元)
pro:给定N*M的矩阵,每次操作一个位置,它会增加2,周围4个位置会增加1.给定初始状态,求一种方案,使得最后的数都为0:(%3意义下. sol:(N*M)^3的复杂度的居然过了. ...
- SAAS云平台搭建札记: (二) Linux Ubutu下.Net Core整套运行环境的搭建
最近做的项目,由于预算有限,公司决定不采购Windows服务器,而采购基于Linux的服务器. 一般的VPS服务器,如果使用Windows系统,那么Windows Server2012\2016安装好 ...
- HDU 5627 Clarke and MST &意义下最大生成树 贪心
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5627 题意:Bestcoder的一道题,让你求&意义下的最大生成树. 解法: 贪心,我们从高位 ...
- 2019牛客暑期多校训练营(第九场)B:Quadratic equation (二次剩余求mod意义下二元一次方程)
题意:给定p=1e9+7,A,B. 求一对X,Y,满足(X+Y)%P=A; 且(X*Y)%P=B: 思路:即,X^2-BX+CΞ0; 那么X=[B+-sqrt(B^2-4C)]/2: 全部部分都要 ...
- hdu 6088 Rikka with Rock-paper-scissors (2017 多校第五场 1004) 【组合数学 + 数论 + 模意义下的FFT】
题目链接 首先利用组合数学知识,枚举两人的总胜场数容易得到 这还不是卷积的形式,直接搞的话复杂度大概是O(n^2)的,肯定会TLE.但似乎和卷积有点像?想半天没想出来..多谢Q巨提醒,才知道可以用下面 ...
- 模意义下的FFT算法
//写在前面 单就FFT算法来说的话,下面只给出个人认为比较重要的推导,详细的介绍可参考 FFT算法学习笔记 令v[n]是长度为2N的实序列,V[k]表示该实序列的2N点DFT.定义两个长度为N的实序 ...
- Newcoder Wannafly13 B Jxy军训(费马小定理、分数在模意义下的值)
链接:https://www.nowcoder.com/acm/contest/80/B 题目描述 在文某路学车中学高一新生军训中,Jxc正站在太阳下站着军姿,对于这样的酷热的阳光,Jxc 表示非常不 ...
随机推荐
- 你真的会玩SQL吗?Case的用法(转)
今天来总结整理一下Case,因为SQL查询中用得最多的逻辑判断. Case具有两种格式.简单Case函数和Case搜索函数. --简单Case函数 CASE sex WHEN '1' THEN '男' ...
- 2.cocos2dx 3.2在语法的差异,lambada使用表达式和function和bind使用功能
1 打开 - 内置T32 Cocos2dx-3.2一个专案 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdG90b3R1enVvcXVhb ...
- linux runtime pm在深入了解的机制
一:runtime机构简介 何为runtime机制?也就是系统在非睡眠状态,设备在空暇时能够进入runtime suspend状态同一时候不依赖系统wake_lock机制.非空暇时运行runtime ...
- XML的序列化和反序列化 详细介绍
为什么要做序列化和反序列化? 一个回答: 我们都知道对象是不能在网络中直接传输的,不过还有补救的办法.XML(Extensible Markup Language)可扩展标记语言,本身就被设计用来存储 ...
- iOS # Charles拦截封包
Charles: 是在Mac下常用的截取网络封包的工具,在做iOS开发时,我们为了调试与服务器端的网络通讯协议,常常需要截取网络封包来分析.Charles通过将自己设置成系统的网络访问代理服务器,使得 ...
- addEventListener 与attachEvent
第一:简单的通用方法(IE && FF) window.onload = function(){ var oDiv = document.getElementById("J_ ...
- JS实现倒计时网页自动跳转(如404页面经常使用到的)
在web前端设计中,我们经常会遇到需要实现页面倒计时跳转的功能,例如在404页面中也会经常使用到此功能,那么如何实现呢,其实实现方法很简单,实现代码如下:<title>JS倒计时网页自动跳 ...
- DB2数据类型
DB2数据库的内置数据类型主要分成数值型(numeric).字符串型(character string).图形字符串(graphic string).二进制字符串型(binary string)或日期 ...
- UIAutomator源码分析之启动和运行
通过上一篇<Android4.3引入的UiAutomation新框架官方简介>我们可以看到UiAutomator其实就是使用了UiAutomation这个新框架,通过调用Accessibi ...
- Windows安全事件日志中的事件编号与描述
帐号登录事件(事件编号与描述) 672 身份验证服务(AS)票证得到成功发行与验证.673 票证授权服务(TGS)票证得到授权.TGS是一份由Kerberos 5.0版票证授权服务(TGS)发行.且允 ...