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



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, energy)
  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), intent(INOUT)  :: energy(1:IMAX, 1:JMAX, 1:KMAX)      ! J/m
  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_tot(1:IMAX, 1:JMAX)      ! 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)                 :: ratio_Ms(1:IMAX, 1:JMAX)
  real(8)                 :: wgt_dammy(1:KMAX)
  real(8)                 :: wgt_nonMs


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

  integer                 :: i, j, k
  integer                :: kk_str, kk
  energy_tot = 0.0D0
  
  ! x $BJ}8~6-3&(B
  energy(1, :, :)    = 0.0D0
  energy(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-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)
           energy_tot(i, j) = energy_tot(i, j)&
                &      +energy_fl(i, j, k)+energy_org(i, j, k)

        end do
        if(energy_Ms(i,j) < 0.0D0)then
           mass_Ms(i, j) = 0.0D0
           energy_Ms(i, j) =0.0D0
        end if

        energy_tot(i, j) = energy_tot(i, j) + energy_Ms(i, j)
        
        if(Hsfc2(i, j) > 0.0D0)then
           wgt_dammy(1:KMAX-1)=&
                & (mass_fl(i,j,1:KMAX-1)+mass_org(i, j, 1:KMAX-1))  &
                &          /sum(mass(i, j, :))
           ! KMAX $B$O>e$+$i$+$sM\$,2C$o$k(B
           wgt_dammy(KMAX)=(mass_fl(i,j,KMAX)+mass_Ms(i, j)         &
                &            +mass_org(i, j, KMAX))                 &
                &          /sum(mass(i, j, :))
           wgt_nonMs      = mass_fl(i,j,KMAX)+mass_org(i, j, KMAX)  &
                &          /sum(mass(i, j, :))
           ratio_Ms(i, j)        = mass_Ms(i, j)/sum(mass(i, j, :))
        else
           wgt_dammy(:) = non
           energy(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)
!              write(6, *)i, j,  'energy_tot', energy_tot(i, j)
!           end if


        do k=KMAX, 2,  -1

           ! k $BAX$KF~$k<ANL$,>/$J$$>l9g(B($B$b$i$&(B)
           if(wgt_dammy(k) < wgt(k))then
              ! $B2<$NAX$+$i$b$i$&(B
              do kk = kk_str, 2, -1
                 ! kk $BAX$rB-$7$F$b>/$J$$>l9g(B
                 if(wgt_dammy(k)+wgt_dammy(kk) < wgt(k))then
                    wgt_dammy(k)= wgt_dammy(k)+wgt_dammy(kk)
                    energy(i, j, k) = energy(i, j, k)                 &
                         & + energy_fl(i, j, kk)+ energy_org(i, j, kk)
                 ! kk $BAX$rB-$7$?$iB?$$>l9g(B
                 else
                    wgt_dammy(k+1) = &
                         & wgt_dammy(k+1)+wgt_dammy(k)+wgt_dammy(kk)-wgt(k)

                    energy(i, j, k)= energy(i, j, k)                  &
                         & + (wgt(k) - wgt_dammy(k))                  &
                         &    /(wgt_dammy(kk))                        &  
                         & *(energy_fl(i, j, kk)                      &
                         & +energy_org(i, j, kk))
                    ! $B;D$j$O$=$N$^$^(B
                    energy(i, j, k-1) = energy(i, j, k-1)             &
                         & + (wgt_dammy(k) + wgt_dammy(kk)-wgt(k))    &
                         &    /(wgt_dammy(kk))                        &  
                         & *(energy_fl(i, j, kk)                     & 
                         & +energy_org(i, j, kk))

                    wgt_dammy(k)= wgt(k)

                    kk_str = kk - 1
                    exit
                 end if
              end do
           else !k $BAX$KF~$k<ANL$,B?$$>l9g(B($B$o$?$9(B)
              wgt_dammy(k-1) = wgt_dammy(k-1) + wgt_dammy(k) - wgt(k)
              ! $B$=$N$&$A$+$sM\$GJd$o$l$k>l9g(B
              if(wgt_dammy(k) <= ratio_Ms(i, j))then

                 energy(i, j, k)=energy_Ms(i, j)*wgt(k)/(1.0D0 - wgt_nonMs)
                 ! $BF~$i$J$+$C$?%(%M%k%.!<$O2<$X<u$1EO$9(B
                 energy_fl(i,j,k-1) = energy_fl(i,j,k-1) + energy_fl(i,j,k)
                 energy_org(i,j,k-1)= energy_org(i,j,k-1) + energy_org(i,j,k)
                 ratio_Ms(i, j) = ratio_Ms(i, j) - wgt(k)
              else
                 ! ($B$+$sM\(B)+ $B85$N%(%M%k%.!<(B + $B0\F0$K$h$k%(%M%k%.!<(B
                 energy(i, j, k) = energy_Ms(i, j)&
                      & * ratio_Ms(i, j)/(mass_Ms(i, j)/sum(mass(i, j, :)))&
                      & + (energy_fl(i, j, k)+energy_org(i, j,k))          &
                      &  * (wgt(k)-ratio_Ms(i,j))/(wgt_dammy(k)-ratio_Ms(i,j))
                 energy_fl(i, j, k-1) = energy_fl(i, j, k-1)               &
                      & +energy_fl(i, j, k)                                &
                      &  * (1.0D0- (wgt(k)-ratio_Ms(i,j))                  &
                      &      /(wgt_dammy(k)-ratio_Ms(i, j)))
                 energy_org(i, j, k-1) = energy_org(i, j, k-1)             &
                      & +energy_org(i, j, k)                               &
                      &  * (1.0D0- (wgt(k)-ratio_Ms(i,j))                  & 
                      &      /(wgt_dammy(k)-ratio_Ms(i, j)))
                 ratio_Ms(i, j) = 0.0D0
              end if

           end if
           wgt_dammy(k) = wgt(k)
        end do
        ! k=1 $B$N$H$-(B
        if(ratio_Ms(i, j) >0.0D0)then
           energy(i, j, 1) = energy_Ms(i, j)*ratio_Ms(i, j)/(1.0D0-wgt_nonMs) &
                & +energy_fl(i, j, 1)+energy_org(i, j, 1) 
        else
           energy(i, j, 1)= energy_fl(i, j, 1)+energy_org(i, j, 1) 
        end if
        ! $B3J;R$N@Z$jJ,$1$NA08e$G$NJ]B8$N%A%'%C%/(B
        if(energy_tot(i, j) ==0.0D0)cycle
        if((sum(energy(i, j, :))/energy_tot(i, j) > 1.0000001).or.         &
             &(sum(energy(i, j, :))/energy_tot(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

subroutine Ms_minus(Hsfc1, Hsfc2, energy, energy2)
  implicit none
  
  real(8), intent(IN)     :: Hsfc2(1:IMAX, 1:JMAX)               ! m
  real(8), intent(IN)     :: Hsfc1(1:IMAX, 1:JMAX)               ! m
  real(8), intent(INOUT)  :: energy(1:IMAX, 1:JMAX, 1:KMAX)      ! J/m
  real(8), intent(INOUT)  :: energy2(1:IMAX, 1:JMAX, 1:KMAX)     ! J/m

  real(8)                 :: energy_tot(1:IMAX, 1:JMAX)      ! J/m
  real(8)                 :: mass_Ms(1:IMAX, 1:JMAX)      ! J/m

  real(8)                 :: rest
  real(8)                 :: mass(1:IMAX, 1:JMAX, 1:KMAX)
  real(8)                 :: mass1(1:IMAX, 1:JMAX, 1:KMAX)
  
  integer                 :: i, j, k,  k1, k2

  ! $B<:$&<ANL(B
  mass_Ms   = - Ms*dt*dx*rho


  do i = 1, IMAX
     do j =1, JMAX
        mass1(i, j, :) =  Hsfc1(i, j) * wgt(:)*dx*rho
        mass(i, j, :)  =  Hsfc2(i, j) * wgt(:)*dx*rho
        ! $BAm%(%M%k%.!<(B
        energy_tot(i, j) = sum(energy(i, j, :))
        if((Ms(i, j) < 0.0D0).and.(Hsfc2(i, j) > 0.0D0))then
           write(6, *)'Ms < 0', i, j
           do k = KMAX, 1, -1
              ! $B>:2Z$,(B k $BAX$KC#$9$k>l9g(B
              if(mass_Ms(i, j) < mass(i, j, k))then
                 energy(i, j, k) = mass_Ms(i, j)/mass1(i, j, k) &
                      &    * energy(i, j, k)
                 energy_tot(i, j) = energy_tot(i, j) &
                      & - energy(i, j, k)*(1.0D0 -mass_Ms(i,j)/mass(i, j, k))
                 rest = (1.0D0 - mass_Ms(i, j)/mass(i, j, k))&
                      &    *Hsfc1(i, j)*rho*dx

                 exit 
              else
                 mass_Ms(i, j) = mass_Ms(i, j) -mass(i, j, k)
                 energy_tot(i, j) = energy_tot(i, j) - energy(i, j, k)
              end if
           end do
           write(6, *)k           
           ! $B;D$j$N<ANL$,(B k2 $BAXL\$K$OB-$j$J$$>l9g(B
           do k2 = KMAX, 2, -1 ! k2 $BAX$O@Z$jD>$7$?AX(B
              do k1 = k, 2, -1
                 write(6, *)'rest=', rest, mass(i, j, k2)
                 if( mass(i, j, k2) > rest)then
                    energy2(i, j, k2) = energy2(i, j, k2)&
                         & +energy(i, j, k1)
                    write(6, *)'ene_1', i, j, k2, energy(i, j, k2)
                    ! mass1(i, j, k)=0.0D0
                    rest = rest + mass1(i, j, k1-1)
                    ! k1 $B$,(B 2 $B$^$G9T$C$F$bB-$j$J$$>l9g(B
                    if(k1 == 2)then
                       energy2(i, j, k2) = energy2(i, j, k2) &
                            & + (mass(i, j, k2)+mass1(i, j, k1-1)-rest)&
                            &      /mass1(i, j, k1-1)*energy(i, j, k1-1)
                       rest = rest - mass(i, j, k2) 
                       ! $B;D$j$rJ,G[$9$k(B
                       energy2(i, j, 1:k2-1)=rest*wgt(1:k2-1)/sum(wgt(1:k2-1))
                       exit 
                    end if
                       
                 ! $B;D$j$N<ANL$,(B k2 $BAX$h$jBg$-$$>l9g(B
                 else
                    ! rest $B$N$&$A(B $B$@$12C$($k(B
                    energy2(i, j, k2) = energy2(i, j, k2)            &
                         & + (mass2(i, j, k2)-rest)/mass1(i,j, k1)  * energy(i, j, k1)
                    ! $BM>$j$O2<$NAX$XEO$9(B
                    energy2(i, j, k2-1) = energy2(i, j, k2-1)        &
                         &  + (1.0D0-(mass2(i, j, k2)-rest)/mass1(i, j, k1))*energy(i,j,k1)
                    write(6, *)'ene_2', i, j, k2, energy2(i, j, k2)
                 end if
              end do
           end do

                 

        end if
        
     end do
  end do
              
        
           
        
           

end subroutine Ms_minus

end module T_pack
