首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >修改rk4方法的C实现

修改rk4方法的C实现
EN

Stack Overflow用户
提问于 2011-04-30 04:53:01
回答 2查看 1.2K关注 0票数 0

坦率地说,我的问题是,我不确定这是如何工作的。

我需要修改double f()函数来求解θ中的任意微分方程d2θ/dt2 =−ω2in,但现在我不确定如何继续。

我理解rk4函数runge4()本身;我不理解的是f()函数如何返回谐振子的正确值。

有人能至少解释一下f()函数背后的逻辑吗?

原始代码如下。

代码语言:javascript
复制
/* 
************************************************************************
*  rk4.c: 4th order Runge-Kutta solution for harmonic oscillator       *
*                      *
* From: "A SURVEY OF COMPUTATIONAL PHYSICS" 
   by RH Landau, MJ Paez, and CC BORDEIANU 
   Copyright Princeton University Press, Princeton, 2008.
   Electronic Materials copyright: R Landau, Oregon State Univ, 2008;
   MJ Paez, Univ Antioquia, 2008; & CC BORDEIANU, Univ Bucharest, 2008
   Support by National Science Foundation                              
*
************************************************************************
*/

#include <stdio.h>

#define N 2                                   /* number of equations */
#define dist 0.1                              /* stepsize */
#define MIN 0.0                               /* minimum x */
#define MAX 10.0                              /* maximum x */

void runge4(double x, double y[], double step);
double f(double x, double y[], int i);

int main()
{

   double x, y[N];
   int j;

   FILE *output;                              /* save data in rk4.dat */
   output = fopen("rk4.dat","w");

   y[0] = 1.0;                                /* initial position  */
   y[1] = 0.0;                                /* initial velocity  */

   fprintf(output, "%f\t%f\n", x, y[0]);

   for(x = MIN; x <= MAX ; x += dist)
   {
      runge4(x, y, dist);
      fprintf(output, "%f\t%f\n", x, y[0]);   /* position vs. time */
   }
   printf("data stored in rk4.dat\n");
   fclose(output);
}
/*-----------------------end of main program--------------------------*/

/* Runge-Kutta subroutine */
void runge4(double x, double y[], double step)
{
   double h=step/2.0,                         /* the midpoint */
          t1[N], t2[N], t3[N],                /* temporary storage */
          k1[N], k2[N], k3[N],k4[N];          /* for Runge-Kutta  */
   int i;

   for (i=0; i<N; i++) t1[i] = y[i]+0.5*(k1[i]=step*f(x, y, i));
   for (i=0; i<N; i++) t2[i] = y[i]+0.5*(k2[i]=step*f(x+h, t1, i));
   for (i=0; i<N; i++) t3[i] = y[i]+    (k3[i]=step*f(x+h, t2, i));
   for (i=0; i<N; i++) k4[i] =                 step*f(x + step, t3, i);

   for (i=0; i<N; i++) y[i] += (k1[i]+2*k2[i]+2*k3[i]+k4[i])/6.0;
}
/*--------------------------------------------------------------------*/

/* definition of equations - this is the harmonic oscillator */
double  f(double x, double y[], int i)
{
   if (i == 0) return(y[1]);               /* RHS of first equation */
   if (i == 1) return(-y[0]);              /* RHS of second equation */
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-04-30 05:06:20

从胡克定律说起:

代码语言:javascript
复制
F = -kx

结合牛顿第二定律,得到线性谐振子的微分方程:

代码语言:javascript
复制
ma = F = -kx
mx'' = -kx
x'' = -k/m x

任意选择单位,这样k/m == 1,方程就变成了:

代码语言:javascript
复制
x'' = -x

现在,引入一个虚拟变量y = x',并将这个二阶微分方程写成一个二维一阶系统:

代码语言:javascript
复制
x' = y
y' = -x

代码中的函数f完全编码了这个系统;为清楚起见,我将更改变量名:

代码语言:javascript
复制
double  f(double t, double v[], int i)
{
   if (i == 0) return(v[1]);
   if (i == 1) return(-v[0]);
}

v是来自上面二维系统的向量[x,y]。给定itv,函数f返回关于tv的第i个分量的导数。使用这些名称重写2d系统,我们得到:

代码语言:javascript
复制
dv[0]/dt =  v[1]
dv[1]/dt = -v[0]

这正是函数f所做的。

票数 3
EN

Stack Overflow用户

发布于 2011-04-30 05:00:20

N被定义为常量2。这意味着这些循环将进行2次迭代,i = 0i = 1

如果为i == 0,则f()函数将返回传入的多项式的第二个元素;如果为i == 1,则返回该多项式的第一个元素的负数。

我不知道获得谐振子的公式(老实说,这听起来像是Geordi LaForge会说需要重新校准的东西),但我认为就是这样。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5837293

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档