次に 並列オブジェクトを用いる場合について示す. ここでは, 2種類の記述を示す.
; ABCL/f program
; 並列オブジェクトの定義
(defclass mesh ()
; 並列オブジェクトの番号(=セルの番号)
(fixnum num)
; 時刻 T(n) における 圧力, エンタルピ, 密度, 密度×流速
(real p-n) (real h-n) (real r-n) (real ru-n)
; 時刻 T(n+1) における 圧力, エンタルピ, 密度, 密度×流速
(real p-n+1) (real h-n+1) (real r-n+1) (real ru-n+1)
; 左隣のセルへのポインタ
(mesh left)
; 右隣のセルへのポインタ
(mesh right)) ; ABCL/f program
(mesh i
p-n-ini h-n-ini r-n-ini ru-n-ini
p-n+1-ini h-n+1-ini r-n+1-ini ru-n+1-ini
left-mesh
right-mesh)
(<クラス名> <初期値> ...) ; ABCL/f program
(now
(mesh i
p-n-ini h-n-ini r-n-ini ru-n-ini
p-n+1-ini h-n+1-ini r-n+1-ini ru-n+1-ini
left-mesh
right-mesh)
:on pe)
; pe(整数) で表されるPEにオブジェクトが生成される.
; ABCL/f program
(let ((left-r-n (get-r-n left))
(left-ru-n (get-ru-n left))
(right-p-n+1 (get-p-n+1 right)))
; get-r-n は, オブジェクト(クラス)mesh のメソッドであり,
; 指定された並列オブジェクト(ここでは, left)
; の持つ r-n の値を返す.
; get-ru-n, get-p-n+1 も同様であり,
; それぞれ, ru-n, p-n+1 の値を返す.
(set-ru-n+1 self (+ ru-n
(* DT
(- (/ (- (/ (* left-ru-n left-ru-n)
left-r-n)
(/ (* ru-n ru-n)
r-n))
DX)
(/ (* (- right-p-n+1 p-n+1)
GX)
DX)))))
; set-ru-n+1 は, クラスmesh のメソッドであり,
; 指定された並列オブジェクト(ここでは, self = 自己)の
; ru-n+1 に値を設定する.
まずはじめに 両端のセルにある必要な値をローカルな変数にバインドする. 隣のセルは, 他の並列オブジェクトに存在するため PE間通信をともなう. 計算に必要な値を用意した後, 計算を行なう. 上に示したように, FORTRAN などのプログラムに比べ, 計算式が非常にみにくくなっているのが分かる.
; ABCL/f program
; 並列オブジェクトの定義
(defclass mesh-+vector ()
; 並列オブジェクトの番号
(fixnum num)
; 時刻 T(n) における 圧力, エンタルピ, 密度, 密度×流速
; 複数セル分必要なので ベクトルを用いる
((vector real) p-n) ((vector real) h-n)
((vector real) r-n) ((vector real) ru-n)
; 時刻 T(n+1) における 圧力, エンタルピ, 密度, 密度×流速
; 複数セル分必要なので ベクトルを用いる
((vector real) p-n+1) ((vector real) h-n+1)
((vector real) r-n+1) ((vector real) ru-n+1)
; 左隣の並列オブジェクトへのポインタ
(mesh left)
; 右隣の並列オブジェクトへのポインタ
(mesh right)) (mesh-+vector
i
(make-vector VN p-n-ini) (make-vector VN h-n-ini)
(make-vector VN r-n-ini) (make-vector VN ru-n-ini)
(make-vector VN p-n+1-ini) (make-vector VN h-n+1-ini)
(make-vector VN r-n+1-ini) (make-vector VN ru-n+1-ini)
left-mesh
right-mesh)
; 定数 VN は, 1つの並列オブジェクトに含まれるセルの数
(クラス名 初期値 ...) (dotimes (c (- VN 2))
(vsetf ru-n+1 (+ c 1)
(+ (vref ru-n (+ c 1))
(* DT
(- (/ (- (/ (* (vref ru-n c)
(vref ru-n c))
(vref r-n c))
(/ (* (vref ru-n (+ c 1))
(vref ru-n (+ c 1)))
(vref r-n (+ c 1))))
DX)
(/ (* (- (vref p-n+1 (+ c 2))
(vref p-n+1 (+ c 1)))
GX)
DX))))))