龙格库塔4阶方法

在groops源码数值积分时看到orbitPropagatorRungeKutta4.h,源码如下:

//4级龙格-库塔方法,求解位置,速度,加速度,并输出
inline OrbitArc OrbitPropagatorRungeKutta4::integrateArc(OrbitEpoch startEpoch, Time sampling, UInt posCount, ForcesPtr forces,
                                                         SatelliteModelPtr satellite, EarthRotationPtr earthRotation, EphemeridesPtr ephemerides, Bool timing) const
{
  try
  {
    OrbitArc orbit;
    startEpoch.acceleration = acceleration(startEpoch, forces, satellite, earthRotation, ephemerides);
    orbit.push_back(startEpoch);
    const Double dt = sampling.seconds();

    Single::forEach(posCount-1, [&](UInt /*k*/) //[ ]()语句
    {
      // Evaluate accelerations at 4 positions between current epoch and next
      OrbitEpoch k1 = orbit.back();

      OrbitEpoch k2 = k1;
      k2.time        += seconds2time(dt/2.);
      k2.position    += dt/2. * k1.velocity;
      k2.velocity    += dt/2. * k1.acceleration;
      k2.acceleration = acceleration(k2, forces, satellite, earthRotation, ephemerides);

      OrbitEpoch k3 = k1;
      k3.time        += seconds2time(dt/2.);
      k3.position    += dt/2. * k2.velocity;
      k3.velocity    += dt/2. * k2.acceleration;
      k3.acceleration = acceleration(k3, forces, satellite, earthRotation, ephemerides);

      OrbitEpoch k4 = k1;
      k4.time        += sampling;
      k4.position    += dt * k3.velocity;
      k4.velocity    += dt * k3.acceleration;
      k4.acceleration = acceleration(k4, forces, satellite, earthRotation, ephemerides);

      // Compute final value for this epoch
      OrbitEpoch epoch = k1;
      epoch.time        += sampling;
      epoch.position    += (dt/6.) * (k1.velocity + 2*k2.velocity + 2*k3.velocity + k4.velocity);
      epoch.velocity    += (dt/6.) * (k1.acceleration + 2*k2.acceleration + 2*k3.acceleration + k4.acceleration);
      epoch.acceleration = acceleration(epoch, forces, satellite, earthRotation, ephemerides);
      orbit.push_back(epoch);
    }, timing);

    return orbit;
  }
  catch (std::exception &e)
  {
    GROOPS_RETHROW(e)
  }
}

可以看出,源码中采用经典的RK4龙格-库塔方法,将函数增量通过4个斜率加权平均计算得到《卫星轨道--模型、方法和应用P113》。

 关于经典龙格库塔法比较好理解的代码可看:

https://www.cnblogs.com/JustHaveFun-SAN/archive/2012/02/09/2330655.html

Runge-Kutta公式的思路就是利用区间内一些特殊点的一阶导数值的线性组合来替代某点处的n阶导数值,这样就可以仅通过一系列一阶导数值来得到某点幂级数展开的预测效果.这和泰勒公式正好是反过来的,泰勒公式是用某点的n阶幂级数展开来近似得到小领域内的函数值。

关于龙格-库塔公式原型,以及s级龙格-库塔公式中,s次函数计算、步长控制等可参考《卫星轨道--模型、方法和应用P114-P117》,满足以下关系式:

微分方程求解通常需要预定的输出点,如果连续两点间的输出间隔比步长控制设计的步长大的多,就不会有什么大问题。但是,如果为了达到预定输出点,步长经常需要截断,这时使用龙格-库塔方法就很没有效率。因为卫星轨道等应用时输出稠密,有以下两种方法:第一时用比较宽的时间步长计算微分方程的解,然后用近似多项式插值得到所要的稠密输出点。另外一种方法是采用连续方法。

这里给一个Horn插值的6级龙格-库塔-Fehlberg方法的系数。

 

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值