!= Module DynFunc
!
! Authors::   SUGIYAMA Ko-ichiro
! Version::   $Id: dynfunc.f90,v 1.12 2011-02-28 12:00:23 sugiyama Exp $
! Tag Name::  $Name:  $
! Copyright:: Copyright (C) GFD Dennou Club, 2006. All rights reserved.
! License::   See COPYRIGHT[link:../../COPYRIGHT]
!
!== Overview
!
!ãƒ¢ãƒ‡ãƒ«ã®åŠ›å¦éŽç¨‹ã‚’è¨ˆç®—ã™ã‚‹ãŸã‚ã«å¿…è¦ã¨ãªã‚‹é–¢æ•°ç¾¤ã‚’æŸããŸãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«
!å…·ä½“çš„ã«ã¯ä»¥ä¸‹ã®é …ã‚’è¨ˆç®—ã™ã‚‹ãŸã‚ã®é–¢æ•°ã‚’æ ¼ç´ã™ã‚‹.
!  * ç§»æµé …
!  * æµ®åŠ›é …
!  * æ°—åœ§å‚¾åº¦åŠ›é …
!
!== Error Handling
!
!== Known Bugs
!
!== Note
!
!  * ã‚¨ã‚¯ã‚¹ãƒŠãƒ¼é–¢æ•°ã®ç©ºé–“æ–¹å‘ã®é›¢æ•£åŒ–ã«ãŠã„ã¦, 2 æ¬¡ç²¾åº¦ã®é›¢æ•£åŒ–ã‚’é™½ã«åˆ©ç”¨ã—ã¦ã„ã‚‹ãŸã‚,
!    æ°—åœ§å‚¾åº¦åŠ›é …ã®è¨ˆç®—ãƒ—ãƒã‚°ãƒ©ãƒ ã«ãŠã„ã¦ differentiate_center4 ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã‚’æŒ‡å®šã™ã‚‹ã“ã¨ã¯ã§ããªã„ã®ã§æ³¨æ„.
!
!== Future Plans
!

module DynFunc
  !
  !é™½é–‹æ”¾ã‚’ç”¨ã„ãŸåŠ›å¦éŽç¨‹ã®å„é …ã®è¨ˆç®—ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«.
  !å…·ä½“çš„ã«ã¯ä»¥ä¸‹ã®é …ã‚’è¨ˆç®—ã™ã‚‹ãŸã‚ã®é–¢æ•°ã‚’æ ¼ç´ã™ã‚‹.
  !  * ç§»æµé …
  !  * æµ®åŠ›é …
  !  * æ°—åœ§å‚¾åº¦åŠ›é …
  !

  !ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«èªã¿è¾¼ã¿
  use gridset, only:  DimXMin,           &! x æ–¹å‘ã®é…åˆ—ã®ä¸‹é™
    &                 DimXMax,           &! x æ–¹å‘ã®é…åˆ—ã®ä¸Šé™
    &                 DimZMin,           &! z æ–¹å‘ã®é…åˆ—ã®ä¸‹é™
    &                 DimZMax,           &! z æ–¹å‘ã®é…åˆ—ã®ä¸Šé™
    &                 SpcNum              !
  use damping,  only: DampSound           !éŸ³æ³¢ã®æ¸›è¡°ä¿‚æ•°
  use basicset, only: xz_PotTempBasicZ,  &!åŸºæœ¬å ´ã®æ¸©ä½
    &                 xz_EffMolWtBasicZ   !åŸºæœ¬å ´ã®åˆ†åé‡åŠ¹æžœ
  use constants,only: CpDry,             &!ä¹¾ç‡¥æˆåˆ†ã®æ¯”ç†±
    &                 Grav                !é‡åŠ›åŠ é€Ÿåº¦
  use average,  only: xz_avr_pz, xz_avr_xr, &
    &                 pz_avr_xz, pz_avr_pr, &
    &                 pr_avr_xr, pr_avr_pz, &
    &                 xr_avr_pr, xr_avr_xz
!  use StorePotTemp,  only: StorePotTempAdv
!  use StoreMixRt,    only: StoreMixRtAdv
!  use StoreMom,    only: StoreMomAdv
!  use StoreBuoy,    only: StoreBuoyTemp

  !æš—é»™ã®åž‹å®£è¨€ç¦æ¢
  implicit none

  !å±žæ€§ã®æŒ‡å®š
  private

  !ç§»æµé …è¨ˆç®—ã®ãŸã‚ã®é–¢æ•°ã‚’ public ã«ã™ã‚‹
  public xz_AdvScalar
  public xz_AdvKm
  public xza_AdvScalar
  public pz_AdvVelX
  public xr_AdvVelZ

  !æµ®åŠ›é …è¨ˆç®—ã®ãŸã‚ã®é–¢æ•°ã‚’ public ã«ã™ã‚‹
  public xr_Buoy

  !æ°—åœ§å‚¾åº¦åŠ›ã®è¨ˆç®—ã®ãŸã‚ã®é–¢æ•°ã‚’ public ã«ã™ã‚‹
  public pz_GradPi

contains

!!!------------------------------------------------------------------------!!!
  function xz_AdvScalar(xz_Var, pz_VelX, xr_VelZ)
    !
    ! x, z æ–¹å‘ã«åŠæ ¼åãšã‚ŒãŸç‚¹ã«ãŠã‘ã‚‹ç§»æµã‚’è¨ˆç®—
    !

    !ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«èªã¿è¾¼ã¿
    use differentiate_center4, only: pz_dx_xz, xr_dz_xz
!    use differentiate_center2, only: pz_dx_xz, xr_dz_xz

    !æš—é»™ã®åž‹å®£è¨€ç¦æ¢
    implicit none

    !å¤‰æ•°å®šç¾©
    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_Var(DimXMin:DimXMax, DimZMin:DimZMax)
                                                        !ã‚¹ã‚«ãƒ©ãƒ¼é‡
    real(8)             :: xz_AdvScalar(DimXMin:DimXMax, DimZMin:DimZMax)
                                                        !ã‚¹ã‚«ãƒ©ãƒ¼é‡ã®æ°´å¹³ç§»æµ

    xz_AdvScalar =                               &
      & - xz_avr_pz(pz_VelX * pz_dx_xz(xz_Var))  &
      & - xz_avr_xr(xr_VelZ * xr_dz_xz(xz_Var))

!    call StorePotTempAdv( xz_AdvScalar )

  end function xz_AdvScalar

!!!------------------------------------------------------------------------!!!
  function xz_AdvKm(xz_Var, pz_VelX, xr_VelZ)
    !
    ! x, z æ–¹å‘ã«åŠæ ¼åãšã‚ŒãŸç‚¹ã«ãŠã‘ã‚‹ç§»æµã‚’è¨ˆç®—
    !

    !ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«èªã¿è¾¼ã¿
    use differentiate_center4, only: pz_dx_xz, xr_dz_xz
!    use differentiate_center2, only: pz_dx_xz, xr_dz_xz

    !æš—é»™ã®åž‹å®£è¨€ç¦æ¢
    implicit none

    !å¤‰æ•°å®šç¾©
    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_Var(DimXMin:DimXMax, DimZMin:DimZMax)
                                                        !ã‚¹ã‚«ãƒ©ãƒ¼é‡
    real(8)             :: xz_AdvKm(DimXMin:DimXMax, DimZMin:DimZMax)
                                                        !ã‚¹ã‚«ãƒ©ãƒ¼é‡ã®æ°´å¹³ç§»æµ

    xz_AdvKm =                                   &
      & - xz_avr_pz(pz_VelX * pz_dx_xz(xz_Var))  &
      & - xz_avr_xr(xr_VelZ * xr_dz_xz(xz_Var))

  end function xz_AdvKm

  function xza_AdvScalar(xza_Var, pz_VelX, xr_VelZ)
    !
    ! x, z æ–¹å‘ã«åŠæ ¼åãšã‚ŒãŸç‚¹ã«ãŠã‘ã‚‹ç§»æµã‚’è¨ˆç®—
    !

    !ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«èªã¿è¾¼ã¿
    use differentiate_center4, only: pz_dx_xz, xr_dz_xz
!    use differentiate_center2, only: pz_dx_xz, xr_dz_xz

    !æš—é»™ã®åž‹å®£è¨€ç¦æ¢
    implicit none

    !å¤‰æ•°å®šç¾©
    real(8), intent(in) :: pz_VelX(DimXMin:DimXMax, DimZMin:DimZMax)
                                                        !æ°´å¹³é¢¨é€Ÿ
    real(8), intent(in) :: xr_VelZ(DimXMin:DimXMax, DimZMin:DimZMax)
                                                        !é‰›ç›´é¢¨é€Ÿ
    real(8), intent(in) :: xza_Var(DimXMin:DimXMax, DimZMin:DimZMax, SpcNum)
                                                        !ã‚¹ã‚«ãƒ©ãƒ¼é‡
    real(8)             :: xza_AdvScalar(DimXMin:DimXMax, DimZMin:DimZMax, SpcNum)
                                                        !ã‚¹ã‚«ãƒ©ãƒ¼é‡ã®æ°´å¹³ç§»æµ
    integer             :: s

    do s = 1, SpcNum
      xza_AdvScalar(:,:,s) =                               &
        & - xz_avr_pz(pz_VelX * pz_dx_xz(xza_Var(:,:,s)))  &
        & - xz_avr_xr(xr_VelZ * xr_dz_xz(xza_Var(:,:,s)))
    end do

!    call StoreMixRtAdv( xza_AdvScalar )

  end function xza_AdvScalar

!!!------------------------------------------------------------------------!!!
  function pz_AdvVelX(pz_VelX, xr_VelZ)
    !
    ! z æ–¹å‘ã«åŠæ ¼åãšã‚ŒãŸç‚¹ã«ãŠã‘ã‚‹ç§»æµã‚’è¨ˆç®—
    !

    !ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«èªã¿è¾¼ã¿
    use differentiate_center4, only: xz_dx_pz, pr_dz_pz
!    use differentiate_center2, only: xz_dx_pz, pr_dz_pz

    !æš—é»™ã®åž‹å®£è¨€ç¦æ¢
    implicit none

    !å¤‰æ•°å®šç¾©
    real(8), intent(in) :: pz_VelX(DimXMin:DimXMax, DimZMin:DimZMax)
                                                        !æ°´å¹³é¢¨é€Ÿ
    real(8), intent(in) :: xr_VelZ(DimXMin:DimXMax, DimZMin:DimZMax)
                                                        !é‰›ç›´é¢¨é€Ÿ
    real(8)             :: pz_AdvVelX(DimXMin:DimXMax, DimZMin:DimZMax)
                                                        !ã‚¹ã‚«ãƒ©ãƒ¼é‡ã®æ°´å¹³ç§»æµ

!    pz_AdvVelX = 0.0d0  !åˆæœŸåŒ–
    pz_AdvVelX =                                                 &
      & - pz_VelX * pz_avr_xz( xz_dx_pz( pz_VelX ) )             &
      & - pz_avr_pr( pr_avr_xr( xr_VelZ ) * pr_dz_pz( pz_VelX ) )

!    call StoreMomAdv( pz_AdvVelX )

  end function pz_AdvVelX

!!!------------------------------------------------------------------------!!!
  function xr_AdvVelZ(xr_VelZ, pz_VelX)
    !
    ! x æ–¹å‘ã«åŠæ ¼åãšã‚ŒãŸç‚¹ã«ãŠã‘ã‚‹ç§»æµã‚’è¨ˆç®—
    !

    !ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«èªã¿è¾¼ã¿
    use differentiate_center4, only: pr_dx_xr, xz_dz_xr
!    use differentiate_center2, only: pr_dx_xr, xz_dz_xr

    !æš—é»™ã®åž‹å®£è¨€ç¦æ¢
    implicit none

    !å¤‰æ•°å®šç¾©
    real(8), intent(in) :: pz_VelX(DimXMin:DimXMax, DimZMin:DimZMax)
                                                        !æ°´å¹³é¢¨é€Ÿ
    real(8), intent(in) :: xr_VelZ(DimXMin:DimXMax, DimZMin:DimZMax)
                                                        !é‰›ç›´é¢¨é€Ÿ
    real(8)             :: xr_AdvVelZ(DimXMin:DimXMax, DimZMin:DimZMax)
                                                        !ã‚¹ã‚«ãƒ©ãƒ¼é‡ã®æ°´å¹³ç§»æµ

!    xr_AdvVelZ = 0.0d0  !åˆæœŸåŒ–
    xr_AdvVelZ =                                                 &
      & - xr_avr_pr( pr_avr_pz( pz_VelX ) * pr_dx_xr( xr_VelZ ) ) &
      & - xr_VelZ * xr_avr_xz( xz_dz_xr( xr_VelZ ) )

  end function xr_AdvVelZ

!!!------------------------------------------------------------------------!!!
  function xr_Buoy(xz_PotTemp)
    !
    ! é‰›ç›´æ–¹å‘ã®é‹å‹•æ–¹ç¨‹å¼ã«ç¾ã‚Œã‚‹æµ®åŠ›é …ã‚’è¨ˆç®—
    !

    !æš—é»™ã®åž‹å®£è¨€ç¦æ¢
    implicit none

    !å¤‰æ•°å®šç¾©
    real(8), intent(in)  :: xz_PotTemp(DimXMin:DimXMax, DimZMin:DimZMax)
                                               !æ¸©ä½æ“¾ä¹±
    real(8)              :: xr_Buoy(DimXMin:DimXMax, DimZMin:DimZMax)
                                               !æµ®åŠ›é …

!    !åˆæœŸåŒ–
!    xr_Buoy = 0.0d0

    !æµ®åŠ›é …ã®è¨ˆç®—
    xr_Buoy = Grav * xr_avr_xz(xz_PotTemp / xz_PotTempBasicZ)

!    call StoreBuoyTemp(xz_avr_xr(xr_Buoy))

  end function xr_Buoy

!!!------------------------------------------------------------------------!!!
  function pz_GradPi(xz_Exner, pz_VelX, xr_VelZ)
    !
    ! z æ–¹å‘ã«åŠæ ¼åãšã‚ŒãŸç‚¹ã§ã®åœ§åŠ›å‚¾åº¦åŠ›é …ã®è¨ˆç®—.
    ! éŸ³æ³¢æ¸›è¡°é …ã‚’å«ã‚ãŸå½¢å¼ã§å®šå¼åŒ–ã—ã¦ã‚ã‚‹ã“ã¨ã«æ³¨æ„.
    !

    !ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«èªã¿è¾¼ã¿
    use differentiate_center2,  only: pz_dx_xz, xz_dx_pz, xz_dz_xr

    !æš—é»™ã®åž‹å®£è¨€ç¦æ¢
    implicit none

    !å¤‰æ•°å®šç¾©
    real(8), intent(in)  :: xz_Exner(DimXMin:DimXMax, DimZMin:DimZMax)
                                               !ã‚¨ã‚¯ã‚¹ãƒŠãƒ¼é–¢æ•°ã®æ“¾ä¹±
    real(8), intent(in)  :: pz_VelX(DimXMin:DimXMax, DimZMin:DimZMax)
                                               !æ°´å¹³é€Ÿåº¦
    real(8), intent(in)  :: xr_VelZ(DimXMin:DimXMax, DimZMin:DimZMax)
                                               !é‰›ç›´é€Ÿåº¦
    real(8)              :: pz_GradPi(DimXMin:DimXMax, DimZMin:DimZMax)
                                               !åœ§åŠ›å‚¾åº¦åŠ›
    real(8)              :: xz_DivVel(DimXMin:DimXMax, DimZMin:DimZMax)
                                               !é€Ÿåº¦ã®åŽæŸ

    !é€Ÿåº¦ã®åŽæŸ
    xz_DivVel =  xz_dx_pz( pz_VelX ) + xz_dz_xr( xr_VelZ )

    !åœ§åŠ›å‚¾åº¦
!    pz_GradPi = 0.0d0
!    pz_GradPi =  &
!      & pz_avr_xz( CpDry * xz_PotTempBasicZ / xz_EffMolWtBasicZ )    &
!      &   * ( pz_dx_xz( xz_Exner ) - pz_dx_xz( DampSound * xz_DivVel ) )
    pz_GradPi =  &
      & pz_avr_xz( CpDry * xz_PotTempBasicZ / xz_EffMolWtBasicZ )    &
      &   * pz_dx_xz( xz_Exner ) &
      & - pz_dx_xz( DampSound * xz_DivVel )

  end function pz_GradPi

!!!--------------------------------------------------------------------!!!
  function xr_GradPi(xz_Exner, pz_VelX, xr_VelZ)
    !
    ! x æ–¹å‘ã«åŠæ ¼åãšã‚ŒãŸç‚¹ã§ã®åœ§åŠ›å‚¾åº¦åŠ›é …ã®è¨ˆç®—.
    ! éŸ³æ³¢æ¸›è¡°é …ã‚’å«ã‚ãŸå½¢å¼ã§å®šå¼åŒ–ã—ã¦ã‚ã‚‹ã“ã¨ã«æ³¨æ„.
    !

    !ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«èªã¿è¾¼ã¿
    use differentiate_center2,  only: xr_dz_xz, xz_dx_pz, xz_dz_xr

    !æš—é»™ã®åž‹å®£è¨€ç¦æ¢
    implicit none

    !å¤‰æ•°å®šç¾©
    real(8), intent(in)  :: xz_Exner(DimXMin:DimXMax, DimZMin:DimZMax)
                                               !ã‚¨ã‚¯ã‚¹ãƒŠãƒ¼é–¢æ•°ã®æ“¾ä¹±
    real(8), intent(in)  :: pz_VelX(DimXMin:DimXMax, DimZMin:DimZMax)
                                               !æ°´å¹³é€Ÿåº¦
    real(8), intent(in)  :: xr_VelZ(DimXMin:DimXMax, DimZMin:DimZMax)
                                               !é‰›ç›´é€Ÿåº¦
    real(8)              :: xr_GradPi(DimXMin:DimXMax, DimZMin:DimZMax)
                                               !åœ§åŠ›å‚¾åº¦åŠ›
    real(8)              :: xz_DivVel(DimXMin:DimXMax, DimZMin:DimZMax)
                                               !é€Ÿåº¦ã®åŽæŸ

    !é€Ÿåº¦ã®åŽæŸ
    xz_DivVel =  xz_dx_pz( pz_VelX ) + xz_dz_xr( xr_VelZ )

    !é€Ÿåº¦ w ã®åœ§åŠ›å‹¾é…
!    xr_GradPi = 0.0d0
!    xr_GradPi =   &
!      & xr_avr_xz(CpDry * xz_PotTempBasicZ / xz_EffMolWtBasicZ )   &
!      &   * ( xr_dz_xz( xz_Exner ) - xr_dz_xz( DampSound * xz_DivVel ) )
    xr_GradPi =   &
      & xr_avr_xz(CpDry * xz_PotTempBasicZ / xz_EffMolWtBasicZ )   &
      &   * xr_dz_xz( xz_Exner ) &
      & - xr_dz_xz( DampSound * xz_DivVel )

  end function xr_GradPi

end module DynFunc