!=====================================================================
! $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
!=====================================================================
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




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


!=====================================================================
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
!
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

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)                 :: 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)                 :: 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


  !$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

        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
        if(energy_Ms(i,j) < 0.0D0)then
           mass_Ms(i, j) = 0.0D0
           energy_Ms(i, j) =0.0D0
        end if
        ! $BD4@aA0$N%(%M%k%.!<(B
        energy1(i, j, 1:KMAX)=energy_org(i, j, 1:KAMX)+energy_fl(i, j, 1:KMAX)
        energy1(i, j, KMAX+1)=energy_Ms(i, j)

        
        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==2).and.(j==2))then
!              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, 2,  -1               ! $BD4@a8e$N3J;R(B

           do kk = kk_str, 2, -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
                 wgt_sum       = wgt_sum + wgt_dammy(kk-1)
                 if(kk==2)then
                    if(wgt(k) > wgt_sum)then 
                       energy2(i, j, k) = energy2(i, j, k)+energy1(i, j, kk-1)
                    else
                       energy2(i, j, k) = energy2(i, j, k)&
                            &  + (wgt_sum - wgt_dammy(kk-1)-wgt(k))&
                            &      /wgt_dammy(kk-1)* energy1(i, j, kk-1)
                       ! $B:G8e$NM>$j$O7h$a$?3d9g$KJ,3d(B
                       energy2(i, j, 1:k-1) = &
                            & (1.0D0 -(wgt_sum - wgt_dammy(kk-1)-wgt(k))&
                            &      /wgt_dammy(kk-1))*energy1(i, j, kk-1)

                    end if
                 else                      ! wgt_dammy(kk)$B$N0lIt(B 
                    energy2(i, j, k) = energy2(i, j, k)&
                         & +(wgt_sum-wgt_dammy(kk)-wgt(k))/wgt_dammy(kk) &
                         &   * energy1(i, j, kk)
                    ! $B;D$j(B
                    energy1(i, j, kk) = & 
                         & (1.0D0-(wgt_sum-wgt_dammy(kk)-wgt(k))/wgt_dammy(kk)) &
                         &   * energy1(i, j, kk)
                    wgt_sum = wgt_sum-wgt(k) ! $BB-$7$9$.$?M>$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, :))/sum(energy1(i, j, :)) > 1.0000001).or.    &
             &(sum(energy2(i, j, :))/sum(energy1(i, j, :)) < 0.9999999))then
           write(6, *)'energy is not conserved. postion is', i, j
           write(6, *)'energy total', energy_tot(i, j)
           write(6, *)'energy sum', sum(energy(i, j, :))
           stop
        end if
     end do
  end do
end subroutine adjust_energy

end module T_pack
