多数のファイル出力を行うモデルでのデータ出力 (dc_date 版)

概要

出力ファイルの数が多いモデルでは, 以下で紹介する gtool_historyauto モジュールを利用することで, 複数ファイルの出力やその出力の設定変更を簡単に行うことが可能です.

gtool_historyautoデータ出力のための最低限の設定 で紹介した gtool_history モジュールの拡張版で, 以下のような特徴を持ちます.

  • 複数のファイルへの出力を行う場合, gtool_history モジュールでは ファイルごとに HistoryCreate を呼び出す 必要がありましたが, gtool_historyauto では HistoryAutoCreate をモデル内で一度呼び出す だけで済みます.
  • 個別の変数について, 出力ファイル名や出力間隔を NAMELIST で手軽に変更可能です.

以下では 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 を用いたサンプルプログラム

上記プログラムを 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 による出力間隔等の変更

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" を参照ください.

NAMELIST による変数ごとの個別出力設定

上記の例では, 全ての変数に対して一括の出力設定を行いましたが, 変数ごとに個別設定を行うことも可能です.

まず, 上記で作成したファイルを掃除しておきます.

$ 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 の以下の個所での出力間隔の設定を反映したものです.

  • 赤字はすべての変数のデフォルトの出力設定となります. 変数 "zeta" はその変数名のみを記述したため, このデフォルトの出力設定に従って出力されました. (Name を与えないか, もしくは空文字を与えた場合に, それが デフォルト設定となります).
  • 緑字は変数 "u" と "v" のみの出力設定となります. これは上記のデフォルト設定に上書きされるため, "u" および "v" についてはこの出力設定に従って出力されました.
  • 変数 "h" は記述されていないため, 出力は行われませんでした.
    !
    ! データ出力の全体設定
    !
    >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 として用意しましたので, こちらを用いて設定変更をお試しください.

設定項目の一覧

File
(文字型) 出力ファイル名. 未指定もしくは空文字を指定した場合には, "<変数名>.nc" がファイル名となります.
IntValue
(実数型) 出力間隔の数値
IntUnit
(文字型) 出力間隔の単位
Precision
(文字型) データの精度. "float" (単精度実数型), "double" (倍精度実数型), "int" (整数型) を指定可能
TimeAverage
(論理型) データの時間平均フラグ. ".true." を与えると, 時間平均値が出力されます
OriginValue
(実数型) 出力開始時刻
OriginUnit
(文字型) 出力開始時刻の単位
TerminusValue
(実数型) 出力終了時刻
TerminusUnit
(文字型) 出力終了時刻の単位
SliceStart
(整数型配列) 空間方向の開始点. 空間方向に一部分のみ切り出して出力する場合に使用します. 以下の SliceEnd, SliceStride も同様です. 配列の 1 番目, 2 番目... が HistoryAutoCreate の dims に指定された次元に対応します.
SliceEnd
(整数型配列) 空間方向の終了点
SliceStride
(整数型配列) 空間方向の刻み幅
SpaceAverage
(論理型配列) 空間平均のフラグ. 配列の 1 番目, 2 番目... が HistoryAutoCreate の dims に指定された次元に対応します.
NewFileIntValue
(整数型) ファイル分割時間間隔. データを時間方向に分割する場合に使用します. 分割時には, ファイルの末尾に開始時刻に相当する数値が自動的に付加されます.
NewFileIntUnit
(文字型) ファイル分割時間間隔の単位

全体設定でのみ有効な設定項目

Name を指定しない, もしくは空文字を与えた場合, それは全ての変数に対するデフォルト設定となります.

その場合にのみ有効な項目として以下のものがあります.

AllOutput
(論理型) HistoryAutoAddVariable によってプログラム内で登録された変数を全て出力するためのフラグ. デフォルトではNAMELIST による変数ごとの個別出力設定に示すように, 変数は明示的に指定しない限り出力されませんが, この項目を ".true." とすることで, 全ての変数が出力されます.
FilePrefix
(文字型) データのファイル名の接頭詞. 例えば "exp1-" と指定すれば, 変数 "u" の出力ファイル名は (上記の項目 "File" で変数 "u" に対して明示的にファイル名を指定しない限りは) "exp1-u.nc" となります. また, "data01/" のようにスラッシュを含む文字列を指定することで, カレントディレクトリ以外の場所に出力するよう設定することも可能です.

サブルーチンの解説

gtool_historyauto を用いたサンプルプログラム で示した, gtool_historyauto の各サブルーチンおよびその引数については, 使われているサブルーチンの説明 を参照してください.


$Id: gtauto_first.rd,v 1.4 2009-10-19 11:56:10 morikawa Exp $