!---------------------------------------------------------------------
!     Copyright (C) GFD Dennou Club, 2004. All rights reserved.
!---------------------------------------------------------------------
! histget.f90 - Sample program for gt4_history/gt4f90io.
!               Test Program for "HistoryGet".
!
! History
!   2004/03/31 Morikawa Yasuhiro     create
!   2004/08/05 Morikawa Yasuhiro     add "single & double precision check"
!   2004/08/08 Morikawa Yasuhiro     change to pointer array test

program histget
    use gt4f90io
    use dc_trace,   only: SetDebug, DataDump
    use dc_message, only: MessageNotify
    use dc_types,   only: string
    use gt4_history
implicit none
    integer            :: i,j,k,l                        ! 作業変数
    integer, parameter :: nx=10, ny=20, nz=30            ! グリッド数
    real,    parameter :: x(nx)=(/(1.0*(i-1),i=1,nx)/)   ! x座標変数
    real(8), parameter :: y(ny)=(/(10.0*(i-1),i=1,ny)/)  ! y座標変数
    real(8), parameter :: z(nz)=(/(100.0*(i-1),i=1,nz)/) ! z座標変数

    real   , target    :: u           ! 出力用無次元配列
    real(8), target    :: v(nx)       ! 出力用 1 次元配列
    real(8), target    :: v2(nz)      ! 出力用 1 次元配列その2
    real   , target    :: w(nx,ny)    ! 出力用 2 次元配列
    real(8), target    :: q(nx,ny,nz) ! 出力用 3 次元配列

    real   , pointer   :: up          ! 入力用無次元配列ポインタ
    real(8), pointer   :: vp(:)       ! 入力用 1 次元配列ポインタ
    real   , pointer   :: wp(:,:)     ! 入力用 2 次元配列ポインタ
    real(8), pointer   :: qp(:,:,:)   ! 入力用 3 次元配列ポインタ

    real   , pointer   :: xp(:)       ! 入力用 x座標元配列ポインタ
    real(8), pointer   :: yp(:)       ! 入力用 y座標元配列ポインタ
    real(8), pointer   :: zp(:)       ! 入力用 z座標元配列ポインタ

    character(string), parameter  :: subname = 'histget'
continue

    call SetDebug

    !-----------------------------------------------------------------
    ! まずは入力用のファイルを作成
    !-----------------------------------------------------------------

    call HistoryCreate(file='xhistget/xhistget1.nc', &
        & title='gt4_history HistoryGet test 1', &
        & source='gt4f90io/Fortran library test kit', &
        & institution='GFD Dennou Club', &
        & dims=(/'x','y','z','t'/), &
        & dimsizes=(/10,20,30,0/), &
        & longnames=(/'X-coordinate','Y-coordinate', &
                   &  'Z-coordinate','time        '/), &
        & units=(/'m','m','m','s'/), &
        & origin=0.0, interval=0.2, &
        & xtypes=(/'real  ','double','double','real  '/))

    call HistoryPut('x',x)   ! 次元変数出力
    call HistoryPut('y',y)   ! 次元変数出力
    call HistoryPut('z',z)   ! 次元変数出力

    call HistoryAddVariable('u', dims=(/'t'/), &
        & longname='Non Dimensional any quantity', &
        & units='non-dimensional')
    call HistoryAddVariable('v', dims=(/'x','t'/), &
        & longname='1 Dimensional any quantity', &
        & units='1-dimensional any unit', xtype='double')
    call HistoryAddVariable('v2', dims=(/'z','t'/), &
        & longname='1 Dimensional any quantity II', &
        & units='1-dimensional any unit', xtype='double')
    call HistoryAddVariable('w', dims=(/'x','y','t'/), &
        & longname='2 Dimensional any quantity', &
        & units='2-dimensional any unit')
    call HistoryAddVariable('q', dims=(/'x','y','z','t'/), &
        & longname='3 Dimensional any quantity', &
        & units='3-dimensional any unit', xtype='double')

    do, l = 1, 24
       u = real(l)*0.100000001
        do i = 1, 10
           v(i) = dble(l)*0.100000001d0+dble(i)*10.0000001d0
           do j = 1, 20
              w(i,j) = real(l)*0.100000001 + real(i)*10.0000001 &
                       & + real(j)*1000.00001
              do k = 1, 30
                 q(i,j,k) = dble(l)*0.100000001d0     &
                            & + dble(i)*10.0000001d0  &
                            & + dble(j)*1000.00001d0  &
                            & + dble(k)*100000.001d0

                 v2(k) = dble(k)*100000.001d0
              enddo
           enddo
        enddo
        call HistoryPut('t', real(l)*0.2)
        call HistoryPut('u', u)
        call HistoryPut('v', v)
        call HistoryPut('v2', v2)
        call HistoryPut('w', w)
        call HistoryPut('q', q)

    enddo

    call DataDump('v', v, strlen=10)
    call DataDump('w', dble(w), strlen=60)
    call DataDump('q(1,1,', q(1,1,:))

    call HistoryClose

    call MessageNotify('M', subname, 'Input file <%c> is generated.', &
         & c1='xhistget/xhistget1.nc')

    !-----------------------------------------------------------------
    ! 固定長配列による入力テスト (色々な作法で入力)
    !-----------------------------------------------------------------

    call MessageNotify('M', subname, 'Getting by Fixed-Length Array.')

    call HistoryCreate(file='xhistget/xhistget2.nc', &
        & title='gt4_history HistoryGet test 1', &
        & source='gt4f90io/Fortran library test kit', &
        & institution='GFD Dennou Club', &
        & dims=(/'x','y','z','t'/), &
        & dimsizes=(/10,20,30,0/), &
        & longnames=(/'X-coordinate','Y-coordinate', &
                   &  'Z-coordinate','time        '/), &
        & units=(/'m','m','m','s'/), &
        & origin=0.0, interval=0.2, &
        & xtypes=(/'real  ','double','double','real  '/))

    call HistoryPut('x',x)   ! 次元変数出力
    call HistoryPut('y',y)   ! 次元変数出力
    call HistoryPut('z',z)   ! 次元変数出力

    call HistoryAddVariable('u', dims=(/'t'/), &
        & longname='Non Dimensional any quantity', &
        & units='non-dimensional')
    call HistoryAddVariable('v', dims=(/'x','t'/), &
        & longname='1 Dimensional any quantity', &
        & units='1-dimensional any unit', xtype='double')
    call HistoryAddVariable('v2', dims=(/'z','t'/), &
        & longname='1 Dimensional any quantity II', &
        & units='1-dimensional any unit', xtype='double')
    call HistoryAddVariable('w', dims=(/'x','y','t'/), &
        & longname='2 Dimensional any quantity', &
        & units='2-dimensional any unit')
    call HistoryAddVariable('q', dims=(/'x','y','z','t'/), &
        & longname='3 Dimensional any quantity', &
        & units='3-dimensional any unit', xtype='double')

    do, l = 1, 23
       call HistoryPut('t', real(l)*0.2)
       call HistoryGet(file='xhistget/xhistget1.nc', varname='u', & 
            &          array=u, time=real(l)*0.2)
       call HistoryPut('u', u)
       call HistoryGet('xhistget/xhistget1.nc', 'v', v, dble(l)*0.2d0)
       call HistoryPut('v', v)
       call HistoryGet('xhistget/xhistget1.nc', 'v2', v2, time='^'//toChar(l))
       call HistoryPut('v2', v2)
       call HistoryGet('xhistget/xhistget1.nc', 'w', w, time='^'//toChar(l))
       call HistoryPut('w', w)
       call HistoryGet('xhistget/xhistget1.nc', 'q', q, '^'//toChar(l))
       call HistoryPut('q', q)
    enddo

    ! 時間の自動判別のテスト
    l = 24
    call HistoryPut('t', real(l)*0.2)
    call HistoryGet(file='xhistget/xhistget1.nc', varname='u', array=u)
    call HistoryPut('u', u)
    call HistoryGet('xhistget/xhistget1.nc', 'v', v)
    call HistoryPut('v', v)
    call HistoryGet('xhistget/xhistget1.nc', 'v2', v2, time='^'//toChar(l))
    call HistoryPut('v2', v2)
    call HistoryGet('xhistget/xhistget1.nc', 'w', w)
    call HistoryPut('w', w)
    call HistoryGet('xhistget/xhistget1.nc', 'q', q, '^'//toChar(l))
    call HistoryPut('q', q)

    call HistoryClose


    !-----------------------------------------------------------------
    !   ポインタ配列による入力テスト (色々な作法で入力)
    !-----------------------------------------------------------------
    call MessageNotify('M', subname, 'Getting by Pointer Array.')

    call HistoryCreate(file='xhistget/xhistget3.nc', &
        & title='gt4_history HistoryGet test 1', &
        & source='gt4f90io/Fortran library test kit', &
        & institution='GFD Dennou Club', &
        & dims=(/'x','y','z','t'/), &
        & dimsizes=(/10,20,30,0/), &
        & longnames=(/'X-coordinate','Y-coordinate', &
                   &  'Z-coordinate','time        '/), &
        & units=(/'m','m','m','s'/), &
        & origin=0.0, interval=0.2, &
        & xtypes=(/'real  ','double','double','real  '/))

    call HistoryPut('x',x)   ! 次元変数出力
    call HistoryPut('y',y)   ! 次元変数出力
    call HistoryPut('z',z)   ! 次元変数出力

    call HistoryAddVariable('u', dims=(/'t'/), &
        & longname='Non Dimensional any quantity', &
        & units='non-dimensional')
    call HistoryAddVariable('v', dims=(/'x','t'/), &
        & longname='1 Dimensional any quantity', &
        & units='1-dimensional any unit', xtype='double')
    call HistoryAddVariable('v2', dims=(/'z','t'/), &
        & longname='1 Dimensional any quantity II', &
        & units='1-dimensional any unit', xtype='double')
    call HistoryAddVariable('w', dims=(/'x','y','t'/), &
        & longname='2 Dimensional any quantity', &
        & units='2-dimensional any unit')
    call HistoryAddVariable('q', dims=(/'x','y','z','t'/), &
        & longname='3 Dimensional any quantity', &
        & units='3-dimensional any unit', xtype='double')

    do, l = 1, 23
       call HistoryPut('t', real(l)*0.2)
       call HistoryGetPointer(file='xhistget/xhistget1.nc', varname='u', & 
            &          array=up, time=real(l)*0.2)
       call HistoryPut('u', up)
       ! 途中で別の関数に割り付けられても自動的に解除されるかテスト
       up => u
       call HistoryGetPointer('xhistget/xhistget1.nc', 'v', vp, dble(l)*0.2d0)
       call HistoryPut('v', vp)
       call HistoryGetPointer('xhistget/xhistget1.nc', 'v2', vp, time='^'//toChar(l))
       call HistoryPut('v2', vp)
       call HistoryGetPointer('xhistget/xhistget1.nc', 'w', wp, time='^'//toChar(l))
       call HistoryPut('w', wp)
       call HistoryGetPointer('xhistget/xhistget1.nc', 'q', qp, '^'//toChar(l))
       call HistoryPut('q', qp)
    enddo

    ! 時間の自動判別のテスト
    l = 24
    call HistoryPut('t', real(l)*0.2)
    call HistoryGetPointer(file='xhistget/xhistget1.nc', varname='u', array=up)
    call HistoryPut('u', up)
    call HistoryGetPointer('xhistget/xhistget1.nc', 'v', vp)
    call HistoryPut('v', vp)
    call HistoryGetPointer('xhistget/xhistget1.nc', 'v2', vp, dble(l)*0.2d0)
    call HistoryPut('v2', vp)
    call HistoryGetPointer('xhistget/xhistget1.nc', 'w', wp)
    call HistoryPut('w', wp)
    call HistoryGetPointer('xhistget/xhistget1.nc', 'q', qp, '^'//toChar(l))
    call HistoryPut('q', qp)

    call HistoryClose


    !-----------------------------------------------------------------
    !   次元データの入力テスト (色々な作法で入力)
    !-----------------------------------------------------------------
    call MessageNotify('M', subname, 'Getting by Various Forms.')

    call HistoryCreate(file='xhistget/xhistget4.nc', &
        & title='gt4_history HistoryGet test 1', &
        & source='gt4f90io/Fortran library test kit', &
        & institution='GFD Dennou Club', &
        & dims=(/'x','y','z','t'/), &
        & dimsizes=(/10,20,30,0/), &
        & longnames=(/'X-coordinate','Y-coordinate', &
                   &  'Z-coordinate','time        '/), &
        & units=(/'m','m','m','s'/), &
        & origin=0.0, interval=0.2, &
        & xtypes=(/'real  ','double','double','real  '/))

    ! 次元データを入力する
    call HistoryGetPointer('xhistget/xhistget1.nc', 'x' ,xp)   ! x 次元入力
    call HistoryGetPointer('xhistget/xhistget1.nc', 'y' ,yp)   ! y 次元入力
    call HistoryGetPointer(file='xhistget/xhistget1.nc', varname='z' ,array=zp)   ! z 次元入力

    call HistoryPut('x',xp)   ! 次元変数出力
    call HistoryPut('y',yp)   ! 次元変数出力
    call HistoryPut('z',zp)   ! 次元変数出力

    call HistoryAddVariable('u', dims=(/'t'/), &
        & longname='Non Dimensional any quantity', &
        & units='non-dimensional')
    call HistoryAddVariable('v', dims=(/'x','t'/), &
        & longname='1 Dimensional any quantity', &
        & units='1-dimensional any unit', xtype='double')
    call HistoryAddVariable('v2', dims=(/'z','t'/), &
        & longname='1 Dimensional any quantity II', &
        & units='1-dimensional any unit', xtype='double')
    call HistoryAddVariable('w', dims=(/'x','y','t'/), &
        & longname='2 Dimensional any quantity', &
        & units='2-dimensional any unit')
    call HistoryAddVariable('q', dims=(/'x','y','z','t'/), &
        & longname='3 Dimensional any quantity', &
        & units='3-dimensional any unit', xtype='double')

    do, l = 1, 24
       call HistoryPut('t', real(l)*0.2)
       call HistoryGetPointer(file='xhistget/xhistget1.nc', varname='u', & 
            &          array=up, time=real(l)*0.2)
       call HistoryPut('u', up)
       ! 途中で別の関数に割り付けられても自動的に解除されるかテスト
       up => u
       call HistoryGetPointer('xhistget/xhistget1.nc', 'v', vp, dble(l)*0.2d0)
       call HistoryPut('v', vp)
       call HistoryGetPointer('xhistget/xhistget1.nc', 'v2', vp, time='^'//toChar(l))
       call HistoryPut('v2', vp)
       call HistoryGetPointer('xhistget/xhistget1.nc', 'w', wp, time='^'//toChar(l))
       call HistoryPut('w', wp)
       call HistoryGetPointer('xhistget/xhistget1.nc', 'q', qp, '^'//toChar(l))
       call HistoryPut('q', qp)
    enddo

    call HistoryClose

end program
