プログラム forward.f に注釈をつけながら説明する。 Pascal、 Cの例文も同じ考え方で作ってある。
ここでは、z (時刻 t+Δtでの変数Zの値)と、 zold (時刻 t での変数Zの値)を 別々の(Fortranなどの言語の立場での)変数にしてみた。 前方差分だけに限れば、この2つを同じ変数にしてしまっても問題ない (なぜか考えてみよう)。しかし、後方差分その他への変更のしやすさを考えて、 区別しておくことにする。
PROGRAM decay
C
C Simple decay
C dZ/dt = aZ
C by forward difference
C written by K. Masuda, 1994-05-23
*まず変数の宣言。
IMPLICIT NONE
これは、変数はすべて宣言する、という指定である。つまり、宣言しない変数を
使うとコンパイル段階でエラーになるようにしておく。
REAL*8 a, deltat, t, tzero,
& z, zold, zzero, ztrue
実数型変数はいずれも倍精度で宣言した。
INTEGER kt, nt
*以下はFortran文法上は変数への代入文だが、実質的には定数を与えている。
. 方程式の係数 a
a = -1.0d0
. 時間発展の開始時刻
tzero = 0.0d0
. Zの初期値 (時刻 tzero での値)
zzero = 1.0d0
. 時間ステップ (解析解では結果の出力間隔)
deltat = 0.1d0
. 終了までの時間ステップ数
nt = 100
*対象とする問題や計算の条件を示す定数の値を書き出しておく。
WRITE文のカッコの中
. 1つめの要素はファイル参照番号(星印なら標準出力)。
. 2つめは、FORMAT(=書式)文の番号(星印なら変数の型ごとに標準の書式を仮定)。
gnuplotでコメント扱いするため、各行の頭に「#」を入れている。
FORMAT文の要素 Aは文字型、Iは整数型、Fは実数型変数用の書式。
WRITE (*,600) 'Problem dZ/dt = aZ'
WRITE (*,600) 'Forward difference'
WRITE (*,610) 'a',a
WRITE (*,610) 'tzero',tzero
WRITE (*,610) 'zzero',zzero
WRITE (*,610) 'deltat',deltat
WRITE (*,620) 'nt',nt
WRITE (*,610) 'tfinal',tzero+nt*deltat
600 FORMAT('#',A)
610 FORMAT('#',A6,1X,F20.10)
620 FORMAT('#',A6,1X,I20)
*シミュレーションの最初の時刻(tzero)での変数の値(初期値)の設定と出力。
t = tzero
z = zzero
ztrue = zzero
. 各列の見出しも、「#」つきで書き出しておく。
WRITE (*,700) 'time', 'simulated', 'true'
700 FORMAT('#',3A20)
WRITE (*,710) t, z, ztrue
710 FORMAT(' ',3F20.10)
. 時刻 Δt での計算の準備として、z の値を zold に入れる
zold = z
*時間発展の計算。ステップ数 nt だけ、ループ内容を繰り返す。
DO..ENDDOは、Fortran77標準ではないが、90標準に含まれ、教室でも使える。
DO kt = 1, nt
. これから計算する時刻
t = tzero + kt * deltat
. これが前方差分の1ステップの計算
z = zold + deltat * a * zold
. この問題は真の解がわかっているので計算しておく
ztrue = zzero * exp( a * (t - tzero) )
. 値を書き出す
WRITE (*,710) t, z, ztrue
. 時刻 t (次のステップでは時刻 t - Δt になる)の z の値を zold に入れる
zold = z
END DO
*終わり。
STOP
END