修改rk4方法的C实现
坦率地说,我的问题是我不确定这是如何运作的。
我需要修改 double f() 函数来解决任意问题 微分方程 d2θ/dt2 = −ω2sinθ,但事实上我不确定如何继续。
我理解 rk4 函数 runge4() 本身;我不明白的是如何 f() 函数返回谐振子的正确值。
有人至少可以解释一下 f() 函数背后的逻辑吗?
原始代码如下。
/*
************************************************************************
* 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 */
}
My problem is, frankly, that I'm unsure how this works.
I need to modify the double f() function to solve an arbitrary
differential equation d2θ/dt2 = −ω2sinθ, but as it is I am unsure how to proceed.
The rk4 function runge4() itself I understand; What I don't understand is how the
f() function returns the correct values for the harmonic oscillator.
Would someone please at least explain the logic behind the f() function?
Original code is below.
/*
************************************************************************
* 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 */
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
从胡克定律开始:
将其与牛顿第二定律结合起来,得到线性谐振子的微分方程:
任意选择我们的单位,使
k/m == 1
,方程变为:现在,引入一个虚拟变量
y = x'
,并将这个二阶微分方程写为二维一阶系统:代码中的函数
f
正是这样编码的系统;为了清楚起见,我将更改变量名称:v
是来自上面二维系统的向量[x,y]
。给定i
、t
和v
,函数f
返回相对于t< 的导数
v
的第i
组件的 /code>。使用这些名称重写二维系统,我们得到:这正是函数
f
的作用。Start from Hooke's law:
Combine this with Newton's second law to get the differential equation for a linear harmonic oscillator:
Arbitrarily chose our units so that
k/m == 1
, and the equation becomes just:Now, introduce a dummy variable
y = x'
, and write this second-order differential equation as a two-dimensional first-order system:The function
f
in your code encodes exactly this system; I'm going to change the variable names for clarity:v
is the vector[x,y]
from the two dimensional system above. Giveni
,t
, andv
, the functionf
returns the derivative with respect tot
of thei
th component ofv
. Re-writing the 2d system using these names, we get:Which is exactly what the function
f
does.N 被定义为常量 2。这意味着这些循环将进行 2 次迭代,
i = 0
和i = 1
f()
如果i == 0
,函数将返回传入多项式的第二个元素;如果i == 1
,则返回该多项式第一个元素的负数。我不知道获取谐振子的公式(老实说,这听起来像 Geordi LaForge 所说的需要重新校准之类的东西),但我认为就是这样。
N is defined as a constant 2. This means those loops are going to be doing 2 iterations,
i = 0
andi = 1
The
f()
function will return the second element of the polynomial passed in ifi == 0
and the negative of the first element of that polynomial ifi == 1
.I don't know the formula for acquiring the harmonic oscillator (it sounds like something Geordi LaForge would say needs recalibrating or something, honestly) but I would assume that's it.