Class | gt4_historyauto_h |
In: |
gt4_historyauto_h.f90
|
module gt4_history のアプリケーション. 変数毎に時・空間に自由にサンプリングを設定できる. 長くなりそうな出力の時分割や並列化に対応.
その他の特徴
HistoryAutoCreate : | . |
HistoryAutoCopyCreate : | . |
HistoryAutoPut : | . |
HistoryAutoWhetherPutNow : | . |
GT4_ATTRIBUTE ( init_gt4_attribute ) : | . |
GT4_REAL1D ( init_gt4_real1d ) : | . |
GT4_NAMED_REALARY ( init_gt4_named_realary ) : | . |
Derived Type : | |
name : | character(len=TOKEN) |
rval(:) =>null() : | real,pointer |
ival(:) =>null() : | integer,pointer |
cval : | character(len=STRING) |
属性を名前と値の組で入れる
Derived Type : | |||
rank : | integer | ||
name : | character(len=TOKEN) | ||
dims(3) : | character(len=TOKEN)
| ||
longname : | character(len=STRING) | ||
units : | character(len=STRING) | ||
ary(:) =>null() : | real,pointer |
名前, 次元名, longname, units を持つ実数配列. 配列データは 1 次元で保持
Derived Type : | |
ary(:) => null() : | real,pointer |
to make an array of 1D arrays
配列の配列をつくるための型 (実数)
Subroutine : | |
name : | character(len=*), intent(in) |
longname : | character(len=*), intent(in) |
units : | character(len=*), intent(in) |
file : | character(len=*), intent(in),optional |
use the result of the latest call of HistoryAutoCreate
直前の HistoryAutoCreate を使って, 格子及び出力の空間・時間 サンプリングが同じ出力を定義する. file を省略すれば 同じファイルを使う.
subroutine HistoryAutoCopyCreate( name, longname, units, file ) ! ! use the result of the latest call of HistoryAutoCreate ! ! 直前の HistoryAutoCreate を使って, 格子及び出力の空間・時間 ! サンプリングが同じ出力を定義する. file を省略すれば ! 同じファイルを使う. ! character(len=*), intent(in) :: name character(len=*), intent(in) :: longname character(len=*), intent(in) :: units character(len=*), intent(in),optional :: file ! type(HIST_EACHVAR) :: hist type(HIST_EACHVAR),pointer :: histpt character(len = *), parameter:: subname = 'HistoryAutoCopyCreate' ! call BeginSub(subname) histpt => histpl_last(HISTPOOL) hist = histpt ! copy the contents if(present_and_not_empty(file)) then hist%file = file allocate(hist%h) ! always new allocation nullify(hist%h%hs) else hist%h => histpt%h endif hist%name = name hist%longname = longname hist%units = units call histpl_push(HISTPOOL, hist) call EndSub(subname) end subroutine HistoryAutoCopyCreate
Subroutine : | |||
name : | character(len=*), intent(in) | ||
longname : | character(len=*), intent(in) | ||
units : | character(len=*), intent(in) | ||
file : | character(len=*), intent(in) | ||
slfst(*) : | integer, intent(in)
| ||
sllst(*) : | integer, intent(in)
| ||
slstp(*) : | integer, intent(in)
| ||
time_to_start : | real, intent(in)
| ||
put_interval : | real, intent(in)
| ||
dt : | real, intent(in)
| ||
newfile_interval : | real, intent(in)
| ||
attrs(:) : | type(GT4_ATTRIBUTE),intent(in),optional | ||
aryshape(:) : | integer, intent(in)
| ||
dims(*) : | character(len=*), intent(in)
| ||
axlongnames(*) : | character(len=*), intent(in)
| ||
axunits(*) : | character(len=*), intent(in)
| ||
axxtypes(*) : | character(len=*), intent(in) | ||
spcoordvars(*) : | type(GT4_REAL1D),
intent(in)
| ||
ancilcrdvars(:) : | type(GT4_NAMED_REALARY),intent(in),optional | ||
title : | character(len=*), intent(in),optional | ||
source : | character(len=*), intent(in),optional | ||
institution : | character(len=*), intent(in),optional | ||
conventions : | character(len=*), intent(in),optional | ||
gt_version : | character(len=*), intent(in),optional | ||
proc : | character(len=*), intent(in),optional | ||
domain_div : | logical, intent(in),optional | ||
subdomfst(*) : | integer, intent(in),optional
|
ヒストリファイル初期化情報の設定. 実際のファイル初期化は 必要に応じて HistoryAutoPut が行う (時分割するときは適宜 クローズと初期化を繰り返さないとならないので, そういう 構造になる). なお, 一つのファイルへの出力に対して このサブルーチンを 2 回以上呼んではならない. 複数の 変数を一つのファイルに出したい場合は, HistoryAutoCopyCreate を利用せよ. 時・空間に自由にサンプリングを設定できる. 但し, いずれも等間隔. 長い時間積分によって, ファイルが 大きくなり過ぎることに対応するため, 一定の時間間隔で 分割することが可能. また, 並列化を念頭に各ノードを特定する 文字列を挿入することができる.
Alias for HistoryAutoCreateH1
Subroutine : | |||
name : | character(len=*), intent(in) | ||
longname : | character(len=*), intent(in) | ||
units : | character(len=*), intent(in) | ||
file : | character(len=*), intent(in) | ||
slfst(*) : | integer, intent(in)
| ||
sllst(*) : | integer, intent(in)
| ||
slstp(*) : | integer, intent(in)
| ||
time_to_start : | real, intent(in) | ||
put_interval : | real, intent(in) | ||
dt : | real, intent(in) | ||
newfile_interval : | real, intent(in) | ||
attrs(:) : | type(GT4_ATTRIBUTE),intent(in),optional | ||
grid_label : | character(len=*), intent(in)
| ||
title : | character(len=*), intent(in),optional | ||
source : | character(len=*), intent(in),optional | ||
institution : | character(len=*), intent(in),optional | ||
conventions : | character(len=*), intent(in),optional | ||
gt_version : | character(len=*), intent(in),optional | ||
proc : | character(len=*), intent(in),optional |
Alias for HistoryAutoCreateH2
Subroutine : | |
name : | character(len=*), intent(in) |
vals(*) : | real |
time : | real |
変数の出力を行う. タイミングは内部で制御するので, 全タイム ステップで呼べば良い. なお, 下記の HistoryAutoWhetherPutNow を使って呼ぶタイミングを制御しても良い.
Alias for HistoryAutoPutH0
Subroutine : | |||
grid_label : | character(len=*), intent(in) | ||
aryshape(:) : | integer, intent(in)
| ||
dims(:) : | character(len=*), intent(in)
| ||
axlongnames(:) : | character(len=*), intent(in)
| ||
axunits(:) : | character(len=*), intent(in)
| ||
axxtypes(:) : | character(len=*), intent(in) | ||
coord1(:) : | real, intent(in),optional
| ||
coord2(:) : | real, intent(in),optional
| ||
coord3(:) : | real, intent(in),optional
| ||
ancilcrdvars(:) : | type(GT4_NAMED_REALARY),intent(in),optional | ||
subdomfst(:) : | integer, intent(in),optional
|
subroutine HistoryAutoSetGrid( grid_label, aryshape, dims, axlongnames, axunits, axxtypes, coord1, coord2, coord3, ancilcrdvars, subdomfst ) use dc_error, only: USR_ERRNO, StoreError implicit none character(len=*), intent(in) :: grid_label integer, intent(in) :: aryshape(:) ! size <= 3 (--> sprank) character(len=*), intent(in) :: dims(:) !size == sprank+1 character(len=*), intent(in) :: axlongnames(:) !size == sprank+1 character(len=*), intent(in) :: axunits(:) !size == sprank+1 character(len=*), intent(in) :: axxtypes(:) real, intent(in),optional :: coord1(:) ! must present if sprank>=1 real, intent(in),optional :: coord2(:) ! must present if sprank>=2 real, intent(in),optional :: coord3(:) ! must present if sprank>=3 type(GT4_NAMED_REALARY),intent(in),optional :: ancilcrdvars(:) integer, intent(in),optional :: subdomfst(:) ! For domain-dividing comp. ! first indx relative in the whole dom. (size == sprank) ! type(HIST_EACHVAR) :: hist integer :: sprank character(len = *),parameter :: subname = "HistoryAutoSetGrid" continue call BeginSub(subname) sprank = min( size(aryshape), 3 ) hist%sprank = sprank hist%name = grid_label hist%aryshape(1:sprank) = aryshape(1:sprank) hist%dims(1:sprank+1) = dims(1:sprank+1) hist%axlongnames(1:sprank+1) = axlongnames(1:sprank+1) hist%axunits(1:sprank+1) = axunits(1:sprank+1) hist%axxtypes(1:sprank+1) = axxtypes(1:sprank+1) if (present(subdomfst)) then hist%domain_div = .true. hist%subdomfst(1:sprank) = subdomfst(1:sprank) else hist%domain_div = .false. endif if (sprank >= 1) hist%spcoordvars(1) = init_gt4_real1d( coord1 ) if (sprank >= 2) hist%spcoordvars(2) = init_gt4_real1d( coord2 ) if (sprank >= 3) hist%spcoordvars(3) = init_gt4_real1d( coord3 ) if(.not. present(ancilcrdvars)) then nullify(hist%ancilcrdvars) else if ( size(ancilcrdvars)==0 )then nullify(hist%ancilcrdvars) else allocate(hist%ancilcrdvars(size(ancilcrdvars))) ! always new alloc hist%ancilcrdvars = ancilcrdvars endif call histpl_push(HISTGRIDPOOL, hist) call EndSub(subname) end subroutine HistoryAutoSetGrid
Subroutine : | |
title : | character(len=*), intent(in), optional |
source : | character(len=*), intent(in), optional |
institution : | character(len=*), intent(in), optional |
proc : | character(len=*), intent(in), optional |
conventions : | character(len=*), intent(in), optional |
gt_version : | character(len=*), intent(in), optional |
subroutine HistoryAutoSetRunInfo( title, source, institution, proc, conventions, gt_version ) use dc_error, only: USR_ERRNO, StoreError implicit none character(len=*), intent(in), optional :: title, source, institution character(len=*), intent(in), optional :: proc character(len=*), intent(in), optional :: conventions, gt_version ! character(len = *),parameter :: subname = "HistoryAutoSetRunInfo" continue call BeginSub(subname) if (present(title)) com_title = title if (present(source)) com_source = source if (present(institution)) com_institution = institution if (present(proc)) com_proc = proc if (present(conventions)) com_conventions = conventions if (present(gt_version)) com_gt_version = gt_version call EndSub(subname) end subroutine HistoryAutoSetRunInfo
Function : | |
result : | logical |
name : | character(len=*), intent(in) |
time : | real, intent(in) |
name の名を持つ出力項目に関し, 現在がファイルに出力するタイミ ングかどうかを返す. 同名で複数の出力をする場合, どれか一つでも 出力するタイミングなら .true. を返す. 出力のために特別に計算を を要するようなケースに使うと良い. (ほとんどのステップで無駄に なる計算をするのを避けられる)
function HistoryAutoWhetherPutNow( name, time ) result(result) ! ! name の名を持つ出力項目に関し, 現在がファイルに出力するタイミ ! ングかどうかを返す. 同名で複数の出力をする場合, どれか一つでも ! 出力するタイミングなら .true. を返す. 出力のために特別に計算を ! を要するようなケースに使うと良い. (ほとんどのステップで無駄に ! なる計算をするのを避けられる) ! implicit none logical :: result character(len=*), intent(in) :: name real, intent(in) :: time ! integer :: ith type(HIST_EACHVAR),pointer :: hst character(len = *), parameter:: subname = 'HistoryAutoWhetherPutNow' logical :: put_now ! call BeginSub(subname) result = .false. ith = 1 do while( histpl_find(HISTPOOL, name, ith, hst) ) put_now = whether_to_put_now( time, hst%time_last, hst%time_to_start, hst%put_interval, hst%dt ) if (put_now) then result = .true. exit endif enddo call EndSub(subname) end function HistoryAutoWhetherPutNow
Function : | |
result : | type(GT4_ATTRIBUTE) |
name : | character(len=*),intent(in) |
rval(:) : | real,intent(in),optional |
ival(:) : | integer,intent(in),optional |
cval : | character(len=*),intent(in),optional |
ATTRIBUTEのコンストラクター. 名前 & (実数配列 or 整数配列 or 文字列) を与える
function init_gt4_attribute(name,rval,ival,cval) result(result) ! ! ATTRIBUTEのコンストラクター. ! 名前 & (実数配列 or 整数配列 or 文字列) を与える ! implicit none type(GT4_ATTRIBUTE) :: result character(len=*),intent(in) :: name real,intent(in),optional :: rval(:) integer,intent(in),optional :: ival(:) character(len=*),intent(in),optional :: cval result%name = name if(present(rval)) then allocate(result%rval(size(rval))) result%rval = rval nullify(result%ival) else if (present(ival)) then allocate(result%ival(size(ival))) result%ival = ival nullify(result%rval) else if (present(cval)) then nullify(result%rval) nullify(result%ival) result%cval = cval endif end function init_gt4_attribute
Function : | |
result : | type(GT4_NAMED_REALARY) |
name : | character(len=*),intent(in) |
rank : | integer,intent(in) |
dims(rank) : | character(len = *),intent(in) |
length : | integer,intent(in) |
ary(length) : | real,intent(in) |
longname : | character(len=*),intent(in) |
units : | character(len=*),intent(in) |
GT4_NAMED_REALARYのコンストラクター.
function init_gt4_named_realary(name,rank,dims,length,ary,longname,units) result(result) ! GT4_NAMED_REALARYのコンストラクター. use dc_error, only: USR_ERRNO, StoreError implicit none type(GT4_NAMED_REALARY) :: result ! character(len=*),intent(in) :: name integer,intent(in) :: rank character(len = *),intent(in) :: dims(rank) integer,intent(in) :: length real,intent(in) :: ary(length) character(len=*),intent(in) :: longname character(len=*),intent(in) :: units ! character(len = *), parameter:: subname = 'init_gt4_named_realary' ! call BeginSub(subname) if(rank>3 .or. rank<0) call StoreError(USR_ERRNO, subname, cause_c='rank must be <= 3 and >=1') result%rank = rank result%name = name result%dims(1:rank) = dims(1:rank) allocate(result%ary(length)) ! always new allocation result%ary(1:length) = ary(1:length) result%longname = longname result%units = units call EndSub(subname) end function init_gt4_named_realary
Function : | |
result : | type(GT4_REAL1D) |
ary(:) : | real,intent(in) |
REAL1Dのコンストラクター.
function init_gt4_real1d(ary) result(result) ! ! REAL1Dのコンストラクター. ! implicit none type(GT4_REAL1D) :: result real,intent(in) :: ary(:) if(associated(result%ary)) deallocate(result%ary) allocate(result%ary(size(ary))) result%ary = ary end function init_gt4_real1d
Derived Type : | |||
name : | character(len=TOKEN) | ||
h =>null() : | type(GTHP), pointer | ||
longname : | character(len=STRING) | ||
units : | character(len=STRING) | ||
size : | integer | ||
aryshape(3) : | integer | ||
slfst(3) : | integer | ||
sllst(3) : | integer | ||
slstp(3) : | integer | ||
domain_div : | logical | ||
subdomfst(3) : | integer
| ||
file : | character(len=STRING) | ||
proc : | character(len=TOKEN) | ||
newfile_interval : | real
| ||
title : | character(len=STRING) | ||
source : | character(len=STRING) | ||
institution : | character(len=STRING) | ||
sprank : | integer | ||
dims(4) : | character(len=TOKEN) | ||
dimsizes(4) : | integer | ||
axlongnames(4) : | character(len=STRING) | ||
axunits(4) : | character(len=STRING) | ||
axxtypes(4) : | character(len=TOKEN) | ||
time_last : | real | ||
time_to_start : | real | ||
put_interval : | real
| ||
dt : | real
| ||
conventions : | character(len=STRING) | ||
gt_version : | character(len=TOKEN) | ||
out_of_domain : | logical
| ||
spcoordvars(3) : | type(GT4_REAL1D) | ||
ancilcrdvars(:) =>null() : | type(GT4_NAMED_REALARY),pointer
| ||
attrs(:) =>null() : | type(GT4_ATTRIBUTE),pointer |
Derived Type : | |
name : | character(len=TOKEN) |
hist : | type(HIST_EACHVAR) |
next =>null() : | type(HIST_LINK),pointer |
Subroutine : | |||
name : | character(len=*), intent(in) | ||
longname : | character(len=*), intent(in) | ||
units : | character(len=*), intent(in) | ||
file : | character(len=*), intent(in) | ||
slfst(*) : | integer, intent(in)
| ||
sllst(*) : | integer, intent(in)
| ||
slstp(*) : | integer, intent(in)
| ||
time_to_start : | real, intent(in)
| ||
put_interval : | real, intent(in)
| ||
dt : | real, intent(in)
| ||
newfile_interval : | real, intent(in)
| ||
attrs(:) : | type(GT4_ATTRIBUTE),intent(in),optional | ||
aryshape(:) : | integer, intent(in)
| ||
dims(*) : | character(len=*), intent(in)
| ||
axlongnames(*) : | character(len=*), intent(in)
| ||
axunits(*) : | character(len=*), intent(in)
| ||
axxtypes(*) : | character(len=*), intent(in) | ||
spcoordvars(*) : | type(GT4_REAL1D),
intent(in)
| ||
ancilcrdvars(:) : | type(GT4_NAMED_REALARY),intent(in),optional | ||
title : | character(len=*), intent(in),optional | ||
source : | character(len=*), intent(in),optional | ||
institution : | character(len=*), intent(in),optional | ||
conventions : | character(len=*), intent(in),optional | ||
gt_version : | character(len=*), intent(in),optional | ||
proc : | character(len=*), intent(in),optional | ||
domain_div : | logical, intent(in),optional | ||
subdomfst(*) : | integer, intent(in),optional
|
ヒストリファイル初期化情報の設定. 実際のファイル初期化は 必要に応じて HistoryAutoPut が行う (時分割するときは適宜 クローズと初期化を繰り返さないとならないので, そういう 構造になる). なお, 一つのファイルへの出力に対して このサブルーチンを 2 回以上呼んではならない. 複数の 変数を一つのファイルに出したい場合は, HistoryAutoCopyCreate を利用せよ. 時・空間に自由にサンプリングを設定できる. 但し, いずれも等間隔. 長い時間積分によって, ファイルが 大きくなり過ぎることに対応するため, 一定の時間間隔で 分割することが可能. また, 並列化を念頭に各ノードを特定する 文字列を挿入することができる.
subroutine HistoryAutoCreateH1( name, longname, units, file, slfst, sllst, slstp, time_to_start, put_interval, dt, newfile_interval, attrs, aryshape, dims, axlongnames, axunits, axxtypes, spcoordvars, ancilcrdvars, title, source, institution, conventions, gt_version, proc, domain_div, subdomfst ) ! ! ヒストリファイル初期化情報の設定. 実際のファイル初期化は ! 必要に応じて HistoryAutoPut が行う (時分割するときは適宜 ! クローズと初期化を繰り返さないとならないので, そういう ! 構造になる). なお, 一つのファイルへの出力に対して ! このサブルーチンを 2 回以上呼んではならない. 複数の ! 変数を一つのファイルに出したい場合は, HistoryAutoCopyCreate ! を利用せよ. ! 時・空間に自由にサンプリングを設定できる. ! 但し, いずれも等間隔. 長い時間積分によって, ファイルが ! 大きくなり過ぎることに対応するため, 一定の時間間隔で ! 分割することが可能. また, 並列化を念頭に各ノードを特定する ! 文字列を挿入することができる. ! use dc_error, only: USR_ERRNO, StoreError implicit none character(len=*), intent(in) :: name character(len=*), intent(in) :: longname character(len=*), intent(in) :: units character(len=*), intent(in) :: file integer, intent(in) :: slfst(*) ! size == sprank ! 空間データのスライス (開始点の指定. ! 指定はデータの値ではなく, 格子点添字) integer, intent(in) :: sllst(*) ! size == sprank ! 空間データのスライス (終了点の指定. ! 指定はデータの値ではなく, 格子点添字). ! 0 を指定する場合には, データの最後尾を ! 終了点とする. integer, intent(in) :: slstp(*) ! size == sprank ! 空間データのスライス (刻み幅の指定. ! 指定はデータの値ではなく, 格子点添字). real, intent(in) :: time_to_start ! 出力開始時刻 real, intent(in) :: put_interval ! データ出力間隔 real, intent(in) :: dt ! モデルのΔt (時刻を自動で進めるためではなく, ! 時刻の許容誤差を測るためのもの). real, intent(in) :: newfile_interval ! ファイルを分割する時間間隔. ! 負の値を与えると分割を行わない. type(GT4_ATTRIBUTE),intent(in),optional :: attrs(:) integer, intent(in) :: aryshape(:) ! size <= 3 (--> sprank) ! 次元サイズの指定 character(len=*), intent(in) :: dims(*) !size == sprank+1 character(len=*), intent(in) :: axlongnames(*) !size == sprank+1 character(len=*), intent(in) :: axunits(*) !size == sprank+1 character(len=*), intent(in) :: axxtypes(*) type(GT4_REAL1D), intent(in) :: spcoordvars(*) ! size == sprank type(GT4_NAMED_REALARY),intent(in),optional :: ancilcrdvars(:) character(len=*), intent(in),optional :: proc character(len=*), intent(in),optional :: title, source, institution character(len=*), intent(in),optional :: conventions, gt_version logical, intent(in),optional :: domain_div integer, intent(in),optional :: subdomfst(*) ! For domain-dividing comp. ! first indx relative in the whole dom. (size == sprank) ! type(HIST_EACHVAR) :: hist integer :: sprank,i,slf character(len = *),parameter :: subname = "HistoryAutoCreate1" call BeginSub(subname) !< initialize hist except hist%h -- actual creation is deferred > hist%time_last = -1e35 ! time_last_inival allocate(hist%h) ! always new allocation nullify(hist%h%hs) hist%name = name hist%longname = longname hist%units = units sprank = min( size(aryshape), 3 ) hist%sprank = sprank if ( present_and_true(domain_div) ) then hist%domain_div = .true. if (.not. present(subdomfst)) call StoreError(USR_ERRNO, subname, cause_c='When domain_div is present and true, subdomfst '// 'must also be present.') else hist%domain_div = .false. end if if (hist%domain_div .and. (minval(slfst(1:sprank)).le.0 .or. minval(sllst(1:sprank)).lt.0) ) then call StoreError(USR_ERRNO, subname, cause_c='When the domain is divided, output-domain '// 'limiting from the end by using negative indices is not '// 'available, since the whole domain size is not known. '// 'Use a postive number (or zero for sllst to express the'// ' last grid point).') endif hist%size = 1 hist%out_of_domain = .false. ! Init. May be true in domain division. do i=1,sprank hist%aryshape(i) = aryshape(i) if(slstp(i) > 0) then hist%slstp(i) = slstp(i) else hist%slstp(i) = 1 endif if (.not.hist%domain_div) then if(slfst(i) > 0) then hist%slfst(i) = slfst(i) else hist%slfst(i) = slfst(i) + aryshape(i) endif if(sllst(i) > 0) then hist%sllst(i) = sllst(i) else hist%sllst(i) = sllst(i) + aryshape(i) endif else slf = slfst(i) - subdomfst(i) + 1 if (slf.le.0) then slf = modulo(slf-1,hist%slstp(i)) + 1 else if(slf.gt.aryshape(i)) then hist%out_of_domain = .true. endif hist%slfst(i) = slf if (sllst(i).eq.0) then hist%sllst(i) = aryshape(i) else hist%sllst(i) = min( sllst(i) - subdomfst(i) + 1, aryshape(i) ) if (hist%sllst(i).le.0) then hist%out_of_domain = .true. endif endif endif hist%dimsizes(i) = (hist%sllst(i)-hist%slfst(i))/hist%slstp(i) + 1 if (.not.hist%domain_div) then if (hist%slfst(i)<=0 .or. hist%slfst(i)>aryshape(i)) call StoreError(USR_ERRNO, subname, cause_c= 'str not within the index range for dim:',cause_i=i) if (hist%sllst(i)<=0 .or. hist%sllst(i)>aryshape(i)) call StoreError(USR_ERRNO, subname, cause_c= 'end not within the index range for dim:',cause_i=i) if (hist%slstp(i)<=0) call StoreError(USR_ERRNO, subname, cause_c='step not positive for dim:', cause_i=i) if (hist%dimsizes(i)<=0) call StoreError(USR_ERRNO, subname, cause_c='negative dimsize for dim:', cause_i=i) endif hist%size = hist%size * hist%dimsizes(i) enddo hist%dimsizes(sprank+1) = 0 ! unlimited dimension hist%file = file hist%newfile_interval = newfile_interval hist%dims(1:sprank+1) = dims(1:sprank+1) hist%axlongnames(1:sprank+1) = axlongnames(1:sprank+1) hist%axunits(1:sprank+1) = axunits(1:sprank+1) hist%time_to_start = time_to_start hist%put_interval = put_interval hist%dt = dt hist%axxtypes(1:sprank+1) = axxtypes(1:sprank+1) if(present(title)) then hist%title = title else hist%title = com_title endif if(present(source)) then hist%source = source else hist%source = com_source endif if(present(institution)) then hist%institution = institution else hist%institution = com_institution endif if(present(conventions)) then hist%conventions = conventions else hist%conventions = com_conventions endif if(present(gt_version)) then hist%gt_version = gt_version else hist%gt_version = com_gt_version endif if(present(proc)) then hist%proc = proc else hist%proc = com_proc endif hist%spcoordvars(1:sprank) = spcoordvars(1:sprank) if(.not. present(ancilcrdvars)) then nullify(hist%ancilcrdvars) else if ( size(ancilcrdvars)==0 )then nullify(hist%ancilcrdvars) else allocate(hist%ancilcrdvars(size(ancilcrdvars))) ! always new alloc hist%ancilcrdvars = ancilcrdvars endif if(.not. present(attrs)) then nullify(hist%attrs) else if ( size(attrs)==0 )then nullify(hist%attrs) else allocate(hist%attrs(size(attrs))) ! always new alloc hist%attrs = attrs endif call histpl_push(HISTPOOL, hist) call EndSub(subname) end subroutine HistoryAutoCreateH1
Subroutine : | |||
name : | character(len=*), intent(in) | ||
longname : | character(len=*), intent(in) | ||
units : | character(len=*), intent(in) | ||
file : | character(len=*), intent(in) | ||
slfst(*) : | integer, intent(in)
| ||
sllst(*) : | integer, intent(in)
| ||
slstp(*) : | integer, intent(in)
| ||
time_to_start : | real, intent(in) | ||
put_interval : | real, intent(in) | ||
dt : | real, intent(in) | ||
newfile_interval : | real, intent(in) | ||
attrs(:) : | type(GT4_ATTRIBUTE),intent(in),optional | ||
grid_label : | character(len=*), intent(in)
| ||
title : | character(len=*), intent(in),optional | ||
source : | character(len=*), intent(in),optional | ||
institution : | character(len=*), intent(in),optional | ||
conventions : | character(len=*), intent(in),optional | ||
gt_version : | character(len=*), intent(in),optional | ||
proc : | character(len=*), intent(in),optional |
subroutine HistoryAutoCreateH2( name, longname, units, file, slfst, sllst, slstp, time_to_start, put_interval, dt, newfile_interval, attrs, grid_label, title, source, institution, conventions, gt_version, proc ) use dc_error, only: USR_ERRNO, USR_ERRNO, StoreError implicit none character(len=*), intent(in) :: name character(len=*), intent(in) :: longname character(len=*), intent(in) :: units character(len=*), intent(in) :: file integer, intent(in) :: slfst(*) ! size == sprank integer, intent(in) :: sllst(*) ! size == sprank integer, intent(in) :: slstp(*) ! size == sprank real, intent(in) :: time_to_start, put_interval, dt real, intent(in) :: newfile_interval type(GT4_ATTRIBUTE),intent(in),optional :: attrs(:) character(len=*), intent(in) :: grid_label ! <-- HistoryAutoSetGrid character(len=*), intent(in),optional :: proc character(len=*), intent(in),optional :: title, source, institution character(len=*), intent(in),optional :: conventions, gt_version ! type(HIST_EACHVAR),pointer :: hist integer :: ith character(len = *),parameter :: subname = "HistoryAutoCreate2" call BeginSub(subname) ith = 1 if (.not.histpl_find(HISTGRIDPOOL, grid_label, ith, hist)) then call StoreError(USR_ERRNO, subname, cause_c='grid '//trim(subname)//' not found') endif call HistoryAutoCreate1( name, longname, units, file, slfst, sllst, slstp, time_to_start, put_interval, dt, newfile_interval, attrs, hist%aryshape(1:hist%sprank), hist%dims(1:hist%sprank+1), hist%axlongnames(1:hist%sprank+1), hist%axunits(1:hist%sprank+1), hist%axxtypes(1:hist%sprank+1), hist%spcoordvars, hist%ancilcrdvars, title, source, institution, conventions, gt_version, proc, hist%domain_div, hist%subdomfst ) call EndSub(subname) end subroutine HistoryAutoCreateH2
Subroutine : | |
name : | character(len=*), intent(in) |
vals(*) : | real |
time : | real |
変数の出力を行う. タイミングは内部で制御するので, 全タイム ステップで呼べば良い. なお, 下記の HistoryAutoWhetherPutNow を使って呼ぶタイミングを制御しても良い.
subroutine HistoryAutoPutH0(name, vals, time) ! ! 変数の出力を行う. タイミングは内部で制御するので, 全タイム ! ステップで呼べば良い. なお, 下記の HistoryAutoWhetherPutNow ! を使って呼ぶタイミングを制御しても良い. ! implicit none character(len=*), intent(in) :: name real :: vals(*) real :: time ! type(HIST_EACHVAR),pointer :: hst integer :: ith, j, rank character(len=STRING) :: file_actual real :: eps=3e-7, newest type(GT_HISTORY),pointer :: hist logical :: put_now integer :: arysize real,pointer :: subset(:) character(len = *), parameter:: subname = 'HistoryAutoPut' ! call BeginSub(subname, 'name=<%c>, time=<%r>', c1=trim(name), r=(/time/)) ith = 1 do while( histpl_find(HISTPOOL, name, ith, hst) ) put_now = whether_to_put_now( time, hst%time_last, hst%time_to_start, hst%put_interval, hst%dt ) if ( put_now .and. .not.hst%out_of_domain ) then if ( associated(hst%h%hs) ) then call HistoryInquire(hst%h%hs, newest=newest) if ( hst%newfile_interval > 0 .and. time >= hst%time_to_start+hst%newfile_interval*(1.0-eps) .and. newest < time) then ! to make a new file hst%time_to_start = hst%time_to_start + hst%newfile_interval call HistoryClose(hst%h%hs) nullify(hst%h%hs) endif endif if (.not.associated(hst%h%hs)) then if (hst%newfile_interval > 0) then file_actual = merge_file_proc_time(hst%file,hst%proc, hst%time_to_start) else file_actual = merge_file_proc_time(hst%file,hst%proc) endif rank = hst%sprank + 1 allocate(hist) ! always new allocataion call HistoryCreate( file_actual, trim(hst%title), trim(hst%source), trim(hst%institution), hst%dims(1:rank), hst%dimsizes(1:rank), hst%axlongnames(1:rank), hst%axunits(1:rank), hst%time_to_start, hst%put_interval, hst%axxtypes(1:rank), hist, trim(hst%conventions), trim(hst%gt_version)) hst%h%hs => hist call HistoryAddVariable(name, hst%dims(1:rank), trim(hst%longname), trim(hst%units), history=hst%h%hs) if (associated(hst%attrs)) then do j=1,size(hst%attrs) call add_gt4_attribute(hst, hst%attrs(j)) enddo endif if (associated(hst%ancilcrdvars)) then do j=1,size(hst%ancilcrdvars) call add_ancilcrdvar(hst, hst%ancilcrdvars(j)) enddo endif do j=1,hst%sprank subset => make_slice(hst%spcoordvars(j)%ary, 1, (/hst%aryshape(j)/), (/hst%slfst(j)/), (/hst%sllst(j)/), (/hst%slstp(j)/) ) if (associated(subset)) then call HistoryPut(hst%dims(j), subset, hst%h%hs) else call HistoryPut(hst%dims(j), hst%spcoordvars(j)%ary, hst%h%hs) endif enddo if (associated(hst%ancilcrdvars)) then do j=1,size(hst%ancilcrdvars) call put_ancilcrdvar(hst, hst%ancilcrdvars(j)) enddo endif call HistorySetTime(time, hst%h%hs) else rank = hst%sprank + 1 if ( .not. HistoryHasVariable(hst%h%hs, name) ) then call HistoryAddVariable(name, hst%dims(1:rank), trim(hst%longname), trim(hst%units), history=hst%h%hs) !" ここで HistorySetTime すると問題が起きるので前回に従う if (associated(hst%attrs)) then do j=1,size(hst%attrs) call add_gt4_attribute(hst, hst%attrs(j)) enddo endif else call HistorySetTime(time, hst%h%hs) endif endif arysize = product(hst%aryshape(1:hst%sprank)) subset => make_slice(vals(1:arysize), hst%sprank, (/hst%aryshape/), (/hst%slfst/), (/hst%sllst/), (/hst%slstp/)) if (associated(subset)) then call HistoryPut(name, subset, hst%h%hs) else call HistoryPut(name, vals(1:hst%size), hst%h%hs) endif hst%time_last = time endif enddo call EndSub(subname) end subroutine HistoryAutoPutH0
Function : | |
result : | logical |
history : | type(GT_HISTORY), intent(in) |
varname : | character(len = *) |
logical function HistoryHasVariable(history, varname) result(result) implicit none type(GT_HISTORY), intent(in):: history character(len = *):: varname type(GT_HISTORY_VARINFO), pointer :: varinfo(:) =>null() integer:: i logical :: err character(STRING) :: name result = .false. call Inquire(history, err = err, varinfo = varinfo) do i = 1, size(varinfo) call Inquire(varinfo(i), name=name) if (name == varname) then result = .true. return endif end do return end function HistoryHasVariable
Subroutine : | |
hst : | type(HIST_EACHVAR),intent(inout) |
var : | type(GT4_NAMED_REALARY),intent(in) |
subroutine add_ancilcrdvar(hst, var) implicit none type(HIST_EACHVAR),intent(inout) :: hst type(GT4_NAMED_REALARY),intent(in) :: var ! integer :: rank ! rank = var%rank call HistoryAddVariable(var%name, var%dims(1:rank), trim(var%longname), trim(var%units), history=hst%h%hs) end subroutine add_ancilcrdvar
Subroutine : | |
hst : | type(HIST_EACHVAR),intent(inout) |
attr : | type(GT4_ATTRIBUTE),intent(in) |
subroutine add_gt4_attribute(hst, attr) implicit none type(HIST_EACHVAR),intent(inout) :: hst type(GT4_ATTRIBUTE),intent(in) :: attr ! if( hst%name /= "" ) then if(associated(attr%rval)) then call HistoryAddAttr(hst%name, attr%name, attr%rval, hst%h%hs) else if(associated(attr%rval)) then call HistoryAddAttr(hst%name, attr%name, attr%ival, hst%h%hs) else call HistoryAddAttr(hst%name, attr%name, trim(attr%cval), hst%h%hs) endif endif end subroutine add_gt4_attribute
Function : | |||
result : | logical
| ||
histpl : | type(HIST_LINK),pointer
| ||
name : | character(len=*), intent(in) | ||
ith : | integer, intent(inout)
| ||
hist : | type(HIST_EACHVAR),pointer |
function histpl_find(histpl, name,ith,hist) result(result) implicit none logical :: result ! .true. if found type(HIST_LINK),pointer :: histpl ! intent(in) character(len=*), intent(in) :: name integer, intent(inout) :: ith ! ith+=1 when return (to iterate) type(HIST_EACHVAR),pointer :: hist ! type(HIST_LINK),pointer,save :: hp integer,save :: cnt=1 character(len=TOKEN),save :: name_save = '' ! if(name/=name_save .or. ith<cnt) then cnt = 1 hp => histpl endif do while (associated(hp)) !!print *,trim(name),ith,cnt,trim(hp%name) if (hp%name == name) then if(cnt==ith) then !!print *,' ...found' hist => hp%hist result = .true. ! found name_save = name ! save the name found ith = ith+1 ! stepped forward for the next search cnt = cnt + 1 ! stepped forward for the next search hp => hp%next ! stepped forward for the next search return endif cnt = cnt + 1 endif hp => hp%next end do !!print *,' ...not found' result = .false. ! not found name_save = '' ! initialize cnt = 1 ! initialize end function histpl_find
Function : | |||
result : | type(HIST_EACHVAR),pointer | ||
histpl : | type(HIST_LINK),pointer
|
function histpl_last(histpl) result(result) implicit none type(HIST_EACHVAR),pointer :: result type(HIST_LINK),pointer :: histpl ! intent(in) ! type(HIST_LINK),pointer :: hp hp => histpl_to_the_end(histpl) result => hp%hist end function histpl_last
Subroutine : | |||
histpl : | type(HIST_LINK),pointer
| ||
hist : | type(HIST_EACHVAR),intent(in) |
subroutine histpl_push(histpl, hist) implicit none type(HIST_LINK),pointer :: histpl ! intent(in) type(HIST_EACHVAR),intent(in) :: hist ! type(HIST_LINK),pointer :: hp, nxt hp => histpl_to_the_end(histpl) if ( .not. associated(hp) ) then ! must be the first time allocate(hp) ! always new allocation histpl => hp else allocate(nxt) hp%next => nxt hp => nxt endif hp%hist = hist hp%name = hist%name end subroutine histpl_push
Function : | |||
result : | type(HIST_LINK),pointer | ||
histpl : | type(HIST_LINK),pointer
|
function histpl_to_the_end(histpl) result(result) type(HIST_LINK),pointer :: result type(HIST_LINK),pointer :: histpl ! intent(in) result => histpl do while (associated(result)) if (associated(result%next)) then result => result%next else exit endif end do end function histpl_to_the_end
Function : | |
result : | real,pointer,dimension(:) |
vals(:) : | real,intent(in) |
rank : | integer,intent(in) |
aryshape(*) : | integer,intent(in) |
slfst(*) : | integer,intent(in) |
sllst(*) : | integer,intent(in) |
slstp(*) : | integer,intent(in) |
function make_slice(vals, rank, aryshape, slfst, sllst, slstp) result(result) implicit none real,pointer,dimension(:) :: result real,intent(in) :: vals(:) integer,intent(in) :: rank integer,intent(in) :: aryshape(*) integer,intent(in) :: slfst(*) integer,intent(in) :: sllst(*) integer,intent(in) :: slstp(*) ! integer :: i,slsize logical :: slicing_needed real,pointer :: v1(:),v2(:,:),v3(:,:,:) character(len = *), parameter:: subname = 'make_slice' ! call BeginSub(subname) nullify(result) ! slicing_needed = .false. do i=1,rank if (slfst(i)/=1) slicing_needed = .true. if (sllst(i)/=aryshape(i)) slicing_needed = .true. if (slstp(i)/=1) slicing_needed = .true. enddo slsize = 1 do i=1,rank slsize = slsize * ( (sllst(i)-slfst(i))/slstp(i) + 1 ) enddo if(.not.slicing_needed) then nullify(result) else if(associated(result)) deallocate(result) allocate(result(slsize)) select case(rank) case (1) if(associated(v1)) deallocate(v1) allocate(v1(aryshape(1))) v1 = reshape(vals,(/aryshape(1:1)/)) result = v1(slfst(1):sllst(1):slstp(1)) case (2) if(associated(v2)) deallocate(v2) allocate(v2(aryshape(1),aryshape(2))) v2 = reshape(vals,(/aryshape(1:2)/)) result = reshape( v2(slfst(1):sllst(1):slstp(1), slfst(2):sllst(2):slstp(2)), (/slsize/) ) case (3) if(associated(v3)) deallocate(v3) allocate(v3(aryshape(1),aryshape(2),aryshape(3))) v3 = reshape(vals,(/aryshape(1:3)/)) result = reshape( v3(slfst(1):sllst(1):slstp(1), slfst(2):sllst(2):slstp(2), slfst(3):sllst(3):slstp(3)), (/slsize/) ) end select endif call EndSub(subname) end function make_slice
Function : | |
result : | character(len=STRING) |
file : | character(len=*), intent(in) |
proc : | character(len=*), intent(in) |
time : | real, intent(in), optional |
function merge_file_proc_time(file,proc,time) result(result) implicit none character(len=STRING) :: result character(len=*), intent(in) :: file character(len=*), intent(in) :: proc real, intent(in), optional :: time ! integer :: idx character(len=TOKEN) :: ctime character(len=10) :: fmt ! if(.not.present(time)) then ctime = "" else if (aint(time) == time) then fmt = "(I)" write(ctime,fmt=fmt) nint(time) idx = index(ctime, '.') if (idx>0) ctime = ctime(1:idx-1) else write(ctime,*) time endif ctime = '_t'//adjustl(ctime)//'-' endif ! if (proc == "") then result = file else idx = index(file, '.nc', .true.) ! tru -> search the right-most match if (idx == 0) then result = trim(file) // trim(adjustl(proc)) else if (idx /= 1) then result = file(1:idx-1) // trim(adjustl(proc)) // '.nc' else result = trim(adjustl(proc)) // '.nc' endif endif if (ctime == "") then ! do nothing else idx = index(result, '.nc', .true.) !tru-> search the right-most match if (idx == 0) then result = trim(result) // trim(adjustl(ctime)) else if (idx /= 1) then result = result(1:idx-1) // trim(adjustl(ctime)) // '.nc' else result = trim(adjustl(ctime)) // '.nc' endif endif end function merge_file_proc_time
Function : | |
result : | logical |
arg : | character(len=*),intent(in),optional |
function present_and_not_empty(arg) result(result) logical :: result character(len=*),intent(in),optional :: arg if(present(arg)) then if(arg/="") then result=.true. else result=.false. endif else result=.false. endif end function present_and_not_empty
Subroutine : | |
hst : | type(HIST_EACHVAR),intent(inout) |
var : | type(GT4_NAMED_REALARY),intent(in) |
subroutine put_ancilcrdvar(hst, var) use dc_error, only: GT_ENOMATCHDIM, StoreError implicit none type(HIST_EACHVAR),intent(inout) :: hst type(GT4_NAMED_REALARY),intent(in) :: var ! integer :: rank,i,j integer,allocatable :: idx(:) real,pointer :: subset(:) character(len=*), parameter :: subname = 'put_ancilcrdvar' ! call BeginSub(subname) rank = var%rank allocate(idx(rank)) loopi: do i=1,rank do j=1,hst%sprank if ( var%dims(i) == hst%dims(j) ) then idx(i)=j cycle loopi endif enddo call StoreError(GT_ENOMATCHDIM, subname) enddo loopi subset => make_slice(var%ary, rank, (/hst%aryshape(idx)/), (/hst%slfst(idx)/), (/hst%sllst(idx)/), (/hst%slstp(idx)/)) if (associated(subset)) then call HistoryPut(var%name, subset, hst%h%hs) else call HistoryPut(var%name, var%ary, hst%h%hs) endif deallocate(idx) call EndSub(subname) end subroutine put_ancilcrdvar
Function : | |
result : | logical |
time_now : | real, intent(in) |
time_last : | real, intent(in) |
time_to_start : | real, intent(in) |
put_interval : | real, intent(in) |
dt : | real, intent(in) |
function whether_to_put_now( time_now, time_last, time_to_start, put_interval, dt ) result(result) implicit none logical :: result real, intent(in) :: time_now real, intent(in) :: time_last real, intent(in) :: time_to_start real, intent(in) :: put_interval real, intent(in) :: dt ! real :: next_put_time real :: eps character(len = *), parameter:: subname = 'whether_to_put_now' call BeginSub(subname) eps = dt * 1e-3 ! allowable error in time in float if (time_now < time_to_start - eps) then result = .false. return end if next_put_time = time_last + put_interval ! initially very small because ! of the init val of time_last if ( time_now >= (next_put_time - eps) ) then result = .true. else result = .false. endif call EndSub(subname) end function whether_to_put_now