2019年5月18日 星期六

C語言 例題5-5.c 使用 二階Runge-Kutta 與 四階Runge-Kutta 解 ODE y'= -y + t^2 + 1 , 0<=t<=1 , y(0)=1 , 真實解 W(t)= -2e^(-t) + t ^2 - 2t + 3

C語言 例題5-5.c 使用 二階Runge-Kutta  與 四階Runge-Kutta 解 ODE y'= -y + t^2 + 1 , 0<=t<=1 , y(0)=1 , 真實解 W(t)= -2e^(-t) + t ^2 - 2t + 3

The most widely known member of the Runge–Kutta family is generally referred to as "RK4", the "classical Runge–Kutta method" or simply as "the Runge–Kutta method".
Let an initial value problem be specified as follows:
Here  is an unknown function (scalar or vector) of time , which we would like to approximate; we are told that , the rate at which  changes, is a function of  and of  itself. At the initial time  the corresponding  value is . The function  and the data  are given.
Now pick a step-size h > 0 and define
for n = 0, 1, 2, 3, ..., using[2]




Lower step size means more accuracy.
  K_1 = hf(x_n, y_n)  K_2 = hf(x_n+\frac{h}{2}, y_n+\frac{k_1}{2})  K_3 = hf(x_n+\frac{h}{2}, y_n+\frac{k_2}{2})  K_4 = hf(x_n+h, y_n+k_3)  y_n_+_1 = y_n + k_1/6 + k_2/3 + k_3/3 + k_4/6 + O(h^{5})
The formula basically computes next value yn+1 using current yn plus weighted average of four increments.
  • k1 is the increment based on the slope at the beginning of the interval, using y
  • k2 is the increment based on the slope at the midpoint of the interval, using y + hk1/2.
  • k3 is again the increment based on the slope at the midpoint, using using y + hk2/2.
  • k4 is the increment based on the slope at the end of the interval, using y + hk3.


/* ex5-5.c Second Order Runge-Kutta Method is used
 * for solving Ordinary Differential Equation of
 * y'=f(y,t) with initial condition of y(t0)=y0.
 */
#include <stdio.h>
#include <math.h>
#define F(y,t)   (-y+t*t+1)
#define W(t)     (-2*(1.0/exp(t))+pow(t,2)-2*t+3)
void main()
{
    int i,n=100;
    double h,a=0.0,b=1.0,t0,t,y0=1.0,y,k1,k2,k3,k4;
    h=(b-a)/n;
    y=y0;
    t0=a;
    t=t0;
    printf("t      y(t)       w(t)       error\n");
    printf("=====================================\n");
    printf("%.2lf %10.7lf %10.7lf %10.7lf\n\n",t,y,W(t),fabs(y-W(t)));
    for(i=1;i<=n;i++)
    {
        k1=h*F(y,t);
        k2=h*F((y+k1),(t+h));

        y=y+0.5*(k1+k2);
        t=t+h;
        if (i%10==0)
        {
            printf("k1=%.3lf , k2=%0.3lf\n",k1,k2);
            printf("%.2lf %10.7lf %10.7lf %10.7lf\n\n",t,y,W(t),fabs(y-W(t)));
        }    
    }
   
    h=(b-a)/n;
    y=y0;
    t0=a;
    t=t0;
    printf("t      y(t)       w(t)      error\n");
    printf("=====================================\n");
    printf("%.2lf %10.7lf %10.7lf %10.7lf\n\n" ,t,y,W(t),fabs(y-W(t)));
    for(i=1;i<=n;i++)
    {
        k1=h*F(y,t);
        k2=h*F((y+k1/2.0),(t+h/2.0));
        k3=h*F((y+k2/2.0),(t+h/2.0));
        k4=h*F((y+k3),(t+h));
        y=y+(k1+2*k2+2*k3+k4)/6.0;
        t=a+i*h;
        if(i%10==0)
        {
            printf("k1=%.3lf , k2=%0.3lf , k3=%0.3lf , k4=%0.3lf\n",k1,k2,k3,k4);
            printf("%.2lf %10.7lf %10.7lf %10.7lf\n\n",t,y,W(t),fabs(y-W(t)));
        }    
    }  
   return;
}


輸出畫面

t      y(t)       w(t)       error
=====================================
0.00  1.0000000  1.0000000  0.0000000

k1=0.000 , k2=0.000
0.10  1.0003269  1.0003252  0.0000017

k1=0.000 , k2=0.000
0.20  1.0025421  1.0025385  0.0000036

k1=0.001 , k2=0.001
0.30  1.0083691  1.0083636  0.0000056

k1=0.001 , k2=0.001
0.40  1.0193675  1.0193599  0.0000076

k1=0.002 , k2=0.002
0.50  1.0369483  1.0369387  0.0000096

k1=0.003 , k2=0.003
0.60  1.0623883  1.0623767  0.0000116

k1=0.004 , k2=0.004
0.70  1.0968430  1.0968294  0.0000136

k1=0.005 , k2=0.005
0.80  1.1413577  1.1413421  0.0000156

k1=0.006 , k2=0.006
0.90  1.1968782  1.1968607  0.0000175

k1=0.007 , k2=0.007
1.00  1.2642605  1.2642411  0.0000194

t      y(t)       w(t)      error
=====================================
0.00  1.0000000  1.0000000  0.0000000

k1=0.000 , k2=0.000 , k3=0.000 , k4=0.000
0.10  1.0003252  1.0003252  0.0000000

k1=0.000 , k2=0.000 , k3=0.000 , k4=0.000
0.20  1.0025385  1.0025385  0.0000000

k1=0.001 , k2=0.001 , k3=0.001 , k4=0.001
0.30  1.0083636  1.0083636  0.0000000

k1=0.001 , k2=0.001 , k3=0.001 , k4=0.001
0.40  1.0193599  1.0193599  0.0000000

k1=0.002 , k2=0.002 , k3=0.002 , k4=0.002
0.50  1.0369387  1.0369387  0.0000000

k1=0.003 , k2=0.003 , k3=0.003 , k4=0.003
0.60  1.0623767  1.0623767  0.0000000

k1=0.004 , k2=0.004 , k3=0.004 , k4=0.004
0.70  1.0968294  1.0968294  0.0000000

k1=0.005 , k2=0.005 , k3=0.005 , k4=0.005
0.80  1.1413421  1.1413421  0.0000000

k1=0.006 , k2=0.006 , k3=0.006 , k4=0.006
0.90  1.1968607  1.1968607  0.0000000

k1=0.007 , k2=0.007 , k3=0.007 , k4=0.007
1.00  1.2642411  1.2642411  0.0000000

沒有留言:

張貼留言

2024_09 作業3 以Node-Red 為主

 2024_09 作業3  (以Node-Red 為主  Arduino 可能需要配合修改 ) Arduino 可能需要修改的部分 1)mqtt broker  2) 主題Topic (發行 接收) 3) WIFI ssid , password const char br...