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

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

      PROGRAM U2D7

      PARAMETER( NX=21, NY=21 )
      PARAMETER( XMIN=-10, XMAX=10, YMIN=-10, YMAX=10 )
      PARAMETER( DX1=1, DX2=5, DY1=1, DY2=5 )
      PARAMETER( KMAX=5, PMIN=0, PMAX=1 )
      REAL U(NX,NY), V(NX,NY), P(NX,NY), PI(2,KMAX+1)

      DO 10 J=1,NY
      DO 10 I=1,NX
        X = XMIN + (XMAX-XMIN)*(I-1)/(NX-1)
        Y = YMIN + (YMAX-YMIN)*(J-1)/(NY-1)
        U(I,J) =  X
        V(I,J) = -Y
        P(I,J) = EXP( -X**2/64 -Y**2/25 )
   10 CONTINUE

      WRITE(*,*) ' WORKSTATION ID (I)  ? ;'
      CALL SGPWSN
      READ (*,*) IWS

      CALL GROPN( IWS )
      CALL SGLSET( 'LSOFTF', .TRUE. )
      CALL GRFRM

      CALL GRSWND( XMIN, XMAX, YMIN, YMAX )
      CALL GRSVPT(  0.2,  0.8,  0.2,  0.8 )
      CALL GRSTRN( 1 )
      CALL GRSTRF

      CALL UXAXDV( 'B', DX1, DX2 )
      CALL UXAXDV( 'T', DX1, DX2 )
      CALL UXSTTL( 'B', 'X-axis', 0. )
      CALL UXMTTL( 'T', 'FIGURE TITLE', 0. )

      CALL UYAXDV( 'L', DY1, DY2 )
      CALL UYAXDV( 'R', DY1, DY2 )
      CALL UYSTTL( 'L', 'Y-axis', 0. )

      CALL UGLSET( 'LUNIT' , .TRUE. )
      CALL UGRSET( 'VXUOFF', 0.04 )
      CALL UGSUT( 'X', 'U' )
      CALL UGSUT( 'Y', 'V' )
      CALL UGVECT( U, NX, V, NX, NX, NY )

      CALL UDLSET( 'LABEL', .FALSE. )
      CALL UDLSET( 'LMSG' , .FALSE. )
      CALL UDGCLB( P, NX, NX, NY, 0.1 )
      CALL UDCNTR( P, NX, NX, NY )

      DP = (PMAX-PMIN)/KMAX
      DO 20 K=1,KMAX
        TLEV1 = (K-1)*DP
        TLEV2 = TLEV1 + DP
        IPAT  = 600 + K - 1
        CALL UESTLV( TLEV1, TLEV2, IPAT )
   20 CONTINUE
      CALL UETONE( P, NX, NX, NY )

*-- トーンバー ----
      CALL GRSWND(  0.0, 1.0, PMIN, PMAX )
      CALL GRSVPT( 0.85, 0.9, 0.45, 0.75 )
      CALL GRSTRN( 1 )
      CALL GRSTRF

      DO 30 K=1,KMAX+1
        PI(1,K) = PMIN + (K-1)*DP
        PI(2,K) = PMIN + (K-1)*DP
   30 CONTINUE

      CALL UDCNTR( PI, 2, 2, KMAX+1 )
      CALL UETONE( PI, 2, 2, KMAX+1 )

      CALL SLPVPR( 3 )
      CALL UZLSET( 'LABELYR', .TRUE. )
      CALL UZFACT( 0.8 )
      CALL UYSFMT( '(F4.1)' )
      CALL UYAXDV( 'R', DP, DP )

      CALL GRCLS

      END
PROGRAM U2D7

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

サブルーチンにおける引数の結合

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

CALL SGPLV( NMAX+1, X, Y(0,1) )
・ ・ ・ ・ ・ ・ ・ ・ ・ ・ ・ ・ ・ ・ ・
CALL SGPLV( NMAX+1, X, Y(0,I) )
FORTRAN では,配列の結合は次のように定められています:
仮引数が配列名である場合の実引数は,実引数配列の記憶列のうちで仮引 数と結合される部分の先頭の記憶単位を指定する.

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

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

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