! ECCM の再計算
!
! 内部で利用する式は 中島 (1998) を参照


program main
  use gt4_history    

  implicit none

  real(8), allocatable     :: Temp(:)
  real(8), allocatable     :: VTemp(:)
  real(8), allocatable     :: dtdz(:)
  real(8), allocatable     :: dtdz_low(:)
  real(8), allocatable     :: dtdz_high(:)
  real(8), allocatable     :: Vdtdz(:)
  real(8), allocatable     :: Vdtdz_low(:)
  real(8), allocatable     :: Vdtdz_high(:)
  real(8), allocatable     :: stab(:)
  real(8), allocatable     :: stab_low(:)
  real(8), allocatable     :: stab_high(:)
  real(8), allocatable     :: vstab(:)
  real(8), allocatable     :: vstab_low(:)
  real(8), allocatable     :: vstab_high(:)
  real(8), allocatable     :: Pres(:)
  real(8), allocatable     :: Mol(:)
  real(8), allocatable     :: MolWt(:)          !分子量 (kg/mol)
  real(8), allocatable     :: MolWtMean(:)      !分子量 (kg/mol)
  real(8), allocatable     :: MolFr(:,:)        !モル分率
  real(8), allocatable     :: Cp(:)             !比熱   (J/K mol)
  real(8), allocatable     :: CpMean(:)         !比熱   (J/K mol)

  real(8)                  :: VapPres           !分圧
  real(8)                  :: SatVapPres        !飽和蒸気圧
  real(8)                  :: SatVapPres1        !飽和蒸気圧
  real(8)                  :: SatVapPresDT      !飽和蒸気圧の温度勾配

  real(8)                  :: dp
  real(8)                  :: dz
  real(8)                  :: VdtdzDry

  real(8)                  :: temp0, temp1, temp2, temp3
  real(8)                  :: pres0, pres1, pres2, pres3
  real(8)                  :: dtdz1, dtdz2, dtdz3, dtdz4
  real(8)                  :: dt1, dt2, dt3, dt4, dt
  real(8)                  :: MolWtTmp

  integer                  :: i
  logical, allocatable     :: lcl(:)

  real(8), parameter       :: GasR = 8.31d0        !気体定数 (J/k mol)
  real(8), parameter       :: LatentHeat = 40.66d3 !潜熱 (J/mol)
  real(8), parameter       :: Grav = 23.2d0        !木星重力
  real(8), parameter       :: solar  = 8.51d-4   !H/O

  real(8), parameter       :: PresIni = 1.0d6
  real(8), parameter       :: PresEnd = 1.0d4

  integer, parameter       :: NStep = 1000 
  integer, parameter       :: d = 1
  integer, parameter       :: w = 2

  character(40), parameter :: OutputFile = "eccm_x5-anal.nc"  
  real(8), parameter       :: TempIni    = 4.0d2
  real(8), parameter       :: factor     = 5.0d0



!!!
!!!配列の初期化
!!!
  allocate(Pres( Nstep ), &
       & vstab( Nstep ), vstab_low( Nstep ), vstab_high( Nstep ), &
       & stab( Nstep ), stab_low( Nstep ), stab_high( Nstep ), &
       & Temp( Nstep ), vTemp( Nstep ),    &
       & dtdz( NStep ), dtdz_low( NStep ), dtdz_high( NStep ), &
       & vdtdz( NStep ), vdtdz_low( NStep ), vdtdz_high( NStep ), &
       & MolWt( d:w ), MolWtMean( NStep ), &
       & Cp( d:w ), CpMean( NStep ), &
       & Mol( 1:3 ), MolFr( 0:Nstep, d:w ), lcl(NStep) )
  
  Temp = TempIni; vTemp = TempIni
  dtdz = 0.0d0; dtdz_low = 0.0d0; dtdz_high = 0.0d0
  vdtdz = 0.0d0; vdtdz_low = 0.0d0; vdtdz_high = 0.0d0
  vstab = 0.0d0; vstab_low = 0.0d0; vstab_high = 0.0d0
  stab = 0.0d0;  stab_low = 0.0d0;  stab_high = 0.0d0
  MolFr = 0.0d0; Mol = 0.0d0
  lcl = .false. 
  
  !分子量 (単位は kg/mol)
  MolWt(d) = 2.0d-3  * ( 0.5d0 / ( 0.5d0 + 0.0975d0) ) &
       &     + 4.0d-3 * ( 0.0975d0 / ( 0.5d0 + 0.0975d0) ) 
  MolWt(w)= 18.0d-3  !水(水蒸気)
  
  !比熱
  Cp(d) = 29.0d0  * ( 0.5d0 / ( 0.5d0 + 0.0975d0) ) &
       &  + 20.786d0 * ( 0.0975d0 / ( 0.5d0 + 0.0975d0) ) 
  Cp(w) = 33.5d0
  
!  !初期モル
!  Mol(d)   = 1.0d0
!  Mol(w)   = 2 * factor * solar / (1 - 2.0d0 * factor * solar)
!  Mol(w+1) = 0.04875d0
  
  !初期モル比
  MolFr(:,w) = 1.5d-3 * factor
  MolFr(:,d) = 1 - MolFr(:,w) 

  
  
!!!
!!!圧力刻みの設定
!!!
  Pres = PresIni
  do i = 1, NStep
     Pres(i) = PresIni + ( i - 1 )  * ( PresEnd - PresIni ) / ( NStep - 1 ) 
  end do

!  do i = 2, NStep     
!     Pres(i) = PresIni &
!          & * 10.0d0**( ( i - 1 ) * dlog10( PresEnd / PresIni ) &
!          & / ( NStep - 1 ) )
!  end do
  

!!!
!!!NetCDF ファイルの用意
!!!
  call gt4f90io_init

  
!!!
!!!断熱減率の計算
!!!
  do i = 1, NStep - 1 
     
     !圧力変化
     dp = Pres(i+1) - Pres(i)
     
     !前のステップでのモル分率を用いて現在の蒸気圧を計算
     VapPres = MolFr(i-1, w) * Pres(i)
     
     !飽和蒸気圧
     call Amp( Temp(i), svap = SatVapPres )

     if ( VapPres < SatVapPres ) then 

        !モル比
        MolFr(i,:) = MolFr(i-1,:)

        !平均分子量 (モル数は前のステップと変わらない)
        MolWtMean(i) = dot_product( MolFr(i, d:w), MolWt(d:w) )
        
        !平均比熱の計算 (モル数は前のステップと変わらない)
        CpMean(i) = dot_product( MolFr(i, d:w), Cp(d:w) )
        
        !乾燥断熱減率を計算
        dtdz(i)      = - Grav * MolWtMean(i) / CpMean(i)
        dtdz_low(i)  =  dtdz(i)
        dtdz_high(i) =  dtdz(i)

        !温度プロファイルを計算
        Temp(i+1) = Temp(i) &
             & -  dtdz(i) * dp * GasR * Temp(i) &
             &   / ( Pres(i) * Grav * MolWtMean(i) )
        
     else
        
        lcl(i) = .true. 

        !圧力変化
        dp = Pres(i+1) - Pres(i)
        
        temp0 = temp(i)
        pres0 = pres(i)
        call equiv_dtdz(Temp0, Pres0, &
             & MolFr(i,:), MolWtMean(i), CpMean(i), dtdz1)        
        dz = - GasR * Temp(i) * dp  / ( Pres(i) * Grav * MolWtMean(i) )
        dt1 = dtdz1 * dz

        Temp1 = Temp0 + dt1 / 2.0d0  
        Pres1 = Pres0 + dp / 2.0d0
        call equiv_dtdz(Temp1, Pres1, MolWtTmp=MolWtTmp, dtdzTmp=dtdz2)
        dz = - GasR * Temp1 * dp / ( Pres1 * Grav * MolWtTmp )
        dt2 = dtdz2 * dz
        
        Temp2 = Temp0 + dt2  / 2.0d0  
        Pres2 = Pres0 + dp / 2.0d0
        call equiv_dtdz(Temp2, Pres2, MolWtTmp=MolWtTmp, dtdzTmp=dtdz3)
        dz = - GasR * Temp2 * dp / ( Pres2 * Grav * MolWtTmp )
        dt3 = dtdz3 * dz
        
        Temp3 = Temp0 + dt3
        Pres3 = Pres0 + dp
        call equiv_dtdz(Temp3, Pres3, MolWtTmp=MolWtTmp, dtdzTmp=dtdz4)
        dz = - GasR * Temp0 * dp / ( Pres2 * Grav * MolWtTmp )
        dt4 = dtdz4 * dz
        
        dtdz(i) = (dtdz1 + 2.0d0 * dtdz2 + 2.0d0 * dtdz3 + dtdz4) / 6.0d0
        dt = (dt1 + 2.0d0 * dt2 + 2.0d0 * dt3 + dt4) / 6.0d0
        
        Temp(i+1) = Temp(i) + dt
        
     end if
  end do

  MolFr( NStep,: )   = MolFr( NStep-1,: ) 
  MolWtMean( NStep ) = MolWtMean( NStep-1 ) 
  CpMean( NStep )    = CpMean( NStep-1 ) 
  dtdz( NStep )      = dtdz( NStep-1 ) 
  lcl( NStep )       = lcl( NStep-1)


!!!
!!!温度減率の上限・下限
!!!
  do i = 1, NStep
     if (.NOT. lcl(i) ) cycle

     dtdz_high(i) = - MolWtMean(i) * Grav * Temp(i) / LatentHeat
     dtdz_low(i)  = - MolWtMean(i) * Grav *  &
       &          ( 1  &
       &            + LatentHeat * Molfr(i,w) / ( GasR * Temp(i) ) &
       &            - ( LatentHeat ** 2.0d0 ) * MolFr(i,w)  &
       &                / ( CpMean(i) * GasR * ( Temp(i) ** 2.0d0 ) )  &
       &           ) &
       & / CpMean(i)
  end do
  
!!!
!!!仮温度への変換
!!!
!!!平均分子量, モル分率は既に求まっている  
  
  !乾燥気塊の仮温度減率
  VdtdzDry = - Grav * MolWt(d) / Cp(d)

  do i = 1, NStep - 1
     call Amp( Temp(i), svap = SatVapPres, svap_dt = SatVapPresDT )
     
     vdtdz(i)      = dtdz(i)      * MolWt(d) / MolWtMean(i)      
     vdtdz_low(i)  = dtdz_low(i)  * MolWt(d) / MolWtMean(i)      
     vdtdz_high(i) = dtdz_high(i) * MolWt(d) / MolWtMean(i)      

     if ( lcl(i) ) then 

        ! 1 式 (dMdz を利用)
!        vdtdz(i) = vdtdz(i) &
!             & + MolWt(d) * Pres(i) * Grav &
!             &  * ( MolWtMean(i+1) - MolWtMean(i) ) &
!             &  / ( MolWtMean(i) * GasR * ( Pres(i+1) - Pres(i) ) )

!        ! 2 式 (dXdz を利用)
!        vdtdz(i) = vdtdz(i) &
!             & + MolWt(d) * ( MolWt(w) - MolWt(d) ) &    
!             &    * Pres(i) * Grav &
!             &    * ( MolFr(i+1,w) - MolFr(i,w) ) &
!             &    / ( MolWtMean(i) * GasR * ( Pres(i+1) - Pres(i) ) )

        ! 3 式. 1, 2 式と明らかに異なる....
       vdtdz(i) = vdtdz(i) &
             & - MolWt(d) * ( MolWt(w) - MolWt(d) ) &
             &   * LatentHeat * MolFr(i,w) * dtdz(i) &
             &   / ( (MolWtMean(i) ** 2.0d0) * GasR * Temp(i) ) &
             & - MolWt(d) * ( MolWt(w) - MolWt(d) ) &
             &   * Grav * MolFr(i,w) &
             &   / ( MolWtMean(i) * GasR ) 

        !温度差と dtdz の比較. OK. 
!        write(*,*) &
!             & ( Temp(i+1) - Temp(i) ) &
!             & / ( &
!             & -    dtdz(i) * dp * GasR * Temp(i) &
!             &      / ( Pres(i) * Grav * MolWtMean(i) ) &
!             &   )

        call Amp( Temp(i+1), svap = SatVapPres1 )
        call Amp( Temp(i), svap = SatVapPres )

        !クラウジウス・クラペイロンの式から予想される圧力差
        !あきらかにズレ
        write(*,*) &
             & ( SatVapPres * LatentHeat * ( Temp(i+1) - Temp(i) ) &
             &   / ( GasR * ( Temp(i) ** 2.0d0 ) ) )&
             & / ( MolFr(i+1,w) * Pres(i+1) - MolFr(i,w) * Pres(i) )
        
        write(*,*) &
             & ( ( SatVapPres * LatentHeat * ( Temp(i+1) - Temp(i) ) &
             &   / ( GasR * ( Temp(i) ** 2.0d0 ) ) )&
             &   + ( MolFr(i,w) * Pres(i) ) ) &
             & / Pres(i+1) 


        vdtdz_low(i) = vdtdz_low(i) &
             & + MolWt(d) * Pres(i) * Grav &
             &  * ( MolWtMean(i+1) - MolWtMean(i) ) &
             &  / ( MolWtMean(i) * GasR * ( Pres(i+1) - Pres(i) ) )

        vdtdz_high(i) = vdtdz_high(i) &
             & + MolWt(d) * Pres(i) * Grav &
             &  * ( MolWtMean(i+1) - MolWtMean(i) ) &
             &  / ( MolWtMean(i) * GasR * ( Pres(i+1) - Pres(i) ) )
        

!        vdtdz_low(i) = &
!             & - MolWt(d) * ( MolWt(w) - MolWt(d) ) &
!             &   * Grav * MolFr(i,w) &
!             &   / ( MolWtMean(i) * GasR ) &
!             & - MolWt(d) * Grav / CpMean(i) &
!             & - MolWt(d) * Grav * LatentHeat * MolFr(i,w) &
!             &   / ( GasR * Temp(i) * CpMean(i) ) &
!             & + MolWt(d) * Grav * ( LatentHeat ** 2.0d0 ) * MolFr(i,w) &
!             &   / ( GasR * ( Temp(i) ** 2.0d0 ) * ( CpMean(i) ** 2.0d0 )) &
!             & + MolWt(d) * Grav * LatentHeat * MolFr(i,w) &
!             &   * ( MolWt(w) - MolWt(d) ) &
!             &   / ( GasR * Temp(i) * CpMean(i) * MolWtMean(i) ) 

!        vdtdz_high(i) =  vdtdz_high(i) &
!             & - MolWt(d) * ( MolWt(w) - MolWt(d) ) &
!             &   * LatentHeat * MolFr(i,w) * dtdz_high(i) &
!             &   / ( (MolWtMean(i) ** 2.0d0) * GasR * Temp(i) ) &
!             & - MolWt(d) * ( MolWt(w) - MolWt(d) ) &
!             &   * Grav * MolFr(i,w) &
!             &   / ( MolWtMean(i) * GasR ) 
       
!        write(*,*) dtdz(i) * MolWt(d) / MolWtMean(i), &
!             & - MolWt(d) * ( MolWt(w) - MolWt(d) ) &
!             &   * LatentHeat * MolFr(i,w) * dtdz_high(i) &
!             &   / ( (MolWtMean(i) ** 2.0d0) * GasR * Temp(i) ) , &
!             & - MolWt(d) * ( MolWt(w) - MolWt(d) ) &
!             &   * Grav * MolFr(i,w) &
!             &   / ( MolWtMean(i) * GasR ) 

!        write(*,*) MolWt(d) * Pres(i) * Grav &
!             &  * ( MolWtMean(i+1) - MolWtMean(i) ) &
!             &  / ( MolWtMean(i) * GasR * ( Pres(i+1) - Pres(i) ) ), &
!             & ( MolWtMean(i+1) - MolWtMean(i) )


!        vdtdz_high(i) = vdtdz_high(i) &
!             & - MolWt(d) * ( MolWt(w) - MolWt(d) ) &
!             &   * LatentHeat * MolFr(i,w) * dtdz_high(i) &
!             &   / ( (MolWtMean(i) ** 2.0d0) * GasR * Temp(i) ) &
!             & - MolWt(d) * ( MolWt(w) - MolWt(d) ) &
!             &   * Grav * MolFr(i,w) &
!             &   / ( MolWtMean(i) * GasR ) 

!        vdtdz(i) = vdtdz(i) &
!             & - MolWt(d) * ( MolWt(w) - MolWt(d) ) * Temp(i) &
!             &   * dtdz(i) * SatVapPresDT &
!             &   / ( (MolWtMean(i) ** 2.0d0) * Pres(i) ) &
!             & - MolWt(d) * ( MolWt(w) - MolWt(d) ) &
!             &   * Grav * MolFr(i,w) &
!             &   / ( MolWtMean(i) * GasR ) 

!        write(*,*) vdtdz(i)

!        vdtdz_low(i) = vdtdz_low(i) &
!             & + MolWt(d) * Pres(i) * Grav &
!             &  * ( MolWtMean(i+1) - MolWtMean(i) ) &
!             &  / ( MolWtMean(i) * GasR * ( Pres(i+1) - Pres(i) ) )
        
!        vdtdz_high(i) = vdtdz_high(i) &
!             & + MolWt(d) * Pres(i) * Grav &
!             &  * ( MolWtMean(i+1) - MolWtMean(i) ) &
!             &  / ( MolWtMean(i) * GasR * ( Pres(i+1) - Pres(i) ) )

!        vdtdz(i) =  vdtdz(i) &
!             & - MolWt(d) * ( MolWt(w) - MolWt(d) ) &
!             &   * SatVapPres * Grav      &
!             &   / ( MolWtMean(i) * Pres(i) * GasR) &
!             & - MolWt(d) * ( MolWt(w) - MolWt(d) ) * Temp(i)  &
!             &   * dtdz(i) * SatVapPresDT  &
!             &   / ( ( MolWtMean(i) ** 2.0d0 ) * Pres(i) ) 
        
!        vdtdz_low(i) = vdtdz_low(i)  &
!             & - MolWt(d) * ( MolWt(w) - MolWt(d) ) &
!             &   * SatVapPres * Grav      &
!             &   / ( MolWtMean(i) * Pres(i) * GasR) &
!             & - MolWt(d) * ( MolWt(w) - MolWt(d) ) * Temp(i)  &
!             &   * dtdz_low(i) * SatVapPresDT  &
!             &   / ( ( MolWtMean(i) ** 2.0d0 ) * Pres(i) ) 

!        vdtdz_high(i) = vdtdz_high(i) &
!             & - MolWt(d) * ( MolWt(w) - MolWt(d) ) &
!             &   * SatVapPres * Grav      &
!             &   / ( MolWtMean(i) * Pres(i) * GasR) &
!             & - MolWt(d) * ( MolWt(w) - MolWt(d) ) * Temp(i)  &
!             &   * dtdz_high(i) * SatVapPresDT  &
!             &   / ( ( MolWtMean(i) ** 2.0d0 ) * Pres(i) ) 
     end if
  end do
  vdtdz(NStep)      = vdtdz(NStep - 1)
  vdtdz_low(NStep)  = vdtdz_low(NStep - 1)
  vdtdz_high(NStep) = vdtdz_high(NStep - 1)
  

!!!
!!!仮温度
!!!
  VTemp = Temp(1) * MolWt(d) / MolWtMean(1)  !初期化

  do i = 1, NStep - 1
     vTemp(i+1) = vTemp(i) &
          & - vdtdz(i) * &
          &   (  GasR * Temp(i) * ( pres(i+1) - pres(i) ) ) &
          &   / ( pres(i) * Grav * MolWtMean(i)  )
  end do
  vtemp(NStep)      = vtemp(NStep-1)


!!!
!!!静的安定度
!!!
  do i = 1, NStep
     stab(i) = Grav * ( dtdz(i) - vdtdzDry ) / Temp(i)
     stab_low(i) &
          & =   Grav * ( dtdz_low(i) - vdtdzDry ) / Temp(i)
     stab_high(i) &
          & =   Grav * ( dtdz_high(i) - vdtdzDry ) / Temp(i)
  end do
  
  do i = 1, NStep
     vstab(i) = Grav * ( vdtdz(i) - VdtdzDry ) / VTemp(i)
     vstab_high(i) &
          & =   Grav * ( vdtdz_high(i) - VdtdzDry ) / VTemp(i)

     if ( lcl(i) ) then 
        vstab_low(i) &
             & =   ( ( LatentHeat / ( GasR * Temp(i) ) ) &
             &        - ( CpMean(i) / GasR ) )&
             &   * ( ( LatentHeat / ( CpMean(i) * Temp(i) ) ) &
             &        - ( ( MolWt(w) - MolWt(d) ) / MolWtMean(i) ) ) &
             &   * ( MolWtMean(i) * (Grav ** 2.d0) * MolFr(i,w) ) &
             &   / ( CpMean(i) * Temp(i) )
     end if
  end do
  
  
!!!
!!!単位の換算 (m --> km), 符号の付け換え
!!!
  dtdz       = dtdz * (- 1.0d3 )
  dtdz_low   = dtdz_low * ( - 1.0d3 )
  dtdz_high  = dtdz_high * ( - 1.0d3 )
  vdtdz      = vdtdz * (- 1.0d3 )
  vdtdz_low  = vdtdz_low * ( - 1.0d3 )
  vdtdz_high = vdtdz_high * ( - 1.0d3 )
  


!!!
!!!物理量の書き出し
!!!
  call HistoryPut('molfr', MolFr)
  call HistoryPut('molwt', MolWtMean)
  call HistoryPut('cp', CpMean)
  call HistoryPut('temp',  temp)
  call HistoryPut('vtemp', vtemp)
  call HistoryPut('dtdz',  dtdz)
  call HistoryPut('vdtdz', vdtdz)
  call HistoryPut('stab', vstab)
  call HistoryPut('vstab', vstab)

!  call HistoryPut('temp_low',  Temp_low)
!  call HistoryPut('vtemp_low', vTemp_low)
  call HistoryPut('dtdz_low',  dtdz_low)
  call HistoryPut('vdtdz_low', vdtdz_low)
  call HistoryPut('stab_low', vstab_low)
  call HistoryPut('vstab_low', vstab_low)

!  call HistoryPut('temp_high',  Temp_high)
!  call HistoryPut('vtemp_high', vTemp_high)
  call HistoryPut('dtdz_high',  dtdz_high)
  call HistoryPut('vdtdz_high', vdtdz_high)
  call HistoryPut('stab_high', vstab_high)
  call HistoryPut('vstab_high', vstab_high)


!!!
!!!NetCDF ファイルを閉じる
!!!
  call HistoryClose


contains

  subroutine equiv_dtdz(TempTmp, PresTmp, MolFrTmp, MolWtTmp, CpTmp, dtdzTmp)
    real(8), intent(in)            :: TempTmp
    real(8), intent(in)            :: PresTmp
    real(8), intent(out)           :: MolWtTmp
    real(8), intent(out), optional :: MolFrTmp(d:w)
    real(8), intent(out), optional :: CpTmp
    real(8), intent(out)           :: dtdzTmp
    real(8)              :: svap
    real(8)              :: A
    real(8)              :: B
    real(8)              :: MolFr0(d:w)
    real(8)              :: Cp0
    
    
    !飽和蒸気圧
    call amp(TempTmp, svap)
    
    !飽和蒸気圧と圧力から現在のモル数を計算
    MolFr0(w) = svap / PresTmp
    MolFr0(d) = 1.0d0 - MolFr0(w)
    
    !平均分子量
    MolWtTmp = dot_product( MolFr0(d:w), MolWt(d:w) )
    
    !平均比熱の計算
    Cp0    = dot_product( MolFr0(d:w), Cp(d:w) )
    
    !係数. 温度 Temp で評価
    A = LatentHeat * MolFr0(w) / ( GasR * TempTmp )
    B = ( LatentHeat ** 2.0d0 ) * MolFr0(w)  &
         & / ( Cp0 * GasR * ( TempTmp ** 2.0d0 ) )
    
    !断熱減率
    dtdzTmp = - MolWtTmp * Grav * ( 1 + A ) / ( Cp0 * ( 1 + B ) )

    !出力用
    if ( present( MolFrTmp ) ) MolFrTmp = MolFr0
    if ( present( CpTmp ) )    CpTmp    = Cp0
    
  end subroutine equiv_dtdz




  subroutine Antoine(temp, svap)    
    implicit none
    real(8), intent(in)    :: temp         !温度
    real(8), intent(out)   :: svap         !飽和蒸気圧
    real(8)                :: svap_log
  
    !以下は水での値
    real(8), parameter     :: AA = 8.184254d0
    real(8), parameter     :: AB = 1791.3d0
    real(8), parameter     :: AC = 238.1d0
    
    !Antoine の式
    svap_log = (AA - (AB / (AC + Temp - 273.15D0) ) ) &
         & * dlog(10.0D0) + dlog(133.322D0)
    svap = dexp(svap_log)

  end subroutine Antoine


  subroutine Amp(temp, svap, svap_dt)    
    implicit none
    real(8), intent(in)              :: temp         !温度
    real(8), intent(out)             :: svap         !飽和蒸気圧
    real(8), intent(out), optional   :: svap_dt      !飽和蒸気圧
    real(8)                          :: svap_log
    real(8)                          :: svap_log_dt
  
    !以下は水での値
    real(8), parameter     :: A = -5631.1206d0
    real(8), parameter     :: B =  -8.363602d0
    real(8), parameter     :: C = 8.2312d0
    real(8), parameter     :: D = -0.03861449d0
    real(8), parameter     :: E = 2.77494d-5

    svap_log = &
         & A / temp &
         & + B &
         & + (C * dlog(temp)) &
         & + (D * temp) &
         & + (E * (temp**2)) &
         & + dlog(1.0D-1)

    svap_log_dt = &
         & - (A / temp**2.0D0) &
         & + (C / temp) &
         & + (D) &
         & + (2.0D0 * E * temp) 
    
    svap = dexp(svap_log) 
    if ( present(svap_dt) ) svap_dt = dexp( svap_log_dt )
    
  end subroutine Amp


  
  subroutine gt4f90io_init

    implicit none
    real(8)                 :: spc(d:w)
    integer                 :: i 
    integer                 :: num
    character(1000)         :: dataset
    
    write(dataset, *) "; PresIni=", pres(1), &
         & "; PresEnd=", pres(NStep), &
         & "; TempIni=", temp(1), &
         & "; step=", NStep
    num = len_trim(dataset)
    
    call HistoryCreate(&
         & file = OutputFile, &
         & title = "Equilibrium Calculation by ECCM", &
         & source = dataset(:num+1), &
         & institution = "GFD_Dennou_Club oboro Project", &
         & dims = (/ 'pres', 'spc ' /), &
         & dimsizes = (/ NStep, w /), &
         & longnames = (/"Pressure        ", "chemical species"/), &
         & units = (/"Pa", "1 "/), &
         & origin = 0.0,  &
         & interval = 0.0)
    
    spc = (/(i, i = d, w)/)
    call HistoryPut('spc', real(spc, 4))
    
    call HistoryPut('pres', real(pres, 4))
    
    !変数定義, 温度
    call HistoryAddVariable( &
         & varname="temp", &
         & dims=(/'pres'/), &
         & longname="Temperature", &
         & units='K', &
         & xtype="double" )
    
    !変数定義, 温度
!    call HistoryAddVariable( &
!         & varname="temp_low", &
!         & dims=(/'pres'/), &
!         & longname="Temperature", &
!         & units='K', &
!         & xtype="double" )
    
    !変数定義, 温度
!    call HistoryAddVariable( &
!         & varname="temp_high", &
!         & dims=(/'pres'/), &
!         & longname="Temperature", &
!         & units='K', &
!         & xtype="double" )
    
    !変数定義, 仮温度
    call HistoryAddVariable( &
         & varname="vtemp", &
         & dims=(/'pres'/), &
         & longname="Temperature", &
         & units='K', &
         & xtype="double" )
    
    !変数定義, 仮温度
!    call HistoryAddVariable( &
!         & varname="vtemp_low", &
!         & dims=(/'pres'/), &
!         & longname="Temperature", &
!         & units='K', &
!         & xtype="double" )
    
    
!    !変数定義, 仮温度
!    call HistoryAddVariable( &
!         & varname="vtemp_high", &
!         & dims=(/'pres'/), &
!         & longname="Temperature", &
!         & units='K', &
!         & xtype="double" )
    
!    !変数定義, モル
!    call HistoryAddVariable( &
!         & varname="mol", &           
!         & dims=(/'pres', 'spc '/), &
!         & longname="Chemical Species Abundance", &
!         & units='mol', &
!         & xtype="double" )

    !変数定義, モル比
    call HistoryAddVariable( &
         & varname="molfr", &           
         & dims=(/'pres', 'spc '/), &
         & longname="Mol fraction", &
         & units='mol', &
         & xtype="double" )

    !変数定義, 平均分子量
    call HistoryAddVariable( &
         & varname="molwt", &           
         & dims=(/'pres'/), &
         & longname="Mean Mol Weight", &
         & units='mol', &
         & xtype="double" )

    !変数定義, モル
    call HistoryAddVariable( &
         & varname="cp", &           
         & dims=(/'pres'/), &
         & longname="Mean Specific Heat", &
         & units='mol', &
         & xtype="double" )

    !変数定義, 温度減率
    call HistoryAddVariable( &
         & varname="dtdz", &           
         & dims=(/'pres'/), &
         & longname="Lapse Rate", &
         & units='K/km', &
         & xtype="double" )
    
    !変数定義, 温度減率
    call HistoryAddVariable( &
         & varname="dtdz_low", &           
         & dims=(/'pres'/), &
         & longname="Lapse Rate", &
         & units='K/km', &
         & xtype="double" )
    
    !変数定義, 温度減率
    call HistoryAddVariable( &
         & varname="dtdz_high", &           
         & dims=(/'pres'/), &
         & longname="Lapse Rate", &
         & units='K/km', &
         & xtype="double" )
    
    !変数定義, 温度減率
    call HistoryAddVariable( &
         & varname="vdtdz", &           
         & dims=(/'pres'/), &
         & longname="Lapse Rate", &
         & units='K/km', &
         & xtype="double" )
    
    !変数定義, 温度減率
    call HistoryAddVariable( &
         & varname="vdtdz_low", &           
         & dims=(/'pres'/), &
         & longname="Lapse Rate", &
         & units='K/km', &
         & xtype="double" )
    
    !変数定義, 温度減率
    call HistoryAddVariable( &
         & varname="vdtdz_high", &           
         & dims=(/'pres'/), &
         & longname="Lapse Rate", &
         & units='K/km', &
         & xtype="double" )
     
    !変数定義, 温度減率
    call HistoryAddVariable( &
         & varname="stab", &           
         & dims=(/'pres'/), &
         & longname="Stability", &
         & units='s^-2', &
         & xtype="double" )
    
    !変数定義, 温度減率
    call HistoryAddVariable( &
         & varname="stab_low", &           
         & dims=(/'pres'/), &
         & longname="Stability", &
         & units='s^-2', &
         & xtype="double" )

    !変数定義, 温度減率
    call HistoryAddVariable( &
         & varname="stab_high", &           
         & dims=(/'pres'/), &
         & longname="Stability", &
         & units='s^-2', &
         & xtype="double" )
     
    !変数定義, 温度減率
    call HistoryAddVariable( &
         & varname="vstab", &           
         & dims=(/'pres'/), &
         & longname="Stability", &
         & units='s^-2', &
         & xtype="double" )
    
    !変数定義, 温度減率
    call HistoryAddVariable( &
         & varname="vstab_low", &           
         & dims=(/'pres'/), &
         & longname="Stability", &
         & units='s^-2', &
         & xtype="double" )

    !変数定義, 温度減率
    call HistoryAddVariable( &
         & varname="vstab_high", &           
         & dims=(/'pres'/), &
         & longname="Stability", &
         & units='s^-2', &
         & xtype="double" )
    
 end subroutine gt4f90io_init


end program main
