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 まで目盛りがある横軸は系の位置である。縦軸は波の高さである。このような波をみたことないだろうか。
|
|
|
|
|
|
|