RK4方法的运动方程

计算科学 C++ 龙格库塔
2021-12-11 08:54:13

我想唯一的形式的弹簧质量方程: ,其中质量,阻尼,刚度,外部力和横向位移;使用龙格-库塔四阶法我将 RK4 C++ 代码修改为:MY¨+BY˙+KY=Fy(t)M:B:K:Fy:Y:

/*
Definition of the y'(t) = f1(t,y,y') = y' by the definition
*/
double f1(double t, double y, double v)
{
  double d1y;
  d1y = v;
  return d1y;
}

/*
Definition of the y"(t) = f2(t,y,y')
*/
double f2(double t, double y, double v, double Fy)
{
 double d2y;
 double M = 0.03715; // 10.0;
 double B = 0.0;
 double K = 0.149; 
 d2y = (-Fy-B*v-K*x)/M; 
 return d2y;
}

/*-----------------------------------------------------------------------
Program to solve 1st order Ordinary Differential Equations
y'(t) = d1y(t,y)
y"(t) = d2y(t,y)
method: 4th-order Runge-Kutta method */

double rk4_2nd(double(*d1x)(double, double, double),
           double(*d2x)(double, double, double, double),
           double ti, double xi, double vi, double tf, double Fy,
           double& xf, double& vf)
{
  double h,t,k1x,k2x,k3x,k4x,k1v,k2v,k3v,k4v;

  h = tf-ti;
  t = ti;

  k1x = h*d1x(t,xi,vi);
  k1v = h*d2x(t,xi,vi,Fy);

  k2x = h*d1x(t+h/2.0,xi+k1x/2.0,vi+k1v/2.0);
  k2v = h*d2x(t+h/2.0,xi+k1x/2.0,vi+k1v/2.0,Fy);

  k3x = h*d1x(t+h/2.0,xi+k2x/2.0,vi+k2v/2.0);
  k3v = h*d2x(t+h/2.0,xi+k2x/2.0,vi+k2v/2.0,Fy);

  k4x = h*d1x(t+h,xi+k3x,vi+k3v);
  k4v = h*d2x(t+h,xi+k3x,vi+k3v,Fy);

  xf = xi + (k1x + 2.0*(k2x+k3x) + k4x)/6.0;
  vf = vi + (k1v + 2.0*(k2v+k3v) + k4v)/6.0;

  return 0.0;
}

我面临的问题是:

  • RK4 在函数 egFunction(void) 内部被调用,而这个 Function() 在 main 内部被调用,其中时间循环以迭代的形式运行,我如何为我的问题定义 ti、tf 到 RK4 函数。

     void Function() {
    
     Y0[n] = Y[n] - YC; // n =  number of objects i.e. n = 1 at the moment
     // Y : current displacement; YC: Initial/reference position = constant
     V0[n] = V[n]; // Velocity at (t-1) = velocity at (t)
     FY[n] += -k * (Y0[n]); // external force; k : spring constant
    
     rk4_2nd(f1, f2, t0, Y0[n], V0[n], t1, FY[n], Y[n], V[n]); 
    } 
    
    int main() {
      N = 0;
    do {
      N = N + 1;
      Function();
     } while (N < NMAX);
     return 0;
    }
    
1个回答

如果我了解您希望如何实现它,那么您的代码更新应该是您想要的。

void Function(double currentTime, double nextTime) {
 for( int i = 0; i < n; i++ ){
    Y0[i] = Y[i] - YC; // n =  number of objects i.e. n = 1 at the moment
    // Y : current displacement; YC: Initial/reference position = constant
    V0[i] = V[i]; // Velocity at (t-1) = velocity at (t)
    FY[i] += -k * (Y0[i]); // external force; k : spring constant

    rk4_2nd_me1(f1, f2, currentTime, Y0[i], V0[i], nextTime, FY[i], Y[i], V[i]); 
 }
} 

int main() {
  double currentTime = 0.0, finalTime = 1.0;
  double dt = (finalTime-currentTime)/static_cast<double>(NMAX);
  int N = 0;
  do {
    currentTime = N*dt;
    N = N + 1;
    Function(currentTime,currentTime+dt);
  } while (N < NMAX);
 return 0;
}

现在基于此,我假设它们Y0, V0, Y, V, FY, YC都是全局变量。