!=====================================================================
! $B29EYJ,I[7W;;%b%8%e!<%k(B
!  pending
!   - x = 1 and IMAX $B$N%(%M%k%.!<N.F~NL$O%+%&%s%H$7$F$J$$(B
! 2003/12/16 
! 2004/01/01  energy conservation $B$r9MN8$7$?9M$(J}$KJQ99(B
! 2004/01/15  wgt_dammy(KMAX+1)$B$rIU$12C$($k(B
! 2004/01/19  $B3H;69`$NF3F~(B
!=====================================================================
module T_pack
  
  use prm, only : IMAX, JMAX, KMAX,dt, dx
  
  use prmphys, only: k_ice, gamma, rho, c_p
  use com_var, only: zk, wgt, zk_half
  use Tbound,  only: Ts, Ms


  implicit none
  private
  
  public get_T
  public mk_energy
  public mk_temp1
  public adjust_energy
  public energy2Temp



contains

!=====================================================================
! $B3F3J;R$N%(%M%k%.!<$N<0(B
!=====================================================================
subroutine mk_energy(Temp1, energy)
  implicit none
  
  real(8), intent(IN)  :: Temp1(1:IMAX, 1:JMAX, 1:KMAX)
  real(8), intent(OUT) :: energy(1:IMAX, 1:JMAX, 1:KMAX)

  energy =  Temp1 * rho  * c_p

end subroutine mk_energy

!=====================================================================
! $B3H;69`$N7W;;(B($B$?$@$7J]B87O$G$J$$(B)
!=====================================================================
subroutine get_T(Hsfc1,Temp1, Temp2)
  implicit none

  real(8), INTENT(IN)  :: Hsfc1(1:IMAX, 1:JMAX)
  real(8), INTENT(IN)  :: Temp1(1:IMAX, 1:JMAX, 1:KMAX)

  real(8), INTENT(OUT) :: Temp2(1:IMAX, 1:JMAX, 1:KMAX)


  real(8)              :: kappa                           
  real(8)              :: Tbnd(1:IMAX, 1:JMAX)            ! $B:G2<AX$N2<$N29EY(B

  real(8)              :: WORK_aft(1:IMAX, 1:JMAX, 1:KMAX)! $B78?t(B k+1
  real(8)              :: WORK_cnt(1:IMAX, 1:JMAX, 1:KMAX)! $B78?t(B k 
  real(8)              :: WORK_bef(1:IMAX, 1:JMAX, 1:KMAX)! $B78?t(B k-1

  integer              :: i, j, k

  kappa = k_ice/(rho*c_p)


  ! $B>eIt6-3&CM$OI=LL29EY(B
  Temp2(:, :, KMAX) = Ts
  ! $B2<It6-3&CM$OCO3LG.N.NLG.%U%i%C%/%9(B
  Tbnd(:, :) = Temp1(:, :, 1)+wgt(1)/k_ice * gamma

  do j = 1, JMAX
     do i = 1, IMAX
        ! $BI9>2$,$J$$>l9g$OI9>229EY(B
        if(Hsfc1(i, j) == 0.0)then
           Temp2(i, j, :) = Ts(i, j)
           cycle
        end if

        ! $B%l%Y%k(B 1 $B!A(B KMAX-1 $B$^$G$N78?t(B
        do k = 1, KMAX-1
           WORK_aft(i, j, k) =  kappa *dt  &
                &                /Hsfc1(i, j)**2/wgt(k)/(zk(k+1) - zk(k))
        end do
      
        WORK_cnt(i, j, 1) = 1 -  kappa *dt  &
             &                /Hsfc1(i, j)**2/wgt(1) &
             &              *(1/(zk(2) - zk(1)) + 1/wgt(1))
        do k = 2, KMAX-1
           WORK_cnt(i, j, k) = 1 -  kappa *dt  &
                &                /Hsfc1(i, j)**2/wgt(k) &
                &              *(1/(zk(k+1) - zk(k)) + 1/(zk(k) - zk(k-1)))
        end do
        
        WORK_bef(i, j, 1) =  kappa *dt   &
             &                /Hsfc1(i, j)**2/wgt(1)/wgt(1)
        do k=2, KMAX
           WORK_bef(i, j, k) =  kappa *dt   &
                &                /Hsfc1(i, j)**2/wgt(k)/(zk(k) - zk(k-1))
        end do



        ! $B3H;69`$N7W;;(B
        Temp2(i, j, 1) = Temp1(i, j, 1) *WORK_cnt(i, j, 1) &
             &           + Tbnd(i, j)   *WORK_bef(i, j, 1) &
             &           + Temp1(i, j, 2)*WORK_aft(i, j, 1) 
        do k=2, KMAX-1
           Temp2(i, j, k) = Temp1(i, j, k)*WORK_cnt(i, j, k) &
                &           + Temp1(i, j, k-1)*WORK_bef(i, j, k) &
                &           + Temp1(i, j, k+1)*WORK_aft(i, j, k) 
        end do
     end do
  end do

  

end subroutine get_T

!=====================================================================
! $BI9>2$,@8@.$9$k>l=j$N29EY@_Dj(B
! $BJ]B8$7$F$$$J$$(B
!=====================================================================
subroutine mk_temp1(Hsfc1, Hsfc2, temp1)
  implicit none

  real(8), intent(IN)   :: Hsfc1(1:IMAX, 1:JMAX)
  real(8), intent(IN)   :: Hsfc2(1:IMAX, 1:JMAX)
  real(8), intent(INOUT) :: temp1(1:IMAX, 1:JMAX, 1:KMAX)
  integer    :: i, j
  
  do i = 1, IMAX
     do j =1, JMAX
        if((Hsfc1(i, j) == 0.0D0 ).and.(Hsfc2(i, j) > 0.0D0))then
           temp1(i, j, :) = Ts(i, j)
        end if
     end do
  end do
        
  

end subroutine mk_temp1

!=====================================================================
! $B3J;R$ND4@a(B
!=====================================================================
subroutine adjust_energy(Temp1, Uflgrd, Hsfc1, Hsfc2, energy2)
  implicit none

  real(8), intent(IN)     :: Uflgrd(   0:IMAX, 1:JMAX, 1:KMAX)   ! m^2/s
  real(8), intent(IN)     :: Temp1(1:IMAX, 1:JMAX, 1:KMAX)       ! K

  real(8), intent(IN)     :: Hsfc1(1:IMAX, 1:JMAX)               ! m
  real(8), intent(IN)     :: Hsfc2(1:IMAX, 1:JMAX)               ! m
  real(8)                 :: energy1(1:IMAX, 1:JMAX, 1:KMAX+1)! $BD4@aA0$N%(%M%k%.!<(B
  real(8),intent(OUT)      :: energy2(1:IMAX, 1:JMAX, 1:KMAX) ! $BD4@a8e(B

  real(8)                 :: energy_fl(1:IMAX, 1:JMAX, 1:KMAX)      ! J/m
  real(8)                 :: energy_org(1:IMAX, 1:JMAX, 1:KMAX)      ! J/m
  real(8)                 :: energy_Ms(1:IMAX, 1:JMAX)      ! J/m
  real(8)                 :: energy_tot(1:IMAX, 1:JMAX)      ! J/m

  real(8)                 :: Uflgrdl_pls(0:IMAX, 1:JMAX, 1:KMAX) !m^2/s
  real(8)                 :: Uflgrdl_mns(0:IMAX, 1:JMAX, 1:KMAX) !m^2/s
  real(8)                 :: Uflgrdr_pls(0:IMAX, 1:JMAX, 1:KMAX) !m^2/s
  real(8)                 :: Uflgrdr_mns(0:IMAX, 1:JMAX, 1:KMAX) !m^2/s
  real(8)                 :: mass_fl(1:IMAX, 1:JMAX, 1:KMAX)
  real(8)                 :: ratio_ab(1:IMAX, 1:JMAX, 1:KMAX)
  real(8)                 :: mass_org(1:IMAX, 1:JMAX, 1:KMAX)
  real(8)                 :: mass(1:IMAX, 1:JMAX, 1:KMAX)
  real(8)                 :: mass_Ms(1:IMAX, 1:JMAX)

  real(8)                 :: wgt_dammy(1:KMAX+1)
  real(8)                 :: wgt_sum


  real(8), parameter      :: non = -9.99E33

  integer                 :: i, j, k
  integer                :: kk_str, kk

  
  ! x $BJ}8~6-3&(B
  energy1(1, :, :)    = 0.0D0
  energy1(IMAX, :, :) = 0.0D0
  energy2             = 0.0D0

  !$B$+$sM\$K$h$k<ANLJQ2=(B
  mass_Ms   = Ms*dt*dx*rho
  energy_Ms = Ms*dt*dx*rho*c_p*Ts

  do j =1, JMAX
     do i = 2, IMAX-1
        kk_str = KMAX+1

        do k = 1, KMAX
           ! $B<ANL%U%i%C%/%9$NId9f$rJ,$1$k(B
           ! $B3J;R(B i $B$N:8B&(B
           if(Uflgrd(i-1, j, k) >= 0.0D0)then ! $B3J;R(B i$B$XN.F~(B
              Uflgrdl_pls(i, j, k) = Uflgrd(i-1, j, k) !* Temp1(i-1, j, k)*c_p
              Uflgrdl_mns(i, j, k) = 0.0D0
           else ! $BN.=P(B
              Uflgrdl_pls(i, j, k) = 0.0D0
              Uflgrdl_mns(i, j, k) = Uflgrd(i-1, j, k) !* Temp1(i, j, k)*c_p
          end if
           ! $B3J;R(B i $B$N1&B&(B
           if(Uflgrd(i, j, k) >= 0.0D0)then ! $BN.=P(B
              Uflgrdr_pls(i, j, k) = 0.0D0
              Uflgrdr_mns(i, j, k) = - Uflgrd(i, j, k) ! * Temp1(i, j, k)*c_p
           else ! $BN.F~(B
              Uflgrdr_pls(i, j, k) = - Uflgrd(i, j, k) ! * Temp1(i+1, j, k)c_p
              Uflgrdr_mns(i, j, k) = 0.0D0
           end if

           energy_fl(i, j, k) = &
                &   + (Uflgrdl_pls(i, j, k) * Temp1(i-1, j, k)     &
                &   + (Uflgrdl_mns(i, j, k)+Uflgrdr_mns(i, j, k))*Temp1(i,j,k)&
                &   + Uflgrdr_pls(i, j, k) * Temp1(i+1, j, k))     &
                &   * dt * rho * c_p
           ! $BN.F0$K$h$k<ANLJQ2=(B
           mass_fl(i, j, k) =  &
                &   + (Uflgrdl_pls(i, j, k)+Uflgrdl_mns(i, j, k)   &
                &   + Uflgrdr_pls(i, j, k)+Uflgrdr_mns(i, j, k))   &
                &      * dt * rho 

           ! $B;~9o(B t $B$N;~$N<ANL(B
           mass_org(i, j, k) = Hsfc1(i, j)*wgt(k)*dx*rho 
           ! $B;~9o(B t $B$N;~$N%(%M%k%.!<(B
           energy_org(i, j, k)= mass_org(i, j, k)*c_p*Temp1(i, j, k)
           ! $B;~9o(B t+1$B$N;~$N<ANL(B
           mass(i, j, k)  = Hsfc2(i, j)*wgt(k)*dx*rho 
           ! $B;~9o(B t+1 $B$N;~$N%(%M%k%.!<(B($B3J;RD4@aA0(B)

        end do
        ! $B>CLW$7$F$$$k>l9g(B
        if(mass_Ms(i,j) < 0.0D0)then
           do k = KMAX, 1, -1
              if(mass_org(i, j, k)+mass_fl(i, j, k)+mass_Ms(i,j) > 0.0D0)then
                 ! $B$=$l$>$l$N<ANLHf$G>CLWNL$r=P$9(B
                 ratio_ab(i, j, k) =  mass_org(i, j, k)           &
                      & /(mass_org(i, j, k)+mass_fl(i, j, k))
                 mass_org(i, j, k) = mass_org(i,j, k)&
                      & + ratio_ab(i, j, k)*mass_Ms(i, j)
                 energy_org(i, j,k)= &
                      & mass_org(i, j, k)*c_p*Temp1(i, j, k)
                 energy_fl(i, j, k) = &
                      & mass_fl(i, j, k)                       &
                      & +(1.0D0-ratio_ab(i,j,k))* mass_Ms(i, j)&
                      & /mass_fl(i, j, k) *energy_fl(i, j, k)
                 mass_fl(i, j, k) = mass_fl(i,j, k)            &
                      &  +(1.0D0-ratio_ab(i,j,k))* mass_Ms(i, j)
                 ! $BCM$r%j%;%C%H(B
                 mass_Ms(i, j) = 0.0D0
                 energy_Ms(i, j) =0.0D0
              else ! 2 $BAX0J>e$K$o$?$k>l9g(B
                 mass_Ms(i, j)=mass_org(i, j, k)+mass_fl(i, j, k)+mass_Ms(i,j)
                 mass_org(i,j ,k) = 0.0D0
                 mass_fl(i, j, k) = 0.0D0
                 energy_org(i, j, k) = 0.0D0
                 energy_fl(i, j,k) = 0.0D0
              end if
           end do
        end if
        ! $BD4@aA0$N%(%M%k%.!<(B
        energy1(i, j, 1:KMAX)=energy_org(i, j, 1:KMAX)+energy_fl(i, j, 1:KMAX)
        energy1(i, j, KMAX+1)=energy_Ms(i, j)



        energy_tot(i, j) = sum(energy1(i, j, :))
!        if((i == 2).and.(j==1))then
!           write(6, *)'energy, before', energy1(i, j, :)
!        end if
        ! $BI9>2$N=PMh$O$8$a(B

        if(Hsfc2(i, j) > 0.0D0)then
           wgt_dammy(1:KMAX)=&
                & (mass_fl(i,j,1:KMAX)+mass_org(i, j, 1:KMAX))  &
                &          /sum(mass(i, j, :))
           ! KMAX+1 $BAXL\$O>e$+$i$+$sM\$,2C$o$k(B
           wgt_dammy(KMAX+1) = mass_Ms(i, j)/sum(mass(i, j, :))
        else
           wgt_dammy(:) = non
           energy1(i, j, :) = 0.0D0
           cycle
        end if

! $B%A%'%C%/(B
!           if((i==5).and.(j==3))then
!              write(6, *)i, j,  'energy', sum(energy1(i,j,:)), energy1(i, j, :)
!              write(6, *)i, j,  'wgt_dammy', sum(wgt_dammy), wgt_dammy
!             write(6, *)i, j,  'Hsfc1', Hsfc1(i, j)
!             write(6, *)i, j,  'Hsfc2', Hsfc2(i, j)
!          end if

        wgt_sum = wgt_dammy(kk_str)
        do k=KMAX, 1,  -1               ! $BD4@a8e$N3J;R(B

           do kk = kk_str, 1, -1        ! $BD4@aA0$N3J;R(B

              if(wgt(k) >= wgt_sum)then  ! wgt_dammy(kk)$B$NA4It(B
                 energy2(i, j, k) = energy2(i, j, k)&
                      & +energy1(i, j, kk)
                 ! $BF~$k$J$i2<$NAX$rB-$7$F$^$?%A%'%C%/(B
                 if(kk >= 2)then
                    wgt_sum       = wgt_sum + wgt_dammy(kk-1)
                 else
                   !kk=1 $B$rB-$7$F$bM>$k>l9g(B
                    if((wgt_sum/wgt(k) > 1.000000001).or.&
                         (wgt_sum/wgt(k) > 0.9999999999))then
                       write(6, *)' error!! mass is loss', wgt_sum
                       stop
                    end if
                 end if


              else                      ! wgt_dammy(kk)$B$N0lIt(B 
                 energy2(i, j, k) = energy2(i, j, k)&
                      & +(wgt(k)-(wgt_sum-wgt_dammy(kk)) )/wgt_dammy(kk) &
                      &   * energy1(i, j, kk)
                    
                    ! $B;D$j(B
                 energy1(i, j, kk) = & 
                      & (wgt_sum-wgt(k))/wgt_dammy(kk) &
                      &   * energy1(i, j, kk)
                 wgt_sum = wgt_sum-wgt(k) ! $BM>$j(B

                 kk_str = kk
                 exit  
              end if
                 
           end do
              
        end do
        ! $B3J;R$N@Z$jJ,$1$NA08e$G$NJ]B8$N%A%'%C%/(B
        if(sum(energy1(i, j, :)) ==0.0D0)cycle
        if((sum(energy2(i, j, :))/energy_tot(i,j) > 1.0000001).or.    &
             &(sum(energy2(i, j, :))/energy_tot(i,j) < 0.9999999))then
           write(6, *)'energy is not conserved. postion is', i, j
           write(6, *)'energy before', energy_tot(i, j)
           write(6, *)'energy after', sum(energy2(i, j, :))
           stop
        end if
     end do
  end do
end subroutine adjust_energy

subroutine energy2Temp(energy, Hsfc2, Temp)
  implicit none
  
  real(8), INTENT(IN) :: energy(1:IMAX, 1:JMAX, 1:KMAX)
  real(8), INTENT(IN) :: Hsfc2(1:IMAX, 1:JMAX)
  real(8), INTENT(OUT):: Temp(1:IMAX, 1:JMAX, 1:KMAX)
  real(8)             :: mass(1:IMAX, 1:JMAX, 1:KMAX)
  integer             :: i, j, k

  do i =1, IMAX
     do j = 1, JMAX
        if(Hsfc2(i, j) > 0.0D0)then
           do k =1, KMAX
              mass(i, j, k) = Hsfc2(i, j)*wgt(k)*dx*rho
              Temp(i, j, k) = energy(i, j, k)/mass(i, j,k)/c_p
           end do
        else
           Temp(i, j, :) = Ts(i, j)
        end if
     end do
  end do

  
end subroutine energy2Temp


end module T_pack
