10.3 等高線とベクトル場の重ね書き

2次元量表示の最後のプログラム例 u2d7 は, 等高線とベクトル場の重 ね書きです. これまでに見てきた内容の描画を1つのフレームにまとめたもの です. 'udlset' ルーチンで等高線図に関する内部変数 'LABEL''LMSG'.false. にして, ラベルとメッセージを描かない ように設定し, そのかわり, 右側にトーンバーをつけるようにしました. 61行 め以降で, もう一度正規化変換を行ない, udcntruetone ルー チンでトーンバーを描いています.

# u2d7.rb


require "narray"
require "numru/dcl"
include NumRu
include Math


nx = 21
ny = 21
xmin = -10
xmax = 10
ymin = -10
ymax = 10
dx1 = 1
dx2 = 5
dy1 = 1
dy2 = 5
kmax = 5
pmin = 0
pmax = 1
u = NArray.sfloat(nx, ny)
v = NArray.sfloat(nx, ny)
p = NArray.sfloat(nx, ny)
pi = NArray.sfloat(2, kmax+1)

#-- data ---
for j in 0..ny-1
  for i in 0..nx-1
    x = xmin + (xmax-xmin)*i/(nx-1).to_f
    y = ymin + (ymax-ymin)*j/(ny-1).to_f
    u[i,j] =  x
    v[i,j] = -y
    p[i,j] = exp(-x**2/64 -y**2/25)
  end
end

#-- graph ---
iws = (ARGV[0] || (puts ' WORKSTATION ID (I)  ? ;'; DCL::sgpwsn; gets)).to_i
DCL::gropn iws

DCL::sglset('LSOFTF', true)
DCL::grfrm

DCL::grswnd(xmin, xmax, ymin, ymax)
DCL::grsvpt(0.2, 0.8, 0.2, 0.8)
DCL::grstrn(1)
DCL::grstrf

DCL::uxaxdv('B', dx1, dx2)
DCL::uxaxdv('T', dx1, dx2)
DCL::uxsttl('B', 'X-axis', 0.0)
DCL::uxmttl('T', 'FIGURE TITLE', 0.0)

DCL::uyaxdv('L', dy1, dy2)
DCL::uyaxdv('R', dy1, dy2)
DCL::uysttl('L', 'Y-axis', 0.0)

DCL::uglset('LUNIT', true)
DCL::ugrset('VXUOFF', 0.04)
DCL::ugsut('X', 'U')
DCL::ugsut('Y', 'V')
DCL::ugvect(u, v)

DCL::udlset('LABEL', false)
DCL::udlset('LMSG', false)
DCL::udgclb(p, 0.1)
DCL::udcntr(p)

dp = (pmax-pmin)/kmax.to_f
for k in 1..kmax
  tlev1 = (k-1)*dp
  tlev2 = tlev1 + dp
  ipat  = 600 + k - 1
  DCL::uestlv(tlev1, tlev2, ipat)
end
DCL::uetone(p)

#-- トーンバー ----
DCL::grswnd(0.0, 1.0, pmin, pmax)
DCL::grsvpt(0.85, 0.9, 0.45, 0.75)
DCL::grstrn(1)
DCL::grstrf

for k in 1..kmax+1
  pi[0,k-1] = pmin + (k-1)*dp
  pi[1,k-1] = pmin + (k-1)*dp
end

DCL::udcntr(pi)
DCL::uetone(pi)

DCL::slpvpr(3)
DCL::uzlset('LABELYR', true)
DCL::uzfact(0.8)
DCL::uysfmt('(F4.1)')
DCL::uyaxdv('R', dp, dp)

DCL::grcls
program u2d7

\resizebox{10cm}{!}{\includegraphics{u2d2/u2d7.eps}}
u2d7.rb: frame1
 
FORTRANのひけつ 3

メソッド(元サブルーチン)における引数の結合

メソッド(元関数)引用やメソッド(元サブルーチン)の引用で引数によってデータの結合をおこなうとき,配列の記憶順序を意識したテクニックがよく使われます.たとえば,第 [here]章のプログラム kihon2 では,何の説明も無しにつぎのように使っています.

NumRu::DCL.sgplv(vpx,vpy)
・ ・ ・ ・ ・ ・ ・ ・ ・ ・ ・ ・ ・ ・ ・
NumRu::DCL.sgplv(vpx,vpy)
FORTRAN では,配列の結合は次のように定められています:
仮引数が配列名である場合の実引数は,実引数配列の記憶列のうちで仮引 数と結合される部分の先頭の記憶単位を指定する.

この例のように,実引数が配列要素名であれば,その配列要素の記憶単位から配列の最後の記憶単位までの記憶列が仮引数と結合されます.

つまり,配列がメソッド(元サブルーチン)に渡されるとき,メインプログラムの配列の中身がメソッド(元サブルーチン)の配列の中身にコピーされるのではなくて,メインプログラムの中の配列の番地だけが渡されて,メソッド(元サブルーチン)の方はその番地を基準にしてデータ列の処理を行なうのです.

このようなことを意識してプログラムを書くと,少ない引数で柔軟な処理が可能になります.詳細は,「岩波FORTRAN辞典」などをお読み下さい.