みその計算物理学
ホーム はじめに リンク集
KdV方程式の数値計算例(Java)
  • プログラムソース
    import java.io.*;
    
    class Co
    {
            static final int N = 200;                       //系の範囲
            static final double a = 0.5;            //係数aの値
            static final double b = 0.1;            //係数bの値
    }
    
    class Kdvequation
    {
            public static void main(String arg[])
            {
                    int t,tmax;
                    double dt, dx;
                    double u[][] = new double[3][Co . N];
    
                    tmax = 1000;                            //時間的最大繰り返し回数
                    dt = 0.05;                                      //時間的刻み幅
                    dx = 0.3;                                       //系の刻み幅
    
                    /*初期状態の波。この関数を使うと浅瀬へ向かう穏やかな波が表現できる。*/
                    for (int i = 0; i < Co.N; i++)
                    {
                            u[0][i] = (1.0 - Math.tanh((i - 100.0) / 1.5)) / 2.0;
                    }
    
                    try
                    {
                            FileWriter fw = new FileWriter("output.data");
    
                            for (int i = 2; i < Co.N - 2; i++)
                            {
                                    u[1][i] = u[0][i] - Co.a * dt / (dx) * u[0][i] * (u[0][i + 1] - u[0][i - 1]) - 3.0 * Co.b * dt / (8.0 * dx * dx * dx) * (u[0][i + 2] - u[0][i - 2] - 2.0 * u[0][i + 1] + 2.0 * u[0][i - 1]);
                            }
                            u[1][0] = u[1][1] = 1.0;            //境界条件
                            u[1][Co.N - 1] = u[1][Co.N - 2] = 0.0;
    
                            for (t = 0; t < tmax; t++)
                            {
                                    for (int i = 2; i < Co.N - 2; i++)
                                    {
                                            u[2][i] = u[0][i] - Co.a * dt / dx * u[1][i] * (u[1][i + 1] - u[1][i - 1]) - 3.0 * Co.b * dt / (4.0 * dx * dx * dx) * (u[1][i + 2] - u[1][i - 2] - 2.0 * u[1][i + 1] + 2.0 * u[1][i - 1]);
                                    }
                                    u[2][0] = u[2][1] = 1.0;    //境界条件
                                    u[2][Co.N - 1] = u[2][Co.N - 2] = 0.0;
    
                                    /*次の計算のために配列の入れ替え。ここで一番古い情報は失われる。*/
                                    for (int i = 0; i < Co.N; i++)
                                    {
                                            u[0][i] = u[1][i];
                                            u[1][i] = u[2][i];
                                    }
    
                                    /*一定おきに結果をファイルに書き込むことにしている。*/
                                    if (t % 10 == 0)
                                    {
                                            for (int i = 0; i < Co.N; i++)
                                            {
                                                    fw.write(t / 10 + " " + i + " " + u[2][i] + "\n");
                                            }
                                            fw.write("\n");
                                    }
                            }
                            fw.close();
                    }
                    catch (Exception e)
                    {
                            System.out.println(e);
                    }
            }
    }
    
  • GNUPLOT出力結果

    上のプログラムの結果である。横軸のうち 1~100 まで目盛りがある軸は時間軸、一方の 1~200 まで目盛りがある横軸は系の位置である。縦軸は波の高さである。このような波をみたことないだろうか。