!= Module Differentiate_Center4
!
! Authors::   KITAMORI Taichi, SUGIYAMA Ko-ichiro
! Version::   $Id: differentiate_center4.f90,v 1.3 2006/09/21 03:01:02 odakker Exp $ 
! Tag Name::  $Name: arare4-20060922 $
! Copyright:: Copyright (C) GFD Dennou Club, 2006. All rights reserved.
! License::   See COPYRIGHT[link:../../COPYRIGHT]
!
!== Overview 
!
!4 次精度微分演算を行うための関数群をまとめたパッケージ型モジュール
!水平 Arakawa-C, 鉛直 Lorentz グリッドでの微分計算
!
!== Error Handling
!
!== Known Bugs
!
!== Note
!
!本モジュールで定義されている関数は, モジュール differentiate_center2 で
!定義された関数に同じである. 
!
!== Future Plans
!

module differentiate_center4
  !
  !4 次精度の微分演算を行うための関数群をまとめたパッケージ型モジュール
  !水平 Arakawa-C, 鉛直 Lorentz グリッドでの微分計算
  !

  !モジュール読み込み
  use gridset,    only: DimXMin,  &! 配列の X 方向の下限
    &                   DimXMax,  &! 配列の X 方向の上限
    &                   DimZMin,  &! 配列の Z 方向の下限
    &                   DimZMax,  &! 配列の Z 方向の上限
    &                   DelX,     &! X 方向の格子点間隔
    &                   DelZ       ! Z 方向の格子点間隔

  !暗黙の型宣言禁止
  implicit none

  !まずは private 属性に
  private 
  
  !関数を public にする
  public xz_dx_pz
  public xz_dz_xr
  public pz_dx_xz
  public pz_dz_pr
  public xr_dz_xz
  public xr_dx_pr
  public pr_dx_xr
  public pr_dz_pz


contains 

!!!--------------------------------------------------------------------------
  function xz_dx_pz( pz_var ) 
    !
    ! x, z 方向に半格子ずれた点での x 方向 4 次精度微分演算
    !

    !暗黙の型宣言禁止
    implicit none

    !変数定義
    real(8), intent(in) :: pz_var(DimXMin:DimXMax, DimZMin:DimZMax)
                                     !微分演算の対象となる変数
    real(8)             :: xz_dx_pz(DimXMin:DimXMax, DimZMin:DimZMax)
                                     !微分値

    xz_dx_pz = 1.0d-16 
    xz_dx_pz(DimXMin+2:DimXMax-1,DimZMin:DimZMax) =         &
      &   (                                                 &
      &       pz_var(DimXMin+2:DimXMax-1,DimZMin:DimZMax)   &
      &     - pz_var(DimXMin+1:DimXMax-2,DimZMin:DimZMax)   &
      &    ) * 9.0d0 / (8.0d0 * DelX )                      &
      & -                                                   &
      &   (                                                 &
      &       pz_var(DimXMin+3:DimXMax,DimZMin:DimZMax)     &
      &     - pz_var(DimXMin:DimXMax-3,DimZMin:DimZMax)     &
      &    ) / ( 24.0d0 * DelX )

  end function xz_dx_pz


!!!--------------------------------------------------------------------------
  function xz_dz_xr( xr_var ) 
    !
    ! x, z 方向に半格子ずれた点での z 方向 4 次精度微分演算
    !

    !暗黙の型宣言禁止
    implicit none

    !変数定義
    real(8), intent(in) :: xr_var(DimXMin:DimXMax, DimZMin:DimZMax)
                                     !微分演算の対象となる変数
    real(8)             :: xz_dz_xr(DimXMin:DimXMax, DimZMin:DimZMax)
                                     !微分値
    
    xz_dz_xr = 1.0d-16 
    xz_dz_xr(DimXMin:DimXMax,DimZMin+2:DimZMax-1) =           &
      &   (                                                   &
      &        xr_var(DimXMin:DimXMax,DimZMin+2:DimZMax-1)    &
      &      - xr_var(DimXMin:DimXMax,DimZMin+1:DimZMax-2)    &
      &    ) * 9.0d0 / ( 8.0d0 * DelZ )                       &
      & -                                                     &
      &   (                                                   &
      &       xr_var(DimXMin:DimXMax,DimZMin+3:DimZMax)       &
      &     - xr_var(DimXMin:DimXMax,DimZMin:DimZMax-3)       &
      &    ) / ( 24.0d0 * DelZ )

  end function xz_dz_xr


!!!--------------------------------------------------------------------------
  function pz_dx_xz( xz_var ) 
    !
    ! z 方向に半格子ずれた点での x 方向 4 次精度微分演算
    !
   
    !暗黙の型宣言禁止
    implicit none

    !変数定義
    real(8), intent(in) :: xz_var(DimXMin:DimXMax, DimZMin:DimZMax)
                                     !微分演算の対象となる変数
    real(8)             :: pz_dx_xz(DimXMin:DimXMax, DimZMin:DimZMax)
                                     !微分値

    pz_dx_xz = 1.0d-16
    pz_dx_xz(DimXMin+1:DimXMax-2,DimZMin:DimZMax) =          &
      &   (                                                  &
      &       xz_var(DimXMin+2:DimXMax-1,DimZMin:DimZMax)    &
      &     - xz_var(DimXMin+1:DimXMax-2,DimZMin:DimZMax)    &
      &    ) * 9.0d0 / ( 8.0d0 * DelX )                      &
      & -                                                    &
      &   (                                                  &
      &       xz_var(DimXMin+3:DimXMax,DimZMin:DimZMax)      &
      &     - xz_var(DimXMin:DimXMax-3,DimZMin:DimZMax)      &
      &    ) / ( 24.0d0 * DelX )
  end function pz_dx_xz
  

!!!--------------------------------------------------------------------------  
  function pz_dz_pr( pr_var )
    !
    ! z 方向に半格子ずれた点での z 方向 4 次精度微分演算
    !

    !暗黙の型宣言禁止
    implicit none
    
    real(8), intent(in) :: pr_var(DimXMin:DimXMax, DimZMin:DimZMax)
                                     !微分演算の対象となる変数
    real(8)             :: pz_dz_pr(DimXMin:DimXMax, DimZMin:DimZMax)
                                     !微分値
    
    pz_dz_pr = 1.0d-16
    pz_dz_pr(DimXMin:DimXMax, DimZMin+2:DimZMax-1) =        &
      &   (                                                 &
      &       pr_var(DimXMin:DimXMax,DimZMin+2:DimZMax-1)   &
      &     - pr_var(DimXMin:DimXMax,DimZMin+1:DimZMax-2)   &
      &    ) * 9.0d0 / ( 8.0d0 * DelZ )                     &
      & -                                                   &
      &   (                                                 &
      &       pr_var(DimXMin:DimXMax,DimZMin+3:DimZMax)     &
      &     - pr_var(DimXMin:DimXMax,DimZMin:DimZMax-3)     &
      &    ) / ( 24.0d0 * DelZ )
    
  end function pz_dz_pr
  

!!!--------------------------------------------------------------------------
  function xr_dx_pr( pr_var ) 
    !
    ! x 方向に半格子ずれた点での x 方向 4 次精度微分演算
    !
    
    !暗黙の型宣言禁止
    implicit none

    !変数定義
    real(8), intent(in) :: pr_var(DimXMin:DimXMax, DimZMin:DimZMax)
                                     !微分演算の対象となる変数
    real(8)             :: xr_dx_pr(DimXMin:DimXMax, DimZMin:DimZMax)
                                     !微分値
    
    xr_dx_pr = 1.0d-16
    xr_dx_pr(DimXMin+2:DimXMax-1, DimZMin:DimZMax) =        &
      &   (                                                 &
      &       pr_var(DimXMin+2:DimXMax-1,DimZMin:DimZMax)   &
      &     - pr_var(DimXMin+1:DimXMax-2,DimZMin:DimZMax)   &
      &    ) * 9.0d0 / ( 8.0d0 * DelX )                     &
      & -                                                   &   
      &   (                                                 &
      &       pr_var(DimXMin+3:DimXMax,DimZMin:DimZMax)     &
      &     - pr_var(DimXMin:DimXMax-3,DimZMin:DimZMax)     &
      &     ) / ( 24.0d0 * DelX )
    
  end function xr_dx_pr


!!!--------------------------------------------------------------------------
  function xr_dz_xz( xz_var ) 
    !
    ! x 方向に半格子ずれた点での z 方向 4 次精度微分演算
    !

    !暗黙の型宣言禁止
    implicit none

    !変数定義
    real(8), intent(in) :: xz_var(DimXMin:DimXMax, DimZMin:DimZMax)
                                     !微分演算の対象となる変数    
    real(8)             :: xr_dz_xz(DimXMin:DimXMax, DimZMin:DimZMax)
                                     !微分値
    
    xr_dz_xz = 1.0d-16 
    xr_dz_xz(DimXMin:DimXMax,DimZMin+1:DimZMax-2) =         &
      &   (                                                 &
      &       xz_var(DimXMin:DimXMax,DimZMin+2:DimZMax-1)   &
      &     - xz_var(DimXMin:DimXMax,DimZMin+1:DimZMax-2)   &
      &    ) * 9.0d0 / ( 8.0d0 * DelZ )                     &
      & -                                                   &
      &   (                                                 &
      &       xz_var(DimXMin:DimXMax,DimZMin+3:DimZMax)     &
      &     - xz_var(DimXMin:DimXMax,DimZMin:DimZMax-3)     &
      &    ) / ( 24.0d0 * DelZ )
    
  end function xr_dz_xz


!!!--------------------------------------------------------------------------
  function pr_dx_xr( xr_var )
    !
    !格子点上での x 方向 4 次精度微分演算
    !

    !暗黙の型宣言禁止
    implicit none

    !変数定義    
    real(8), intent(in) :: xr_var(DimXMin:DimXMax, DimZMin:DimZMax)
                                     !微分演算の対象となる変数
    real(8)             :: pr_dx_xr(DimXMin:DimXMax, DimZMin:DimZMax)
                                     !微分値
    
    pr_dx_xr = 1.0d-16
    pr_dx_xr(DimXMin+1:DimXMax-2, DimZMin:DimZMax) =        &
      &   (                                                 &
      &       xr_var(DimXMin+2:DimXMax-1,DimZMin:DimZMax)   &
      &     - xr_var(DimXMin+1:DimXMax-2,DimZMin:DimZMax)   &
      &    ) * 9.0d0 / ( 8.0d0 * DelX )                     &
      & -                                                   &
      &   (                                                 &
      &       xr_var(DimXMin+3:DimXMax,DimZMin:DimZMax)     &
      &     - xr_var(DimXMin:DimXMax-3,DimZMin:DimZMax)     &
      &    ) / ( 24.0d0 * DelX)
    
  end function pr_dx_xr
  
  
!!!-------------------------------------------------------------------------
  function pr_dz_pz( pz_var )
    !
    !格子点上での x 方向 4 次精度微分演算
    !

    !暗黙の型宣言禁止
    implicit none
    
    !変数定義
    real(8), intent(in) :: pz_var(DimXMin:DimXMax, DimZMin:DimZMax)
                                     !微分演算の対象となる変数
    real(8)             :: pr_dz_pz(DimXMin:DimXMax, DimZMin:DimZMax)
                                     !微分値    

    pr_dz_pz = 1.0d-16
    pr_dz_pz(DimXMin:DimXMax, DimZMin+1:DimZMax-2) =        &
      &   (                                                 &
      &       pz_var(DimXMin:DimXMax,DimZMin+2:DimZMax-1)   &
      &     - pz_var(DimXMin:DimXMax,DimZMin+1:DimZMax-2)   &
      &    ) * 9.0d0 / ( 8.0d0 * DelZ )                     &
      & -                                                   &
      &   (                                                 &
      &       pz_var(DimXMin:DimXMax,DimZMin+3:DimZMax)     &
      &     - pz_var(DimXMin:DimXMax,DimZMin:DimZMax-3)     &
      &    ) / ( 24.0d0 * DelZ )
    
  end function pr_dz_pz
  
end module differentiate_center4
