!---------------------------------------------------------------------
!     Copyright (C) GFD Dennou Club, 2004. All rights reserved.
!---------------------------------------------------------------------
!= Module HistoryFileIO
!
!   * Developer: SUGIYAMA Ko-ichiro (sugiyama@gfd-dennou.org)
!   * Version: $Id: outputdatafile.f90,v 1.2 2005/04/22 15:01:52 sugiyama Exp $ 
!   * Tag Name: $Name:  $
!   * Change History: 
!
!== Overview 
!
!ファイル出力. 長い時間ステップの値を出力.
!
!== Error Handling
!
!== Known Bugs
!
!== Note
!
!== Future Plans
!

module HistoryFileIO
  !
  !ファイル出力. 長い時間ステップの値を出力.
  !

  !モジュール読み込み
  use gt4_history
  use gridset,  only: s_X,               &!X 座標軸(スカラー格子点)
    &                 s_Z,               &!Z 座標軸(スカラー格子点)
    &                 FileNX,            &!X 方向の格子点(ファイル出力)
    &                 FileNZ,            &!Z 方向の格子点(ファイル出力)
    &                 FileXMin,          &!X 方向の配列の下限(ファイル出力)
    &                 FileXMax,          &!X 方向の配列の上限(ファイル出力)
    &                 FileZMin,          &!Z 方向の配列の下限(ファイル出力)
    &                 FileZMax,          &!Z 方向の配列の上限(ファイル出力)
    &                 DimXMin,           &!X 方向の配列の下限
    &                 DimXMax,           &!X 方向の配列の上限
    &                 DimZMin,           &!Z 方向の配列の下限
    &                 DimZMax,           &!Z 方向の配列の上限
    &                 SpcNum              !凝縮成分の数
  use fileset,  only: HistoryFile,       &!ヒストリファイル名
    &                 exptitle,          &!データの表題
    &                 expsrc,            &!データを作成する手順
    &                 expinst             !最終変更者・組織
  use basicset, only: SpcWetID,          &!凝縮成分の ID
    &                 xz_ExnerBasicZ,    &!基本場のエクスナー関数
    &                 xz_DensBasicZ,     &!基本場の密度
    &                 xz_PotTempBasicZ,  &!基本場の温位
    &                 xz_VelSoundBasicZ, &!基本場の音速
    &                 xz_PressBasicZ,    &!基本場の圧力
    &                 xz_TempBasicZ,     &!基本場の温度
    &                 xz_MixRtBasicZ,    &!基本場の混合比
    &                 xz_EffMolWtBasicZ   !基本場の分子量効果

  !暗黙の型宣言禁止
  implicit none
  
  !属性の指定
  private

  !関数を public に指定
  public HistoryFile_Open
  public HistoryFile_OutPut
  public HistoryFile_OutPutAnal
  public HistoryFile_Close

contains 

!!!------------------------------------------------------------------------------!!!
  subroutine HistoryFile_Open( )
    !
    !ヒストリファイルの定義
    !
    
    !暗黙の型宣言禁止
    implicit none
    
    !変数定義
    real(4)        :: SpcID(SpcNum)
    integer        :: s
    
    do s = 1, SpcNum
      SpcID(s) = s * 1.0d0
    end do


    !-----------------------------------------------------------
    ! ヒストリー作成
    !-----------------------------------------------------------
    call HistoryCreate(                              &
      & file = HistoryFile,                          &
      & title = exptitle,                            &
      & source = expsrc,                             &
      & institution = expinst,                       &
      & dims=(/'x','z','s','t'/),                    &
      & dimsizes=(/FileNX, FileNZ, SpcNum, 0/),      &
      & longnames=(/'X-coordinate',                  &
      &             'Z-coordinate',                  &
      &             'Species Num ',                  &
      &             'Time        '/),                &
      & units=(/'m','m','1','s'/), origin=0.0,       &
      & interval=0.0 )
    
    !-----------------------------------------------------------  
    ! 軸の出力
    !-----------------------------------------------------------
    call HistoryPut('x', s_X( FileXMin: FileXMax ) )
    call HistoryPut('z', s_Z( FileZMin: FileZMax ) )
    call HistoryPut('s', real(SpcID, 4))

    !-----------------------------------------------------------  
    ! 予報変数の出力
    !-----------------------------------------------------------  
    !無次元圧力の擾乱
    call HistoryAddVariable(                               &
      & varname='Exner', dims=(/'x','z','t'/),             &
      & longname='disturbunce of nondimensional pressure', &
      & units=' ', xtype='double' )
    
    !温位の擾乱
    call HistoryAddVariable(                              &
      & varname='PotTemp', dims=(/'x','z','t'/),          &
      & longname='disturbunce of potential temperature',  &
      & units='K', xtype='double' )

    !水平速度
    call HistoryAddVariable(                         &
      & varname='VelX', dims=(/'x','z','t'/),        &
      & longname='zonal velocity',                   &
      & units='m s|-1"', xtype='double' )

    !鉛直速度
    call HistoryAddVariable(                         &
      & varname='VelZ', dims=(/'x','z','t'/),        &
      & longname='vertical velocity',                &
      & units='m s|-1"', xtype='double' )

    !渦粘性係数
    call HistoryAddVariable(                         &
      & varname='Km', dims=(/'x','z','t'/),          &
      & longname='Km',                               &
      & units='1', xtype='double' )
  
    !混合比
    call HistoryAddVariable(                         &
      & varname='MixRt', dims=(/'x','z','s','t'/),   &
      & longname='Mixing Ratio',                     &
      & units='kg kg|-1"', xtype='double' )
    
    !-----------------------------------------------------------  
    ! 基本場の出力
    !-----------------------------------------------------------  
    !無次元圧力の基本場
    call HistoryAddVariable(                          &
      & varname='ExnerBasicZ', dims=(/'x','z'/),      &
      & longname='nondimensional pressure', units='1',&
      & xtype='double' )
    
    !温位の基本場
    call HistoryAddVariable(                          &
      & varname='PotTempBasicZ', dims=(/'x','z'/),    &
      & longname='potential temperature',             &
      & units='K', xtype='double' )
    
    !密度の基本場
    call HistoryAddVariable(                         &
      & varname='DensBasicZ', dims=(/'x','z'/),      &
      & longname='density',                          &
      & units='Kg/m^3', xtype='double' )
    
    !音波速度の基本場
    call HistoryAddVariable(                         &
      & varname='VelSoundBasicZ', dims=(/'x','z'/),  &
      & longname='sound velocity',                   &
      & units='m/s|2', xtype='double' )
    
    !温度の基本場
    call HistoryAddVariable(                         &
      & varname='TempBasicZ', dims=(/'x','z'/),      &
      & longname='Temperature of basic state',       &
      & units='K', xtype='double' ) 
    
    !圧力の基本場
    call HistoryAddVariable(                         &
      & varname='PressBasicZ', dims=(/'x','z'/),     &
      & longname='Pressure of basic state',          &
      & units='Pa', xtype='double' ) 
    
    !水蒸気混合比の基本場
    call HistoryAddVariable(                               &
      & varname='MixRtBasicZ', dims=(/'x','z','s'/),      &
      & longname='Mixing ratio of Condensible volatiles',  &
      & units='kg/kg', xtype='double' ) 
    
    !分子量効果
    call HistoryAddVariable(                         &
      & varname='EffMolWtBasicZ', dims=(/'x','z'/),  &
      & longname='Effect of Mole Weight',            &
      & units='1', xtype='double' ) 

    !-----------------------------------------------------------  
    ! 解析用の変数の出力
    !-----------------------------------------------------------  
    !仮温位の擾乱
    call HistoryAddVariable(                                     &
      & varname='VPotTemp', dims=(/'x','z','t'/),                &
      & longname='disturbunce of virtual potential temperature', &
      & units='K', xtype='double' )

    !温度擾乱
    call HistoryAddVariable(                         &
      & varname='Temp', dims=(/'x','z','t'/),        &
      & longname='disturbunce of temperature',       &
      & units='K', xtype='double' )

    !密度
    call HistoryAddVariable(                          &
      & varname='Rho', dims=(/'x','z','s','t'/),      &
      & longname='Density of condensable components', &
      & units='kg m|-2"', xtype='double' )

    call HistoryAddVariable(                                         &
      & varname='Cloud2Rain', dims=(/'x','z','s','t'/),              &
      & longname='WarmRainPrm Cloud2Rain of condensable components', &
      & units='kg kg|-1"', xtype='double' ) 
 
    call HistoryAddVariable(                                       &
      & varname='Rain2Gas', dims=(/'x','z','s','t'/),              &
      & longname='WarmRainPrm Rain2Gas of condensable components', &
      & units='kg kg|-1"', xtype='double' ) 

    call HistoryAddVariable(                                        &
      & varname='FallRain', dims=(/'x','z','s','t'/),               &
      & longname='WarmRainPrm FallRain of condensable components',  &
      & units='kg kg|-1"', xtype='double' ) 

    
    !-------------------------------------------------------------
    ! 基本場のファイル出力
    !-------------------------------------------------------------
    call HistoryPut( 'DensBasicZ',     xz_DensBasicZ(FileXMin:FileXMax, FileZMin:FileZMax))
    call HistoryPut( 'ExnerBasicZ',    xz_ExnerBasicZ(FileXMin:FileXMax, FileZMin:FileZMax))
    call HistoryPut( 'PotTempBasicZ',  xz_PotTempBasicZ(FileXMin:FileXMax, FileZMin:FileZMax))
    call HistoryPut( 'VelSoundBasicZ', xz_VelSoundBasicZ(FileXMin:FileXMax, FileZMin:FileZMax))
    call HistoryPut( 'TempBasicZ',     xz_TempBasicZ(FileXMin:FileXMax, FileZMin:FileZMax))
    call HistoryPut( 'PressBasicZ',    xz_PressBasicZ(FileXMin:FileXMax, FileZMin:FileZMax))
    call HistoryPut( 'MixRtBasicZ',    xz_MixRtBasicZ(FileXMin:FileXMax, FileZMin:FileZMax, 1:SpcNum))
    call HistoryPut( 'EffMolWtBasicZ', xz_EffMolWtBasicZ(FileXMin:FileXMax, FileZMin:FileZMax))
    
  end subroutine HistoryFile_Open


!!!------------------------------------------------------------------------------!!!
  subroutine HistoryFile_OutPut(   &
    & Time,                        &
    & xz_PotTemp,                  &
    & xz_Exner,                    &   
    & pz_VelX,                     &
    & xr_VelZ,                     &
    & xz_MixRt,                    &
    & xz_Km        )
    !
    !予報変数のヒストリファイルへの出力. 出力時には半格子点の位置でプロットする. 
    !
    
    !モジュール読み込み
    use average,   only: xz_avr_pz, xz_avr_xr

    !暗黙の型宣言禁止
    implicit none
    
    !変数定義
    real(8), intent(in) :: Time
    real(8), intent(in) :: pz_VelX(DimXMin:DimXMax, DimZMin:DimZMax)
    real(8), intent(in) :: xr_VelZ(DimXMin:DimXMax, DimZMin:DimZMax)
    real(8), intent(in) :: xz_Exner(DimXMin:DimXMax, DimZMin:DimZMax)
    real(8), intent(in) :: xz_PotTemp(DimXMin:DimXMax, DimZMin:DimZMax)
    real(8), intent(in) :: xz_Km(DimXMin:DimXMax, DimZMin:DimZMax)
    real(8), intent(in) :: xz_MixRt(DimXMin:DimXMax, DimZMin:DimZMax, SpcNum)

    real(8)             :: xz_VelX(DimXMin:DimXMax, DimZMin:DimZMax)
    real(8)             :: xz_VelZ(DimXMin:DimXMax, DimZMin:DimZMax)

    !----------------------------------------------------------------
    ! 格子点位置を変換
    !----------------------------------------------------------------
    xz_VelX = xz_avr_pz( pz_VelX )
    xz_VelZ = xz_avr_xr( xr_VelZ )
    

    !----------------------------------------------------------------
    ! 値を出力
    !----------------------------------------------------------------
    call HistoryPut( 't', Time )
    
    call HistoryPut('Exner',                                  &
      & xz_Exner(FileXMin:FileXMax, FileZMin:FileZMax) )
    
    call HistoryPut('PotTemp',                                &
      & xz_PotTemp(FileXMin:FileXMax, FileZMin:FileZMax) )
    
    call HistoryPut( 'VelX',                                  &
      & xz_VelX(FileXMin:FileXMax, FileZMin:FileZMax)    )
    
    call HistoryPut( 'VelZ',                                  &
      & xz_VelZ(FileXMin:FileXMax, FileZMin:FileZMax)    )

    call HistoryPut( 'Km',                                    &
      & xz_Km(FileXMin:FileXMax, FileZMin:FileZMax)      )
    
    call HistoryPut( 'MixRt',                                 &
      & xz_MixRt(FileXMin:FileXMax, FileZMin:FileZMax, 1:SpcNum)  )
    
  end subroutine HistoryFile_OutPut


!!!------------------------------------------------------------------------------!!!
  subroutine HistoryFile_OutPutAnal(  &
    &          xz_PotTemp,            &
    &          xz_Exner,              &
    &          xz_MixRt               &
    &         )
    !
    !解析用の変数のヒストリファイルへの出力.
    !

    use WarmRainPrm, only: xz_FallRain, xz_Cloud2Rain, xz_Rain2Gas

    
    !暗黙の型宣言禁止
    implicit none
    
    !変数定義
    real(8), intent(in) :: xz_PotTemp(DimXMin:DimXMax, DimZMin:DimZMax)
    real(8), intent(in) :: xz_Exner(DimXMin:DimXMax, DimZMin:DimZMax)
    real(8), intent(in) :: xz_MixRt(DimXMin:DimXMax, DimZMin:DimZMax, SpcNum)

    real(8)             :: xz_Temp(DimXMin:DimXMax, DimZMin:DimZMax)
    real(8)             :: xz_VPotTemp(DimXMin:DimXMax, DimZMin:DimZMax)
    real(8)             :: xz_Rho(DimXMin:DimXMax, DimZMin:DimZMax,SpcNum)
    real(8)             :: xz_CloudPhys1(DimXMin:DimXMax, DimZMin:DimZMax,SpcNum)
    real(8)             :: xz_CloudPhys2(DimXMin:DimXMax, DimZMin:DimZMax,SpcNum)
    real(8)             :: xz_CloudPhys3(DimXMin:DimXMax, DimZMin:DimZMax,SpcNum)
    integer             :: spc

    
    !----------------------------------------------------------------
    ! 密度, 温度, 仮温位の計算
    !----------------------------------------------------------------
    do spc = 1, SpcNum
      xz_Rho(:,:,spc) =                                                       &
        &  xz_DensBasicZ(:,:) * ( xz_MixRtBasicZ(:,:,spc) + xz_MixRt(:,:,spc) )
    end do

    xz_Temp = ( xz_Exner + xz_ExnerBasicZ ) * ( xz_PotTemp + xz_PotTempBasicZ ) &
      &       - xz_ExnerBasicZ  * xz_PotTempBasicZ 

    xz_VPotTemp = xz_PotTemp / xz_EffMolWtBasicZ 
    
    !----------------------------------------------------------------
    ! 雲物理量を計算
    !----------------------------------------------------------------
    xz_CloudPhys1(:,:,:) = xz_Cloud2Rain( xz_MixRt(:,:,:) ) 
    xz_CloudPhys2(:,:,:) = xz_Rain2Gas(xz_Exner, xz_PotTemp, xz_MixRt(:,:,:)) 
    do spc = 1, SpcNum      
      xz_CloudPhys3(:,:,spc) = xz_FallRain(xz_MixRt(:,:,spc), spc)
    end do
    
    !----------------------------------------------------------------
    ! 値を出力
    !----------------------------------------------------------------
    call HistoryPut( 'Temp',                                            &
      & xz_Temp(FileXMin:FileXMax, FileZMin:FileZMax)    )    
    
    call HistoryPut( 'VPotTemp',                                        &
      & xz_VPotTemp(FileXMin:FileXMax, FileZMin:FileZMax)    )    
    
    call HistoryPut( 'Rho',                                             &
      & xz_Rho(FileXMin:FileXMax, FileZMin:FileZMax, 1:SpcNum) )
    
    call HistoryPut( 'Cloud2Rain',                                      &
      & xz_CloudPhys1(FileXMin:FileXMax, FileZMin:FileZMax, 1:SpcNum) )

    call HistoryPut( 'Rain2Gas',                                        & 
      & xz_CloudPhys2(FileXMin:FileXMax, FileZMin:FileZMax, 1:SpcNum) )
    
    call HistoryPut( 'FallRain',                                        &
      & xz_CloudPhys3(FileXMin:FileXMax, FileZMin:FileZMax, 1:SpcNum) )

  end subroutine HistoryFile_OutPutAnal


!!!------------------------------------------------------------------------------!!!
  subroutine HistoryFile_Close
    !
    !ヒストリファイルのクローズ
    !
    
    !暗黙の型宣言禁止
    implicit none

    !ファイルを閉じる
    call HistoryClose
  
  end subroutine HistoryFile_Close


end module HistoryFileIO
