出力ファイルの数が多いモデルでは, 以下で紹介する gtool_historyauto モジュールを利用することで, 複数ファイルの出力やその出力の設定変更を簡単に行うことが可能です.
gtool_historyautoは データ出力のための最低限の設定 で紹介した gtool_history モジュールの拡張版で, 以下のような特徴を持ちます.
以下では gtool_historyauto モジュールの使い方を 説明します.
プログラムとして, 階層的地球流体スペクトルモデル集 SPMODEL 一つである 球面上の流れ を計算するものを用います.
gtool_history を用いたものが sp_topo_gthist.f90 になります (上記ページで公開されるオリジナルから少し改変されています). このプログラムをコンパイル・実行すると, 4 つの従属変数 (h, u, v, zeta) が単一のファイル sp_topo_gthist.nc に出力されます. gtool_history でこれを別々のファイルに出力するには, 複数のファイルに出力 に示すように, ファイル毎に初期化サブルーチン HistoryCreate を指定せねばなりません.
gtool_historyauto を用いることで, 初期化サブルーチンの呼び出しが 一つで済むとともに, 変数ごとの出力設定の変更を容易に行うことができます.
上記プログラムを gtool_historyauto を用いて書きなおしたものが 以下に示す sp_topo_gtauto.f90 となります.
赤字(カラーがでない場合はボールド)が gtool_historyauto に 関係している箇所です. (行数が多いため, 一部を抜粋しています). 左の緑字は行数を表します.
このページでは各サブルーチンの詳細については述べません. 以下でサンプルプログラムの実行や NAMELIST による出力設定の変更を一通り試した後, 使われているサブルーチンの説明 を参照してください.
1 !---------------------------------------------------------------------- 2 ! Copyright (C) 2001--2008 SPMODEL Development Group. All rights reserved. 3 !---------------------------------------------------------------------- 4 ! Sample program for gtool_history/gtool5 and ISPACK 2002/08/21 S.Takehiro 5 ! 2004/01/26 M.Odaka 6 ! 2009/02/27 Y.Morikawa 7 ! 8 ! Solving a linear 2-D shallow water system on a sphere 9 ! with an isolated mountain 10 ! du/dt + u0/a\cos\phi du/d\lambda + v/a du0/d\phi - u0v\tan\phi/a 11 ! - 2\Omega\sin\phi v = -g/a\cos\phi dh/d\lambda - \nu\lapla^4 u, 12 ! dv/dt + u0/a\cos\phi dv/d\lambda + 2 u0 u \tan\phi/a 13 ! + 2\Omega\sin\phi u = -g/a dh/d\phi - \nu\lapla^4 v, 14 ! dh/dt + ( 1/\cos\phi d( (H+h0)u+(h-ht)u0 )/d\lambda 15 ! + 1/\cos\phi d( (H+h0)v\cos\phi)/d\phi ) = - \nu\lapla^4 h. 16 ! 17 ! A setup is similar to the experiment of Grose and Hoskins (1979) 18 ! with a superrotating rigid-rotation zonal wind profile. 19 ! 20 program sp_topo_gtauto 21 22 use w_module 23 use gtool5 24 use gtool_historyauto ! モジュール指定 25 implicit none 26 27 !---- 空間解像度設定 ---- 28 integer, parameter :: im=64, jm=32 ! 格子点の設定(X,Y) 29 integer, parameter :: nm=21 30 31 !---- 変数 ---- 32 real(8) :: xy_U(0:im-1,jm) ! 格子点データ(速度経度成分) 33 real(8) :: xy_V(0:im-1,jm) ! 格子点データ(速度緯度成分) 34 real(8) :: xy_H(0:im-1,jm) ! 格子点データ(変位) : : 44 real(8) :: xy_Zeta(0:im-1,jm) ! 格子点データ(渦度) 45 real(8) :: xy_Htopo(0:im-1,jm) ! 格子点データ(地形) 46 47 !---- 時間積分パラメター ---- 48 real(8):: dt ! 時間間隔 [s] 49 type(DC_DIFFTIME):: deltime, dispint ! 時間間隔, 出力時間間隔 50 type(DC_DIFFTIME):: endtime ! 計算終了時間 51 type(DC_DIFFTIME):: ct ! 現在時刻 : : 68 !------ NAMELIST ファイル名 ------ 69 character(*), parameter:: nmlfile = 'sp_topo_gtauto.nml' : : 75 !---- 時間積分パラメターの設定 ---- 76 dt = 100. ! 時間間隔 [s] 77 call DCDiffTimeCreate(deltime, dt, 'sec') ! 時間間隔 78 dispint = deltime * 500 ! 出力時間間隔 79 endtime = deltime * 10000 ! 計算終了時間 80 call DCDiffTimeCreate(ct, 0., 'sec') ! 現在時刻 81 82 !---------------- 座標値の設定 --------------------- 83 call w_Initial(nm,im,jm) ! ISPACK初期化 84 85 !------------------- 初期値設定 ---------------------- 86 xy_U0 = U0*cos(xy_Lat) 87 xy_H0 = ( Omega*R0*U0/(2*Grav) + U0**2/(4*Grav) )*cos(2*xy_Lat) 88 89 xy_U = 0 ; xy_V = 0 ; xy_H = 0 90 91 w_U0 = w_xy(xy_U0) !; w_H0 = w_xy(xy_H0) 92 w_U = w_xy(xy_U) ; w_V = w_xy(xy_V) ; w_H = w_xy(xy_H) : : 107 !------------------- ヒストリー初期設定 ---------------------- 108 call output_gtool5_init ! ヒストリー初期化 109 call output_gtool5 ! 初期値出力 110 111 !------------------- 時間積分 ---------------------- 112 do while ( ct <= endtime ) 113 if ( mod(ct, dispint) == 0 ) then 114 write(6,*) 'it = ', int( ct / deltime ) 115 end if 116 117 ct = ct + deltime ! 時刻の進行 118 119 w_U = ( w_U & 120 + dt * w_xy( - xy_U0 * xy_GradLon_w(w_U) / R0 & 121 - xy_V * xy_GradLat_w(w_U0) / R0 & 122 + xy_U0 * xy_V * tan(xy_Lat) / R0 & 123 + 2 * Omega * sin(xy_Lat) * xy_V & 124 - Grav * xy_GradLon_w(w_H)/ R0 ) & 125 )/(1+Nu*(-rn(:,1)/R0**2)**(ndiff/2)*dt) : : 144 xy_H = xy_w(w_H) 145 146 call output_gtool5 ! 出力 147 enddo 148 149 call output_gtool5_close ! ファイルのクローズ 150 stop 151 152 contains 153 subroutine output_gtool5_init 154 write(6,'(a)',advance='NO') ' Input NAMELIST file: ' 155 read (5,'(a)') nmlfile 156 157 call HistoryAutoCreate( & ! ヒストリー作成 158 title='Shallow water equation on a sphere', & 159 source='Sample program of gtool_historyauto/gtool5', & 160 institution='GFD_Dennou Club davis/spmodel project', & 161 dims=(/'lon','lat','t '/), dimsizes=(/im,jm,0/), & 162 longnames=(/'longitude','latitude ','time '/), & 163 units=(/'degree_east ','degree_north','sec. '/), & 164 origin=ct, interval=dispint, terminus=endtime, & 165 namelist_filename=nmlfile ) 166 167 call HistoryAutoPutAxis('lon',x_Lon*180/pi) ! 変数出力 168 call HistoryAutoAddAttr('lon','topology','circular') ! 周期属性 169 call HistoryAutoAddAttr('lon','modulo',360.0) ! 周期属性 170 call HistoryAutoPutAxis('lat',y_Lat*180/pi) ! 変数出力 171 172 call HistoryAutoAddVariable( & ! 変数定義 173 varname='h', dims=(/'lon','lat','t '/), & 174 longname='surface displacement ', units='m') 175 176 call HistoryAutoAddVariable( & ! 変数定義 177 varname='u', dims=(/'lon','lat','t '/), & 178 longname='velocity(longitude) ', units='m/s') 179 180 call HistoryAutoAddVariable( & ! 変数定義 181 varname='v', dims=(/'lon','lat','t '/), & 182 longname='velocity(latitude) ', units='m/s') 183 184 call HistoryAutoAddVariable( & ! 変数定義 185 varname='zeta', dims=(/'lon','lat','t '/), & 186 longname='vorticity', units='1/s') 187 188 end subroutine output_gtool5_init 189 190 subroutine output_gtool5 191 call HistoryAutoPut(ct, 'u', xy_U) 192 call HistoryAutoPut(ct, 'v', xy_V) 193 call HistoryAutoPut(ct, 'h', xy_H) 194 xy_Zeta = xy_w(w_Divlon_xy(xy_V) - w_Divlat_xy(xy_U))/r0 195 call HistoryAutoPut(ct, 'zeta', xy_Zeta) 196 end subroutine output_gtool5 197 198 subroutine output_gtool5_close 199 call HistoryAutoClose 200 end subroutine output_gtool5_close 201 202 end program sp_topo_gtauto
このプログラムを実際にコンパイルして実行してみましょう. まず, 上記ファイルと, 計算実行に必要なサブルーチンや関数の定義ファイル, およびサンプルとして使用する NAMELIST ファイルを以下からダウンロードしてください.
次に, 計算に必要なサブルーチンや関数が含まれるファイルをコンパイルします. ispack_snip.f と w_module_snip.f90 を以下のようにコンパイルしてください.
$ gt5frt -c w_module_snip.f90 ispack_snip.f
コンパイルの結果, 5 つのファイル (w_module.mod, w_deriv_module.mod, w_base_module.mod, w_module_snip.o, ispack_snip.o) が作成されれば OK です. なお, ispack_snip.f と w_module_snip.f90 はそれぞれ, ISPACK ライブラリと spml ライブラリの一部を抜粋したものです.
sp_topo_gtauto.f90 を以下のようにコンパイルしてください.
$ gt5frt sp_topo_gtauto.f90 w_module_snip.o ispack_snip.o
これで実行ファイル a.out が作成されます. 以下のように実行してみましょう.
$ ./a.out
実行すると, 以下のようなメッセージが表示され NAMELIST ファイル名の入力 が求められます. まずは何も入力せずに Enter キーを入力しましょう.
Input NAMELIST file:
数秒から数分でプログラムが終了し, 4 つのファイル (u.nc, v.nc, h.nc, zeta.nc) が作成されます. これらのファイルには, それぞれ変数 (u, v, h, zeta) が格納されています.
NetCDF のコマンド ncdump を用いて中身を確認しましょう.
$ ncdump -v t u.nc | more
netcdf u { dimensions: lon = 32 ; lat = 16 ; t = UNLIMITED ; // (21 currently) variables: float lon(lon) ; lon:long_name = "longitude" ; lon:units = "degree_east" ; lon:topology = "circular" ; lon:modulo = 360.f ; float lat(lat) ; lat:long_name = "latitude" ; lat:units = "degree_north" ; float t(t) ; t:long_name = "time" ; t:units = "sec." ; float u(t, lat, lon) ; u:long_name = "velocity(longitude)" ; u:units = "m/s" ; // global attributes: :Conventions = "http://www.gfd-dennou.org/library/gtool4/conventions/" ; : data: t = 0, 50000, 100000, 150000, 200000, 250000, 300000, 350000, 400000, 450000, 500000, 550000, 600000, 650000, 700000, 750000, 800000, 850000, 900000, 950000, 1000000 ; }
赤字(カラーがでない場合はボールド)を見ると, データが 50000 sec ごとに出力されていることがわかります. これは gtool_historyauto を用いたサンプルプログラム の 以下の個所での出力間隔の設定を反映したものです.
47 !---- 時間積分パラメター ---- 48 real(8):: dt ! 時間間隔 [s] 49 type(DC_DIFFTIME):: deltime, dispint ! 時間間隔, 出力時間間隔 : : 75 !---- 時間積分パラメターの設定 ---- 76 dt = 100. ! 時間間隔 [s] 77 call DCDiffTimeCreate(deltime, dt, 'sec') ! 時間間隔 78 dispint = deltime * 500 ! 出力時間間隔 : : 157 call HistoryAutoCreate( & ! ヒストリー作成 158 title='Shallow water equation on a sphere', & 159 source='Sample program of gtool_historyauto/gtool5', & 160 institution='GFD_Dennou Club davis/spmodel project', & 161 dims=(/'lon','lat','t '/), dimsizes=(/im,jm,0/), & 162 longnames=(/'longitude','latitude ','time '/), & 163 units=(/'degree_east ','degree_north','sec. '/), & 164 origin=ct, interval=dispint, terminus=endtime, & 165 namelist_filename=nmlfile ) 166
NAMELIST ファイルを用いて出力間隔を変更してみます. 再度 a.out を実行します.
$ ./a.out
今回は以下のように NAMELIST ファイル名を入力してください.
Input NAMELIST file: sp_topo_gtauto1.nml ^^^^^^^^^^^^^^^^^^^ ← ここは手動で入力してください.
すると以下のメッセージが出力された後, 計算が実行されます.
*** MESSAGE [HistAuto] *** ----- "gtool_historyauto_nml" is loaded from "sp_topo_gtauto1.nml" ----- *** MESSAGE [HistAuto] *** Global Settings: *** MESSAGE [HistAuto] *** AllOutput = F *** MESSAGE [HistAuto] *** FilePrefix = *** MESSAGE [HistAuto] *** Interval = 1. [day] *** MESSAGE [HistAuto] *** Individual Settings: *** MESSAGE [HistAuto] *** Name = u, v, h, zeta *** MESSAGE [HistAuto] *** File = <Name>.nc *** MESSAGE [HistAuto] *** Interval = 1. [day]
今回も 4 つのファイル (u.nc, v.nc, h.nc, zeta.nc) が作成されます.
NetCDF のコマンド ncdump を用いて中身を確認しましょう.
$ ncdump -v t u.nc | more
netcdf u { dimensions: lon = 32 ; lat = 16 ; t = UNLIMITED ; // (21 currently) variables: : float t(t) ; t:long_name = "time" ; t:units = "day" ; float u(t, lat, lon) ; u:long_name = "velocity(longitude)" ; u:units = "m/s" ; // global attributes: :Conventions = "http://www.gfd-dennou.org/library/gtool4/conventions/" ; : data: t = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ; }
赤字(カラーがでない場合はボールド)を見ると, データが 1 day (= 86400 sec) ごとに出力されていることがわかります. これは sp_topo_gtauto1.nml の以下の個所での出力間隔の設定を反映したものです.
>ool_historyauto_nml IntValue = 1., ! 出力間隔の数値 IntUnit = 'day' ! 出力間隔の単位 / >ool_historyauto_nml Name = 'u, v, h, zeta' ! 出力変数 /
IntUnit には, "sec", "min", "hour", "day", "month", "year", "nondim" (無次元時間) などが使用可能です. 使用可能な単位については dc_date_typesの "Characters list for unit" を参照ください.
上記の例では, 全ての変数に対して一括の出力設定を行いましたが, 変数ごとに個別設定を行うことも可能です.
まず, 上記で作成したファイルを掃除しておきます.
$ rm -f u.nc v.nc h.nc zeta.nc
そして再度 a.out を実行します.
$ ./a.out
今回は以下のように NAMELIST ファイル名を入力してください.
Input NAMELIST file: sp_topo_gtauto2.nml ^^^^^^^^^^^^^^^^^^^ ← ここは手動で入力してください.
すると以下のメッセージが出力された後, 計算が実行されます.
*** MESSAGE [HistAuto] *** ----- "gtool_historyauto_nml" is loaded from "sp_topo_gtauto2.nml" ----- *** MESSAGE [HistAuto] *** Global Settings: *** MESSAGE [HistAuto] *** AllOutput = F *** MESSAGE [HistAuto] *** FilePrefix = *** MESSAGE [HistAuto] *** Interval = 1. [day] *** MESSAGE [HistAuto] *** Individual Settings: *** MESSAGE [HistAuto] *** Name = u, v *** MESSAGE [HistAuto] *** File = <Name>.nc *** MESSAGE [HistAuto] *** Interval = 12. [hour] *** MESSAGE [HistAuto] *** Individual Settings: *** MESSAGE [HistAuto] *** Name = zeta *** MESSAGE [HistAuto] *** File = <Name>.nc *** MESSAGE [HistAuto] *** Interval = 1. [day]
今回は 3 つのファイル (u.nc, v.nc, zeta.nc) が作成されます.
NetCDF のコマンド ncdump を用いて中身を確認しましょう.
$ ncdump -v t u.nc | more
: float t(t) ; t:long_name = "time" ; t:units = "hour" ; float u(t, lat, lon) ; u:long_name = "velocity(longitude)" ; u:units = "m/s" ; : data: t = 0, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144, 156, 168, 180, 192, 204, 216, 228, 240, 252, 264, 276 ; }
$ ncdump -v t zeta.nc | more
: float t(t) ; t:long_name = "time" ; t:units = "day" ; float zeta(t, lat, lon) ; zeta:long_name = "vorticity" ; zeta:units = "1/s" ; : data: t = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ; }
赤字(カラーがでない場合はボールド)を見ると, 変数 u は 12 hour おきに出力され, 一方で変数 zeta は 1 日おきに出力されていることがわかります.
これらは sp_topo_gtauto2.nml の以下の個所での出力間隔の設定を反映したものです.
! ! データ出力の全体設定 ! >ool_historyauto_nml IntValue = 1., ! 出力間隔の数値 IntUnit = 'day', ! 出力間隔の単位 / ! ! データ出力の個別設定 ! >ool_historyauto_nml Name = 'u, v' ! 出力変数 IntValue = 12., ! 出力間隔の数値 IntUnit = 'hour', ! 出力間隔の単位 / >ool_historyauto_nml Name = 'zeta' ! 出力変数 /
上記では出力間隔の変更を例に挙げましたが, gtool_historyauto ではこれだけでなく, 以下の項目を変更可能です. 一通りの設定が記述された NAMELIST ファイルを sp_topo_gtauto3.nml として用意しましたので, こちらを用いて設定変更をお試しください.
Name を指定しない, もしくは空文字を与えた場合, それは全ての変数に対するデフォルト設定となります.
その場合にのみ有効な項目として以下のものがあります.
gtool_historyauto を用いたサンプルプログラム で示した, gtool_historyauto の各サブルーチンおよびその引数については, 使われているサブルーチンの説明 を参照してください.