!---------------------------------------------------------------------
!     Copyright (C) GFD Dennou Club, 2005. All rights reserved.
!---------------------------------------------------------------------
                                                                 !=begin
!= Module dycore_hs94forcing_mod
!
!   * Developers: Morikawa Yasuhiro
!   * Version: $Id: dycore_hs94forcing.f90,v 1.1.1.1 2005/11/08 14:10:24 morikawa Exp $
!   * Tag Name: $Name: dcpam3-20060725 $
!   * Change History: 
!
!== Overview
!
!Call ((< hs94forcing_mod >)).
!
!== Error Handling
!
!== Known Bugs
!
!== Note
!
!== Future Plans
!
!

                                                                !=end
module dycore_hs94forcing_mod

                                                                !=begin
  !== Dependency
  use type_mod,      only : STRING, DBKIND, INTKIND
  use time_mod,      only : InitTime, DelTime, StepInterval, OutputStep
  use axis_x_mod,    only : 
  use axis_y_mod,    only : y
  use axis_z_mod,    only : z
                                                                 !=end
  implicit non    integer(INTKIND)              :: StepIntervalTmp
  integer(INTKIND)              :: OutputStepTmp

                                                                 !=begin
  !== Public Interface
  private
  public :: dycore_hs94forcing_init        ! subroutines
  public :: dycore_hs94forcing             ! subroutines
  public :: dycore_hs94forcing_end         ! subroutines
                                                                 !=end
  real(DBKIND), save, allocatable :: &
       & xyz_VelLon_phy(:,:,:) , & ! 速度経度成分の加熱散逸効果
       & xyz_VelLat_phy(:,:,:) , & ! 速度緯度成分の加熱散逸効果
       & xyz_Temp_phy(:,:,:)       ! 温度の加熱散逸効果

  !for Generate Velocity from Vorticity and Divergence
  real(DBKIND), save, allocatable :: &
       & wz_Psi_a(:,:)         , & ! スペクトル(流線関数)
       & wz_Chi_a(:,:)             ! スペクトル(ポテンシャル)

  logical, save :: dycore_hs94forcing_initialized = .false.
  character(STRING),parameter:: version = &
       & '$Id: dycore_hs94forcing.f90,v 1.1.1.1 2005/11/08 14:10:24 morikawa Exp $'
  character(STRING),parameter:: tagname = '$Name: dcpam3-20060725 $'

!!==  変数を定義する ==============================================
  real(DBKIND)      :: LonLat_Radius_Rad  = 0.174  ! 半径 (ラジアン)
  real(DBKIND)      :: Lat_Center_Rad = 0.0 ! 緯度の中心位置 (ラジアン)
  real(DBKIND)      :: Lon_Center_Rad = 3.14 ! 経度の中心位置 (ラジアン)
  real(DBKIND)      :: DTempDt ! dT/dt (Max value)
  real(DBKIND) :: RadDegFact     ! ラジアンを度数に変換する係数
  real(DBKIND), allocatable :: xyz_Lon(:,:,:) ! 経度座標 (ラジアン表記)
  real(DBKIND), allocatable :: xyz_Lat(:,:,:) ! 緯度座標 (ラジアン表記)

!!  integer(INTKIND)              :: StepInterval
!!  integer(INTKIND)              :: OutputStep

  character(STRING) :: axis_units
!!==================================================================

contains

                                                                 !=begin
  !== Procedure Interface
  !
  !=== Initialize module and
  !
  !((< hs94forcing_mod >)) を初期化する。
  !
  subroutine dycore_hs94forcing_init( Dims )
  !==== Dependency

    use constants_mod  , only: constants_init, pi
    use spml_mod       , only: spml_init
    use dycore_type_mod, only: DYCORE_DIMS
    use dycore_grid_mod, only: dycore_grid_init, im, jm, km, nm
    use hs94forcing_mod, only: hs94forcing_init
    use dc_trace,        only: BeginSub, EndSub, DbgMessage
    use dc_string,       only: LChar, StrHead
    use gt4_history,     only: HistoryAxisInquire
    use gt4_history

                                                                 !=end
    implicit none

!!#====== test =====================#!!
!!  open(50,file='/home/tutaka/dcpam/practice/result/testfile')


!!#== gt4io ============================================================= 

  call HistoryCreate(                                                          &
       file='../../practice/result/test.nc', title='xyz_Temp_phy',             &
       source='test',                                                          &
       institution='tutaka',                                                   &
       dims=(/'x','y','z','t'/), dimsizes=(/im,jm,km,0/),                      &
       longnames=(/'longitude','latitude ','sigma    ','time     '/),          &
       units=(/'degree_east ','degree_north','sigma_level ','time        '/),  &
       origin=real(InitTime), interval=real(StepInterval*DelTime) )

  call HistoryPut('x',x)
  call HistoryPut('y',y)
  call HistoryPut('z',z)

  call HistoryAddVariable(                                 &
       varname='xyz_Temp_phy', dims=(/'x','y','z','t'/),   &
       longname='xyz_Temp_phy', units='K', xtype='double')                 

  call HistoryPut('t',real(InitTime))
  call HistoryPut('xyz_Temp_phy',xyz_Temp_phy) 




                                                                 !=begin
    !==== Input
    !
    type(DYCORE_DIMS), intent(in)   :: Dims   ! 次元データ全種
                                                                 !=end
    !----- 作業用内部変数 -----
    character(STRING),  parameter:: subname = "dycore_hs94forcing_init"
    integer :: i, j

  continue

    !----------------------------------------------------------------
    !   Check Initialization
    !----------------------------------------------------------------
    call BeginSub(subname)
    if (dycore_hs94forcing_initialized) then
       call EndSub( subname, '%c is already called.', c1=trim(subname) )
       return
    else
       dycore_hs94forcing_initialized = .true.
    endif

    !----------------------------------------------------------------
    !   Version identifier
    !----------------------------------------------------------------
    call DbgMessage('%c :: %c', c1=trim(version), c2=trim(tagname))

    !-----------------------------------------------------------------
    !  Initialize Dependent Modules
    !-----------------------------------------------------------------
    call constants_init
    call spml_init
    call dycore_grid_init
    call hs94forcing_init(   &
         & Dims%x_Lon      , & ! intent(in): 経度座標
         & Dims%y_Lat      , & ! intent(in): 緯度座標
         & Dims%z_Sigma    )   ! intent(in): σレベル(整数)座標

    !-----------------------------------------------------------------
    !   Allocate variables
    !-----------------------------------------------------------------
    allocate( &
         & xyz_VelLon_phy(im,jm,km)  , & ! 速度経度成分の加熱散逸効果
         & xyz_VelLat_phy(im,jm,km)  , & ! 速度緯度成分の加熱散逸効果
         & xyz_Temp_phy(im,jm,km)   )    ! 温度の加熱散逸効果

    allocate( wz_Psi_a((nm+1)*(nm+1), km) )
    allocate( wz_Chi_a((nm+1)*(nm+1), km) )

    allocate( xyz_Lon(im,jm,km) )
    allocate( xyz_Lat(im,jm,km) )

    call HistoryAxisInquire(Dims%x_Lon % axisinfo, units=axis_units)
    if (  StrHead( 'radians', trim(LChar(axis_units)) ) .or.&
      &   StrHead( 'rad.', trim(LChar(axis_units)) ) ) then
      RadDegFact = 1.
    else
      RadDegFact = 180. / pi
    end if
    
    do i = 1, im
      xyz_Lon(i,:,:) = Dims%x_Lon%a_Dim(i) / RadDegFact
    end do

    call HistoryAxisInquire(Dims%y_Lat % axisinfo, units=axis_units)
    if (  StrHead( 'radians', trim(LChar(axis_units)) ) .or.&
      &   StrHead( 'rad.', trim(LChar(axis_units)) ) ) then
      RadDegFact = 1.
    else
      RadDegFact = 180. / pi
    end if
    
    do j = 1, jm
      xyz_Lat(:,j,:) = Dims%y_Lat%a_Dim(j) / RadDegFact
    end do
    
    DTempDt = 10.0d0 / 86400.0d0

    xyz_Temp_phy = DTempDt &
      &            *  ( 1.0D0 &
      &                 - sqrt(  &
      &                        min(  LonLat_Radius_Rad**2 ,              &
      &                              ( xyz_Lon - Lon_Center_Rad )**2     &
      &                                + ( xyz_Lat - Lat_Center_Rad )**2 &
      &                           )     &
      &                       ) / LonLat_Radius_Rad  &
      &               )

    call EndSub(subname)
  end subroutine dycore_hs94forcing_init


                                                                 !=begin
  !=== Calculate Heating and Dissipation for "Held and Suarez(1994)"
  !
  !
  !


  subroutine dycore_hs94forcing( Vars_b, Vars_n, Vars_a )




  !==== Dependency
    use dycore_type_mod, only: DYCORE_VARS, &
         &                     STRING, DBKIND, INTKIND
    use dycore_time_mod, only: DelTime
    use constants_mod  , only: R0
    use spml_mod       , only: xya_wa, wa_Div_xya_xya, &
         &                     wa_LaplaInv_wa, wa_xya, &
         &                     xya_GradLat_wa, xya_GradLon_wa
    use hs94forcing_mod, only: hs94forcing
    use dc_trace       , only: BeginSub, EndSub, DbgMessage
                                                                 !=end
    implicit none
                                                                 !=begin
    !==== Input
    !
    type(DYCORE_VARS), intent(in)   :: Vars_b ! 格子点データ全種 (t-Δt)
    type(DYCORE_VARS), intent(in)   :: Vars_n ! 格子点データ全種 (t)
    !
    !==== Output
    !
    type(DYCORE_VARS), intent(inout):: Vars_a ! 格子点データ全種(t+Δt)
                                                                 !=end

    character(STRING),  parameter:: subname = "dycore_hs94forcing"

  continue

    !----------------------------------------------------------------
    !   Check Initialization
    !----------------------------------------------------------------
    call BeginSub(subname)
    if (.not. dycore_hs94forcing_initialized) then
       call EndSub( subname, 'Call dycore_hs94forcing_init before call %c',  &
            &       c1=trim(subname) )
       return
    endif

    !----------------------------------------------------------------
    !   Call hs94forcing
    !----------------------------------------------------------------
!!$    call hs94forcing(           &
!!$         & Vars_b%xyz_VelLon    , & ! intent(in): 速度経度成分 (t-Δt)
!!$         & Vars_b%xyz_VelLat    , & ! intent(in): 速度緯度成分 (t-Δt)
!!$         & Vars_b%xyz_Temp    , & ! intent(in): 温度         (t-Δt)
!!$         & Vars_b%xy_Ps       , & ! intent(in): 地表面気圧   (t-Δt)
!!$
!!$         & xyz_VelLon_phy , & ! intent(inout): 速度経度成分の加熱散逸効果
!!$         & xyz_VelLat_phy , & ! intent(inout): 速度緯度成分の加熱散逸効果
!!$         & xyz_Temp_phy   )   ! intent(inout): 温度の加熱散逸効果

    !----------------------------------------------------------------
    !   Add Heating and Dissipation
    !----------------------------------------------------------------

!!$    Vars_a%xyz_VelLon = Vars_a%xyz_VelLon + 2. * DelTime * xyz_VelLon_phy
!!$    Vars_a%xyz_VelLat = Vars_a%xyz_VelLat + 2. * DelTime * xyz_VelLat_phy
!!$    Vars_a%xyz_Temp = Vars_a%xyz_Temp + 2. * DelTime * xyz_Temp_phy
!!$    Vars_a%xyz_VelLon = Vars_a%xyz_VelLon
!!$    Vars_a%xyz_VelLat = Vars_a%xyz_VelLat
!!$    Vars_a%xyz_Temp = Vars_a%xyz_Temp


!!    write(50,*) 'time = ',DelTime, 2. * DelTime * xyz_Temp_phy
!!#== gt4io ============================================================= 
call HistoryPut('t',real(StepInterval*OutputStep))
call HistoryPut('xyz_Temp_phy',xyz_Temp_phy)

    Vars_a%xyz_Temp = Vars_a%xyz_Temp + 2. * DelTime * xyz_Temp_phy



    !----------------------------------------------------------------
    !   Generate Vorticity and Divergence from Velocity
    !----------------------------------------------------------------
     Vars_a%xyz_Vor = &
          & xya_wa(                                      &
          &   wa_Div_xya_xya( Vars_a%xyz_VelLat   ,      &
          &                   - Vars_a%xyz_VelLon        &
          &                 ) / R0                       &
          & )

     Vars_a%xyz_Div = &
          & xya_wa(                                      &
          &   wa_Div_xya_xya( Vars_a%xyz_VelLon   ,      &
          &                     Vars_a%xyz_VelLat        &
          &                 ) / R0                       &
          & )

     !-------------------------------------------------------------------
     !   Generate Velocity from Vorticity and Divergence
     !-------------------------------------------------------------------
     wz_Psi_a = wa_LaplaInv_wa(  wa_xya( Vars_a%xyz_Vor )  ) * R0**2
     wz_Chi_a = wa_LaplaInv_wa(  wa_xya( Vars_a%xyz_Div )  ) * R0**2

     Vars_a%xyz_VelLon = (  xya_GradLon_wa( wz_Chi_a ) &
          &                - xya_GradLat_wa( wz_Psi_a )  ) / R0

     Vars_a%xyz_VelLat = (  xya_GradLon_wa( wz_Psi_a ) &
          &                + xya_GradLat_wa( wz_Chi_a )  ) / R0

     !-------------------------------------------------------------------
     !   Trancate Temperature
     !-------------------------------------------------------------------
    Vars_a%xyz_Temp = xya_wa( wa_xya(Vars_a%xyz_Temp) )

    call EndSub(subname)
  end subroutine dycore_hs94forcing

!!#== gt4io ============================================================= 
call HistoryClose
                                                                 !=begin
  !=== Terminate module
  !
  !((< hs94forcing_mod >)) の終了処理を行なう。
  !
  subroutine dycore_hs94forcing_end
  !==== Dependency
    use dycore_type_mod, only: STRING, DBKIND, INTKIND
    use hs94forcing_mod, only: hs94forcing_end
    use dc_trace,        only: BeginSub, EndSub, DbgMessage
                                                                 !=end
    implicit none

    !-----------------------------------------------------------------
    !   変数定義
    !-----------------------------------------------------------------
    !----- 作業用内部変数 -----
    character(STRING),  parameter:: subname = "dycore_hs94forcing_end"

  continue

    !-----------------------------------------------------------------
    !   Check Initialization
    !-----------------------------------------------------------------
    call BeginSub(subname)
    if ( .not. dycore_hs94forcing_initialized) then
       call EndSub( subname, 'dycore_hs94forcing_init was not called', &
            &       c1=trim(subname) )
       return
    else
       dycore_hs94forcing_initialized = .false.
    endif

    !-------------------------------------------------------------------
    !  Terminate Dependent Modules
    !-------------------------------------------------------------------
    call hs94forcing_end

    call EndSub(subname)
  end subroutine dycore_hs94forcing_end

end module dycore_hs94forcing_mod
