gtool5 Fortran 90/95 Library 1.0.0-rc5
日本語
Loading...
Searching...
No Matches
historyaddvariable.f90
Go to the documentation of this file.
1!> @file historyaddvariable.F
2!>
3!> @author Yasuhiro MORIKAWA, Eizi TOYODA
4!> @copyright Copyright (C) GFD Dennou Club, 2000-2026. All rights reserved. <br/>
5!> License is BSD-2-Clause. See [COPYRIGHT](@ref COPYRIGHT) in detail
6!>
7!> @en
8!> @brief Definition of a variable
9!> @enden
10!>
11!> @ja
12!> @brief 変数定義
13!> @endja
14!>
15!> @en
16!> @brief Define a variable in history
17!>
18!> Defines a variable within gtool4 data. HistoryCreate must be called
19!> beforehand. Use HistoryCopyVariable to copy an existing variable
20!> with the same structure.
21!>
22!> HistoryAddVariable is a generic name for two subroutines.
23!>
24!> **Time averaging:**
25!> Output data is averaged in the time direction when both conditions
26!> are met: time_average is set to .true. in HistoryAddVariable,
27!> and a time argument (time, timed, or difftime) is given to HistoryPut.
28!> Data is temporarily stored internally and output at the interval
29!> specified in HistoryCreate. Non-uniform time intervals are handled
30!> by weighted averaging: sum(data * weight) / sum(weight).
31!> @param[in] varname Variable name
32!> @param[in] dims Dependent dimensions
33!> @param[in] longname Descriptive name
34!> @param[in] units Units
35!> @param[in] xtype Variable type (optional)
36!> @param[in] time_average Time average flag (optional)
37!> @param[in] average Time average flag, old version (optional)
38!> @param[inout] history History structure (optional)
39!> @param[out] err Error flag (optional)
40!> @enden
41!>
42!> @ja
43!> @brief 変数定義
44!>
45!> gtool4 データ内の変数の定義を行います。このサブルーチンを
46!> 用いる前に、HistoryCreate による初期設定が必要です。
47!> 既に gtool4 データが存在し、そのデータ内の変数と全く同じ
48!> 構造の変数を定義したい場合は HistoryCopyVariable を利用すると便利です。
49!>
50!> HistoryAddVariable は 2 つの別々のサブルーチンの総称名です。
51!>
52!> **時間平均について:**
53!> HistoryAddVariable の引数 time_average に .true. を与え、
54!> かつ HistoryPut に時刻を示す引数を与えている場合に、
55!> 出力データを時間方向に平均化して出力します。
56!> データは内部に一時保管され、HistoryCreate の interval の
57!> 間隔をおいて出力されます。時間間隔が一定でない場合、
58!> 重み付けをして出力されます。
59!> @param[in] varname 変数名
60!> @param[in] dims 依存する次元
61!> @param[in] longname 変数の記述的名称
62!> @param[in] units 変数の単位
63!> @param[in] xtype 変数のデータ型 (省略可能)
64!> @param[in] time_average 時間平均フラグ (省略可能)
65!> @param[in] average 時間平均フラグ, 旧版 (省略可能)
66!> @param[inout] history 出力ファイル設定構造体 (省略可能)
67!> @param[out] err エラーフラグ (省略可能)
68!> @endja
69!>
70 recursive subroutine historyaddvariable1( &
71 & varname, dims, longname, units, &
72 & xtype, time_average, average, history, err )
73 !
80 & put, putline
81 use gtdata_types, only: gt_variable
82 use netcdf, only: nf90_ebaddim
85 use dc_string, only: cprintf, joinchar, stoa
86 use dc_url, only: gt_atmark, urlresolve
88 use dc_date, only: dcdifftimecreate
89 use dc_date_types, only: dc_difftime
90 use dc_message, only: messagenotify
91 use dc_trace, only: beginsub, endsub
92 use dc_types, only: string, dp
93 implicit none
94 character(len = *), intent(in):: varname
95 ! 定義する変数の名前
96 !
97 ! 最大文字数は dc_types::TOKEN
98 !
99 character(len = *), intent(in):: dims(:)
100 ! 変数が依存する次元の名前
101 !
102 ! 時間の次元は配列の最後に指定
103 ! しなければならない。
104 ! ここで指定するものは、
105 ! HistoryCreate にて dims で指定
106 ! されていなければならない。
107 !
108 ! もしもスカラー変数を作成
109 ! する場合には, サイズが 1 で
110 ! 中身が空の文字型配列,
111 ! すなわち <tt> (/''/) </tt>
112 ! を与えること.
113 !
114 character(len = *), intent(in):: longname
115 ! 変数の記述的名称
116 !
117 ! 最大文字数は dc_types::STRING
118 !
119 character(len = *), intent(in):: units
120 ! 変数の単位
121 !
122 ! 最大文字数は dc_types::STRING
123 !
124 character(len = *), intent(in), optional:: xtype
125 ! 変数のデータ型
126 !
127 ! デフォルトはfloat (単精度実数型)
128 ! である。 有効なのは、
129 ! double (倍精度実数型)、 int
130 ! (整数型)、char (文字型)である。
131 ! 指定しない場合や、無効な型を指定した
132 ! 場合には、 float (単精度実数型)
133 ! となる。
134 !
135 logical, intent(in), optional:: time_average
136 ! 出力データを時間平均する場合には
137 ! .true. を与えます。
138 ! デフォルトは .false. です。
139 !
140 ! If output data is averaged in time direction,
141 ! specify ".true.".
142 ! Default is ".false.".
143 !
144 logical, intent(in), optional:: average
145 ! time_average の旧版.
146 ! Old version of "time_average"
147 type(gt_history), intent(inout), optional, target:: history
148 ! 出力ファイルの設定に関する情報を
149 ! 格納した構造体
150 !
151 ! ここに指定するものは、
152 ! HistoryCreate によって初期設定
153 ! されていなければなりません。
154 !
155 logical, intent(out), optional:: err
156 ! 例外処理用フラグ.
157 ! デフォルトでは, この手続き内でエラーが
158 ! 生じた場合, プログラムは強制終了します.
159 ! 引数 *err* が与えられる場合,
160 ! プログラムは強制終了せず, 代わりに
161 ! *err* に .true. が代入されます.
162 !
163 ! Exception handling flag.
164 ! By default, when error occur in
165 ! this procedure, the program aborts.
166 ! If this *err* argument is given,
167 ! .true. is substituted to *err* and
168 ! the program does not abort.
169 type(gt_history), pointer:: hst =>null()
170 type(gt_variable), pointer:: vwork(:) =>null(), dimvars(:) =>null()
171 character(STRING):: fullname, url, cause_c
172 integer, pointer:: count_work(:) =>null()
173 integer, pointer:: var_avr_count_work(:) =>null()
174 integer:: var_avr_length
175 type(gt_history_avrdata), pointer:: var_avr_data_work(:) =>null()
176 logical, pointer:: var_avr_firstput_work(:) =>null()
177 real(dp), pointer:: var_avr_coefsum_work(:) =>null()
178 real(dp), pointer:: var_avr_baseint_work(:) =>null()
179 real(dp), pointer:: var_avr_prevtime_work(:) =>null()
180!!$ type(DC_DIFFTIME), pointer:: var_avr_baseint_work(:) =>null()
181!!$ type(DC_DIFFTIME), pointer:: var_avr_prevtime_work(:) =>null()
182 character(STRING):: time_name, time_xtype, time_url
183 type(gt_variable), pointer:: dimvars_work(:) =>null()
184 logical, pointer:: dim_value_written_work(:) =>null()
185 integer:: dimvars_size
186 logical:: nv_exist, bnds_exist
187 character(STRING):: nv_name_check, bnds_name_check
188 character(*), parameter:: nv_suffix = '_nv'
189 character(*), parameter:: bnds_suffix = '_bnds'
190 integer, pointer:: dimord(:) =>null()
191 integer:: nvars, numdims, i, stat
192 character(*), parameter:: subname = "HistoryAddVariable1"
193 continue
194 call beginsub(subname, 'name=<%a>, dims=<%a>, longname=<%a>, units=<%a>', &
195 & ca=stoa(varname, joinchar(dims), longname, units))
196 stat = dc_noerr
197 cause_c = ''
198 ! 操作対象決定
199 !
200 if (present(history)) then
201 hst => history
202 else
203 hst => default
204 endif
205 ! 初期設定のチェック
206 ! Check initialization
207 !
208 if ( .not. hst % initialized ) then
209 stat = dc_enotinit
210 cause_c = 'GT_HISTORY'
211 goto 999
212 end if
213 ! 変数表拡張
214 !
215 if (associated(hst % vars)) then
216 nvars = size(hst % vars(:))
217 vwork => hst % vars
218 count_work => hst % count
219 nullify(hst % vars, hst % count)
220 allocate(hst % vars(nvars + 1), hst % count(nvars + 1))
221 hst % vars(1:nvars) = vwork(1:nvars)
222 hst % count(1:nvars) = count_work(1:nvars)
223 deallocate(vwork, count_work)
224 count_work => hst % growable_indices
225 nullify(hst % growable_indices)
226 allocate(hst % growable_indices(nvars + 1))
227 hst % growable_indices(1:nvars) = count_work(1:nvars)
228 deallocate(count_work)
229 ! 平均値出力のための変数表コピー
230 ! Copy table of variables for average value output
231 !
232 var_avr_count_work => hst % var_avr_count
233 nullify( hst % var_avr_count )
234 allocate( hst % var_avr_count(nvars + 1) )
235 hst % var_avr_count(1:nvars) = var_avr_count_work(1:nvars)
236 deallocate( var_avr_count_work )
237 var_avr_data_work => hst % var_avr_data
238 nullify(hst % var_avr_data)
239 allocate(hst % var_avr_data(nvars + 1))
240 do i = 1, nvars
241 hst % var_avr_data(i) % length = var_avr_data_work(i) % length
242 allocate(hst % var_avr_data(i) % &
243 & a_dataavr(var_avr_data_work(i) % length))
244 hst % var_avr_data(i) % a_DataAvr = var_avr_data_work(i) % a_DataAvr
245 deallocate( var_avr_data_work(i) % a_DataAvr )
246 end do
247 deallocate( var_avr_data_work )
248 var_avr_firstput_work => hst % var_avr_firstput
249 nullify( hst % var_avr_firstput )
250 allocate( hst % var_avr_firstput(nvars + 1) )
251 hst % var_avr_firstput(1:nvars) = var_avr_firstput_work(1:nvars)
252 deallocate( var_avr_firstput_work )
253 var_avr_coefsum_work => hst % var_avr_coefsum
254 nullify( hst % var_avr_coefsum )
255 allocate( hst % var_avr_coefsum(nvars + 1) )
256 hst % var_avr_coefsum(1:nvars) = var_avr_coefsum_work(1:nvars)
257 deallocate( var_avr_coefsum_work )
258 var_avr_baseint_work => hst % var_avr_baseint
259 nullify( hst % var_avr_baseint )
260 allocate( hst % var_avr_baseint(nvars + 1) )
261 hst % var_avr_baseint(1:nvars) = var_avr_baseint_work(1:nvars)
262 deallocate( var_avr_baseint_work )
263 var_avr_prevtime_work => hst % var_avr_prevtime
264 nullify( hst % var_avr_prevtime )
265 allocate( hst % var_avr_prevtime(nvars + 1) )
266 hst % var_avr_prevtime(1:nvars) = var_avr_prevtime_work(1:nvars)
267 deallocate( var_avr_prevtime_work )
268 else
269 ! トリッキーだが, ここで count だけ 2 要素確保するのは,
270 ! HistorySetTime による巻き戻しに備えるため.
271 !
272 allocate(hst % vars(1), hst % count(2), hst % growable_indices(1))
273 hst % count(2) = 0
274 allocate(hst % var_avr_count(1), hst % var_avr_data(1))
275 allocate(hst % var_avr_firstput(1), hst % var_avr_coefsum(1))
276 allocate(hst % var_avr_baseint(1), hst % var_avr_prevtime(1))
277 endif
278 nvars = size(hst % vars(:))
279 hst % growable_indices(nvars) = 0
280 if ( nvars < 2 ) then
281 hst % count(nvars) = 0
282 else
283 hst % count(nvars) = hst % count(1)
284 end if
285 ! スカラー変数作成への対応
286 !
287 if (size(dims) == 1 .and. trim(dims(1)) == '') then
288 numdims = 0
289 else
290 numdims = size(dims)
291 end if
292 allocate( dimvars(numdims) )
293 allocate( dimord(numdims) )
294 ! 次元の ID の取得
295 !
296 do, i = 1, numdims
297 ! hst 内で, 次元変数名 dim(i) に当たる次元変数の ID である
298 ! hst % dimvar(i) を dimvars(i) に, 添字を dimord に
299 !
300 dimvars(i) = lookup_dimension( hst, dims(i), & ! (in)
301 & ord = dimord(i) ) ! (out)
302 if (dimord(i) == 0) then
303 stat = nf90_ebaddim
304 cause_c = cprintf('"%c" dimension is not found.', c1=trim(dims(i)))
305 goto 999
306 end if
307 end do
308 ! 変数添字次元を決定
309 !
310 do, i = 1, numdims
311 ! 無制限次元の添字と一致する場合に,
312 ! その添字を hst % growable_indices(nvars) に
313 !
314 if (dimord(i) == hst % unlimited_index) then
315 hst % growable_indices(nvars) = i
316 endif
317 enddo
318 ! 変数作成
319 !
320 call inquire(hst % dimvars(1), url=url)
321 fullname = urlresolve((gt_atmark // trim(varname)), trim(url))
322 call create(hst % vars(nvars), trim(fullname), dimvars, xtype=xtype)
323 if ( associated(dimvars) ) deallocate( dimvars )
324 ! 拡張可能次元があったらそれをサイズ 1 に拡張しておく
325 !
326 if (hst % growable_indices(nvars) /= 0) then
327 call slice(hst % vars(nvars), hst % growable_indices(nvars), &
328 & start=1, count=1, stride=1)
329 endif
330 call put_attr(hst % vars(nvars), 'long_name', longname)
331 call put_attr(hst % vars(nvars), 'units', units)
332 ! 平均処理に関する情報管理
333 !
334 if ( present_and_true( time_average ) &
335 & .or. present_and_true( average ) ) then
336 hst % var_avr_count(nvars) = 0
337 ! 情報の取得
338 ! Get Information
339 !
340 call inquire( &
341 & var = hst % dimvars( hst % unlimited_index ), & ! (in)
342 & name = time_name, url = time_url, & ! (out)
343 & xtype = time_xtype ) ! (out)
344 ! 変数のデータ数の取得
345 !
346 call inquire(hst % vars(nvars), size = var_avr_length )
347 ! 割り付け
348 !
349 hst % var_avr_data(nvars) % length = var_avr_length
350 allocate(hst % var_avr_data(nvars) % a_DataAvr(var_avr_length))
351 hst % var_avr_data(nvars) % a_DataAvr = 0.0_dp
352 ! デフォルト値設定
353 !
354 hst % var_avr_firstput = .true.
355 hst % var_avr_coefsum(nvars) = 0.0_dp
356 hst % var_avr_baseint(nvars) = 0.0_dp
357!!$ call DCDiffTimeCreate( &
358!!$ & hst % var_avr_baseint(nvars), & ! (out)
359!!$ & sec = 0.0_DP ) ! (in)
360 hst % var_avr_prevtime(nvars) = hst % var_avr_baseint(nvars)
361 ! 時間次元情報の取得
362 !
363 if ( hst % growable_indices(nvars) < 1 ) then
364 stat = hst_enodependtime
365 cause_c = trim(varname)
366 goto 999
367 end if
368 ! 時間次元への属性 "bounds" の追加
369 !
370 call put_attr( var = hst % dimvars( hst % unlimited_index ), & ! (inout)
371 & name = 'bounds', & ! (in)
372 & value = trim(time_name) // bnds_suffix ) ! (in)
373 ! 変数 "varname" への属性 "cell_methods" の追加
374 !
375 call put_attr( var = hst % vars(nvars), & ! (inout)
376 & name = 'cell_methods', & ! (in)
377 & value = trim(time_name) // ': mean' ) ! (in)
378 ! "time_nv" 次元の作成 (既に作成されていたら何もしない)
379 !
380 dimvars_size = size( hst % dimvars )
381 nv_exist = .false.
382 do i = 1, dimvars_size
383 call inquire( &
384 & var = hst % dimvars(i), & ! (in)
385 & name = nv_name_check ) ! (out)
386 if ( trim(time_name) // trim(nv_suffix) == trim(nv_name_check) ) then
387 nv_exist = .true.
388 exit
389 end if
390 end do
391 if ( .not. nv_exist ) then
392 dimvars_work => hst % dimvars
393 dim_value_written_work => hst % dim_value_written
394 nullify(hst % dimvars, hst % dim_value_written)
395 allocate(hst % dimvars(dimvars_size + 1))
396 allocate(hst % dim_value_written(dimvars_size + 1))
397 hst % dimvars(1:dimvars_size) = dimvars_work(1:dimvars_size)
398 hst % dim_value_written(1:dimvars_size) = dim_value_written_work(1:dimvars_size)
399 deallocate(dimvars_work)
400 deallocate(dim_value_written_work)
401 call create( &
402 & var = hst % dimvars(dimvars_size + 1), & ! (out)
403 & url = trim(time_url) // trim(nv_suffix), & ! (in)
404 & length = 2, xtype = 'integer' ) ! (in)
405 hst % time_nv_index = dimvars_size + 1
406 call put_attr( var = hst % dimvars(dimvars_size + 1), & ! (inout)
407 & name = 'long_name', & ! (in)
408 & value = 'number of vertices of time') ! (in)
409 call put_attr( var = hst % dimvars(dimvars_size + 1), & ! (inout)
410 & name = 'units', value = '1' ) ! (in)
411 call put( var = hst % dimvars(dimvars_size + 1), & ! (inout)
412 & value = (/1, 2/) ) ! (in)
413 hst % dim_value_written(dimvars_size + 1) = .true.
414 end if
415 ! "time_bnds" 変数の作成 (既に作成されていたら何もしない)
416 !
417 bnds_exist = .false.
418 do i = 1, nvars
419 call inquire( &
420 & var = hst % vars(i), & ! (in)
421 & name = bnds_name_check ) ! (out)
422 if ( trim(time_name) // trim(bnds_suffix) == trim(bnds_name_check) ) then
423 bnds_exist = .true.
424 exit
425 end if
426 end do
427 if ( associated(dimord) ) deallocate( dimord )
428 if ( .not. bnds_exist ) then
429 call historyaddvariable( &
430 & history = hst, & ! (inout)
431 & varname = trim(time_name) // trim(bnds_suffix), &
432 & dims = stoa( trim(time_name) // trim(nv_suffix), &
433 & trim(time_name) ), & ! (in)
434 & longname = 'bounds of time', & ! (in)
435 & units = hst % unlimited_units, & ! (in)
436 & xtype = time_xtype ) ! (in)
437 end if
438 ! 平均処理が不要な場合
439 !
440 else
441 hst % var_avr_count(nvars) = -1
442 ! 割り付け
443 !
444 var_avr_length = 1
445 hst % var_avr_data(nvars) % length = var_avr_length
446 allocate(hst % var_avr_data(nvars) % a_DataAvr(var_avr_length))
447 hst % var_avr_data(nvars) % a_DataAvr = 0.0_dp
448 ! デフォルト値設定
449 !
450 hst % var_avr_firstput = .true.
451 hst % var_avr_coefsum(nvars) = 0.0_dp
452 hst % var_avr_baseint(nvars) = 0.0_dp
453!!$ call DCDiffTimeCreate( &
454!!$ & hst % var_avr_baseint(nvars), & ! (out)
455!!$ & sec = 0.0_DP ) ! (in)
456 hst % var_avr_prevtime(nvars) = hst % var_avr_baseint(nvars)
457 end if
458 ! 終了処理, 例外処理
459 ! Termination and Exception handling
460 !
461999 continue
462 if ( associated(dimvars) ) deallocate( dimvars )
463 if ( associated(dimord) ) deallocate( dimord )
464 call storeerror(stat, subname, err, cause_c)
465 call endsub(subname)
466 end subroutine historyaddvariable1
467!> @en
468 !> @brief Define a variable in history (varinfo interface)
469 !>
470 !> Defines a variable within gtool4 data using a GT_HISTORY_VARINFO
471 !> structure. HistoryCreate must be called beforehand.
472 !> @param[in] varinfo Variable information structure
473 !> @param[inout] history History structure (optional)
474 !> @param[out] err Error flag (optional)
475 !> @enden
476 !> @ja
477 !> @brief 変数定義 (varinfo インターフェース)
478 !>
479 !> GT_HISTORY_VARINFO 構造体を使って gtool4 データ内の変数の定義を
480 !> 行います。このサブルーチンを用いる前に、HistoryCreate による
481 !> 初期設定が必要です。
482 !> @param[in] varinfo 変数情報構造体
483 !> @param[inout] history 出力ファイル設定構造体 (省略可能)
484 !> @param[out] err エラーフラグ (省略可能)
485 !> @endja
487 & varinfo, history, err )
488 !
489 use dc_string, only: joinchar
493 use dc_trace, only: beginsub, endsub
494 implicit none
495 type(gt_history_varinfo), intent(in) :: varinfo
496 ! 変数情報を格納した構造体
497 !
498 ! ここに指定するものは、
499 ! HistoryVarinfoCreate によって
500 ! 初期設定されていなければなりません。
501 !
502 type(gt_history), intent(inout), optional:: history
503 ! 出力ファイルの設定に関する情報を
504 ! 格納した構造体
505 !
506 ! ここに指定するものは、
507 ! HistoryCreate によって初期設定
508 ! されていなければなりません。
509 !
510 logical, intent(out), optional:: err
511 ! 例外処理用フラグ.
512 ! デフォルトでは, この手続き内でエラーが
513 ! 生じた場合, プログラムは強制終了します.
514 ! 引数 *err* が与えられる場合,
515 ! プログラムは強制終了せず, 代わりに
516 ! *err* に .true. が代入されます.
517 !
518 ! Exception handling flag.
519 ! By default, when error occur in
520 ! this procedure, the program aborts.
521 ! If this *err* argument is given,
522 ! .true. is substituted to *err* and
523 ! the program does not abort.
524 character(len = *), parameter:: subname = "HistoryAddVariable2"
525 continue
526 call beginsub(subname, 'varname=<%c>, dims=<%c>, longname=<%c>', &
527 & c1=trim(varinfo % name), c2=trim(joinchar(varinfo % dims)), &
528 & c3=trim(varinfo % longname) )
529 call historyaddvariable( &
530 & history = history, & ! (inout)
531 & varname = varinfo % name, & ! (in)
532 & dims = varinfo % dims, & ! (in)
533 & longname = varinfo % longname, & ! (in)
534 & units = varinfo % units, & ! (in)
535 & xtype = varinfo % xtype, & ! (in)
536 & time_average = varinfo % time_average, & ! (in) optional
537 & err = err ) ! (out) optional
538 if (associated( varinfo % attrs )) then
539 call append_attrs( varinfo % name, varinfo % attrs, history )
540 end if
541 call endsub(subname)
542 end subroutine historyaddvariable2
subroutine historyaddvariable2(varinfo, history, err)
recursive subroutine historyaddvariable1(varname, dims, longname, units, xtype, time_average, average, history, err)
Derived types and parameters for date and time.
Date and time manipulation module.
Definition dc_date.f90:57
Error handling module.
Definition dc_error.f90:454
subroutine, public storeerror(number, where, err, cause_c, cause_i)
Definition dc_error.f90:891
integer, parameter, public dc_enotinit
-400 or less: DC utilities errors
Definition dc_error.f90:534
integer, parameter, public dc_noerr
Error storage variables
Definition dc_error.f90:468
integer, parameter, public hst_enodependtime
Definition dc_error.f90:562
integer, parameter, public hst_empinoaxisdata
Definition dc_error.f90:574
Message output module.
Judge optional control parameters.
logical function, public present_and_true(arg)
Handling character types.
Definition dc_string.f90:83
character(string) function, public joinchar(carray, expr)
Debug tracing module.
Definition dc_trace.f90:150
subroutine, public beginsub(name, fmt, i, r, d, l, n, c1, c2, c3, ca, version)
Definition dc_trace.f90:457
subroutine, public endsub(name, fmt, i, r, d, l, n, c1, c2, c3, ca)
Definition dc_trace.f90:580
Provides kind type parameter values.
Definition dc_types.f90:55
integer, parameter, public string
Character length for string
Definition dc_types.f90:137
integer, parameter, public dp
Double Precision Real number
Definition dc_types.f90:92
Variable URL string parser.
Definition dc_url.f90:61
character, parameter, public gt_atmark
Definition dc_url.f90:96
type(gt_history), target, save, public default