出力ファイルの数が多いモデルでは, 以下で紹介する 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 の各サブルーチンおよびその引数については, 使われているサブルーチンの説明 を参照してください.