みその計算物理学
ホーム はじめに リンク集
2次元波動方程式の数値計算例(Java)
  • プログラムソース

    ここでは波動方程式(PDF形式)に書いてある2次元波動方程式を数値的に求めるアルゴリズムの通りに数値計算してみる。初期条件は四角形の形をした波とした。

    import java.io.*;
    
    class Secondwaveequation
    {
            public static void main(String arg[])
            {
                    int t,i,j,tmax=0,N=100; //tmaxは時間的最大繰り返し回数、Nは系の長さ
                    double c,dt,dd;
                    double z[][][]=new double[3][N][N];
    
                    c=1.0;  //波の速度
                    dt=0.1; //時間の刻み幅
                    dd=2.0; //系の刻み幅
    
                    try
                    {
                            System.out.println("時間的最大繰り返し回数を整数で3以上の値を入力してください。");
                            InputStreamReader isr=new InputStreamReader(System.in);
                            BufferedReader br=new BufferedReader(isr);
                            String s;
                            s=br.readLine();
                            tmax=Integer.parseInt(s);
                    }
                    catch(Exception e)
                    {
                            System.out.println(e);
                    }
    
                    /*波の初期条件の決定*/
                    for(i=0;i<N;i++) 
                    {
                            for(j=0;j<N;j++) 
                            {
    
                                    if(i>40 && i<60 && j>40 && j<60) 
                                    {
                                            z[0][i][j]=20.0;
                                    }
                                    else 
                                    {
                                            z[0][i][j]=0.0;
                                    }
                            }
                    }
                    /*初期状態から次の状態を計算する*/
                    for(i=1;i<N-1;i++) 
                    {
                            for(j=1;j<N-1;j++) 
                            {
                                    z[1][i][j]=z[0][i][j]+c*c/2.0*dt*dt/(dd*dd)*(z[0][i+1][j]+z[0][i-1][j]+z[0][i][j+1]+z[0][i][j-1]-4.0*z[0][i][j]);
                            }
                    }
                    for(i=0;i<N;i++) 
                    {
                            z[1][i][0]=z[1][i][N-1]=z[1][0][i]=z[1][N-1][i]=0.0;    //境界条件
                    }
                    /*以降の波の状態を計算する*/
                    for(t=2;t<tmax;t++) 
                    {
    
                            for(i=1;i<N-1;i++) 
                            {
                                    for(j=1;j<N-1;j++) 
                                    {
                                            z[2][i][j]=2.0*z[1][i][j]-z[0][i][j]+c*c*dt*dt/(dd*dd)*(z[1][i+1][j]+z[1][i-1][j]+z[1][i][j+1]+z[1][i][j-1]-4.0*z[1][i][j]);
                                    }
                            }
    
                            for(i=0;i<N;i++) 
                            {
                                    z[2][i][0]=z[2][i][N-1]=z[2][0][i]=z[2][N-1][i]=0.0;    //境界条件
                            }
    
                            /*次の計算のために配列の数値を入れかえる。ここで過去の情報は失われる。*/
                            for(i=0;i<N;i++) 
                            {
                                    for(j=0;j<N;j++) 
                                    {
                                            z[0][i][j]=z[1][i][j];
                                            z[1][i][j]=z[2][i][j];
                                    }
                            }
                    }
    
                    try
                    {
                            FileWriter fw=new FileWriter("output.data");
    
                            /*最後の結果をファイルに書き込む*/
                            for(i=0;i<N;i++) 
                            {
                                    for(j=0;j<N;j++) 
                                    {
                                            fw.write(i + " " + j + " " + z[2][i][j] + "\n");
                                    }
                                    fw.write("\n");
                            }
                            fw.write("\n");
                            fw.close();
                    }
                    catch(Exception e)
                    {
                            System.out.println(e);
                    }
            }
    }
    
  • GNUPLOT出力結果

    プログラムを実行すると時間的最大繰り返し回数の入力を求められるので、結果を見たい時間経過に応じてその回数を入力する。以下の画像は、それぞれの時間的繰り返し回数別の結果である。

    回数 結果
    3
    100
    500
    1000
    2000
    3000
    4000
    5000
    10000

    さて、これらの結果は正しいであろうか。