時間発展問題の数値計算

減衰問題への前方差分の適用: Cによる例文

プログラム forward.cに 注釈をつけながら説明する。 FortranPascalの例文も同じ考え方で作ってある。

ここでは、z (時刻 t+Δtでの変数Zの値)と、 zold (時刻 t での変数Zの値)を 別々の(Cなどの言語の立場での)変数にしてみた。 前方差分だけに限れば、この2つを同じ変数にしてしまっても問題ない (なぜか考えてみよう)。しかし、後方差分その他への変更のしやすさを考えて、 区別しておくことにする。

/*
 Simple decay
     dZ/dt = aZ
 by forward difference
 written by K. Masuda, 1994-05-23, 1996-05-29, 1996-06-03
*/
*コンパイラとともに用意されたヘッダファイルのとりこみ
(printfなどを使う準備)
#include
(expなどを使う準備)
#include

int main(){
*変数の宣言。
変数はすべて宣言する。
実数型変数は、倍精度を使うことにする。
    double a, deltat, t, tzero,
           z, zold, zzero, ztrue;
    int    kt, nt;

*以下実行部。

*以下はC文法上は変数への代入文だが、実質的には定数を与えている。
(注意: C言語では実数型定数は特に指定しなくても倍精度となる。)
. 方程式の係数 a
    a      = -1.0;
. 時間発展の開始時刻
    tzero  =  0.0;
. Zの初期値 (時刻 tzero での値)
    zzero  =  1.0;
. 時間ステップ (解析解では結果の出力間隔)
    deltat =  0.1;
. 終了までの時間ステップ数
    nt     = 100;

*対象とする問題や計算の条件を示す定数の値を書き出しておく。
  gnuplotでコメント扱いするため、各行の頭に「#」を入れている。
  printf関数のカッコの中の1つめの文字列の中に含まれた「%」で始まる
  文字列は、書式指定である。%20.10lfの20は数値を表わす全体の桁数、
  10は小数部の桁数を示す。
    printf("#Problem dZ/dt = aZ\n");
    printf("#Forward difference\n");
    printf("#     a %20.10lf\n",a);
    printf("# tzero %20.10lf\n",tzero);
    printf("# zzero %20.10lf\n",zzero);
    printf("#deltat %20.10lf\n",deltat);
    printf("#    nt %20d\n",nt);
    printf("#tfinal %20.10lf\n",tzero+nt*deltat);

*シミュレーションの最初の時刻(tzero)での変数の値(初期値)の設定と出力。
    t = tzero;
    z = zzero;
    ztrue = zzero;

. 各列の見出しも、「#」つきで書き出しておく。
    printf("#               time           simulated                true\n");
    printf("%20.10lf%20.10lf%20.10lf\n", t, z, ztrue);

. 時刻 Δt での計算の準備として、z の値を zold に入れる
    zold = z;

*時間発展の計算。ステップ数 nt だけ、ループ内容を繰り返す。
    for(kt = 1; kt <= nt; kt++)
    {
. これから計算する時刻
        t = tzero + kt * deltat;
. これが前方差分の1ステップの計算
        z = zold + deltat * a * zold;
. この問題は真の解がわかっているので計算しておく
        ztrue = zzero  * exp( a * (t - tzero) );
. 値を書き出す
        printf("%20.10lf%20.10lf%20.10lf\n", t, z, ztrue);
. 時刻 t (次のステップでは時刻 t - Δt になる)の z の値を zold に入れる
        zold = z;
    }

*終わり。
}

1996-06-03; 2000-04-18; 2002-07-11
増田 耕一 (MASUDA Kooiti)
[減衰問題への前方差分、本文へ]