!---------------------------------------------------------------------
!     Copyright (C) GFD Dennou Club, 2004. All rights reserved.
!---------------------------------------------------------------------
                                                                 !=begin
!= Module Differentiate_Center2
!
!   * Developer: SUGIYAMA Ko-ichiro (sugiyama@gfd-dennou.org)
!   * Version: $Id: differentiate_center2.f90,v 1.2 2005/04/22 15:01:52 sugiyama Exp $ 
!   * Tag Name: $Name:  $
!   * Change History: 
!
!== Overview 
!
!微分演算を行うための関数群をまとめたパッケージ型モジュール
!水平 Arakawa-C, 鉛直 Lorentz グリッドでの微分計算
!
!== Error Handling
!
!== Known Bugs
!
!== Note
!
!基本的に DelX もしくは DelZ 離れた格子点位置での微分しか定義していない. 
!格子点 2 個分, 4 個分離れた格子点位置の値を使うような微分は, 
!明らかに精度が落ちるためである. 
!
!== Future Plans
!
                                                                 !=end
module differentiate_center2

  interface ss_dx_fs
     function ss_dx_fs(var) 
       use gridset
       real(8), intent(in) :: var(DimXMin:DimXMax, DimZMin:DimZMax)
       real(8)             :: ss_dx_fs(DimXMin:DimXMax, DimZMin:DimZMax)
     end function ss_dx_fs
  end interface

  interface ss_dz_sf
     function ss_dz_sf(var) 
       use gridset
       real(8), intent(in) :: var(DimXMin:DimXMax, DimZMin:DimZMax)
       real(8)             :: ss_dz_sf(DimXMin:DimXMax, DimZMin:DimZMax)
     end function ss_dz_sf
  end interface

  interface fs_dx_ss
     function fs_dx_ss(var) 
       use gridset
       real(8), intent(in) :: var(DimXMin:DimXMax, DimZMin:DimZMax)
       real(8)             :: fs_dx_ss(DimXMin:DimXMax, DimZMin:DimZMax)
     end function fs_dx_ss
  end interface

  interface fs_dz_ff
     function fs_dz_ff(var) 
       use gridset
       real(8), intent(in) :: var(DimXMin:DimXMax, DimZMin:DimZMax)
       real(8)             :: fs_dz_ff(DimXMin:DimXMax, DimZMin:DimZMax)
     end function fs_dz_ff
  end interface

  interface sf_dx_ff
     function sf_dx_ff(var) 
       use gridset
       real(8), intent(in) :: var(DimXMin:DimXMax, DimZMin:DimZMax)
       real(8)             :: sf_dx_ff(DimXMin:DimXMax, DimZMin:DimZMax)
     end function sf_dx_ff
  end interface

  interface sf_dz_ss
     function sf_dz_ss(var) 
       use gridset
       real(8), intent(in) :: var(DimXMin:DimXMax, DimZMin:DimZMax)
       real(8)             :: sf_dz_ss(DimXMin:DimXMax, DimZMin:DimZMax)
     end function sf_dz_ss
  end interface

  interface ff_dz_fs
     function ff_dz_fs(var) 
       use gridset
       real(8), intent(in) :: var(DimXMin:DimXMax, DimZMin:DimZMax)
       real(8)             :: ff_dz_fs(DimXMin:DimXMax, DimZMin:DimZMax)
     end function ff_dz_fs
  end interface

  interface ff_dx_sf
     function ff_dx_sf(var) 
       use gridset
       real(8), intent(in) :: var(DimXMin:DimXMax, DimZMin:DimZMax)
       real(8)             :: ff_dx_sf(DimXMin:DimXMax, DimZMin:DimZMax)
     end function ff_dx_sf
  end interface

end module differentiate_center2


!!!
!!!格子点位置 ss での微分
!!!
function ss_dx_fs(var) 
  use gridset
  implicit none

  real(8), intent(in) :: var(DimXMin:DimXMax, DimZMin:DimZMax)
  real(8)             :: ss_dx_fs(DimXMin:DimXMax, DimZMin:DimZMax)
  
  ss_dx_fs = 0.0d0 
  ss_dx_fs(DimXMin+1 : DimXMax, DimZMin : DimZMax) =       &
       &  (                                 &
       &     var(DimXMin+1 : DimXMax, DimZMin : DimZMax)     &
       &   - var(DimXMin   : DimXMax-1, DimZMin : DimZMax)     &
       &  ) / DelX
end function ss_dx_fs


function ss_dz_sf(var) 
  use gridset
  implicit none
  
  real(8), intent(in) :: var(DimXMin:DimXMax, DimZMin:DimZMax)
  real(8)             :: ss_dz_sf(DimXMin:DimXMax, DimZMin:DimZMax)
  
  ss_dz_sf = 0.0d0 
  ss_dz_sf(DimXMin:DimXMax,DimZMin+1:DimZMax) =        &
       &  (                                 &
       &     var(DimXMin:DimXMax,DimZMin+1:DimZMax)     &
       &   - var(DimXMin:DimXMax,DimZMin:DimZMax-1)     &
       &  ) / DelZ
end function ss_dz_sf



!!!
!!!速度 u の位置での微分演算
!!!
function fs_dx_ss(var) 
  use gridset
  implicit none
  
  real(8), intent(in) :: var(DimXMin:DimXMax, DimZMin:DimZMax)
  real(8)             :: fs_dx_ss(DimXMin:DimXMax, DimZMin:DimZMax)
  
  fs_dx_ss = 0.0d0
  fs_dx_ss(DimXMin:DimXMax-1,DimZMin:DimZMax) =        &
       &  (                                 &
       &     var(DimXMin+1:DimXMax,DimZMin:DimZMax)     &
       &   - var(DimXMin:DimXMax-1,DimZMin:DimZMax)     &
       &  ) / DelX
end function fs_dx_ss

function fs_dz_ff(var) 
  use gridset
  implicit none
  
  real(8), intent(in) :: var(DimXMin:DimXMax, DimZMin:DimZMax)
  real(8)             :: fs_dz_ff(DimXMin:DimXMax, DimZMin:DimZMax)
  
  fs_dz_ff = 0.0d0 
  fs_dz_ff(DimXMin:DimXMax,DimZMin+1:DimZMax) =       & 
       &  (                                           &
       &      var(DimXMin:DimXMax,DimZMin+1:DimZMax)  &
       &   -  var(DimXMin:DimXMax,DimZMin:DimZMax-1)  &
       &  ) / DelZ
end function fs_dz_ff


  

!!!
!!!速度 w の位置での微分操作
!!!
function sf_dz_ss(var) 
  use gridset
  implicit none

  real(8), intent(in) :: var(DimXMin:DimXMax, DimZMin:DimZMax)
  real(8)             :: sf_dz_ss(DimXMin:DimXMax, DimZMin:DimZMax)

  sf_dz_ss = 0.0d0 
  sf_dz_ss(DimXMin:DimXMax,DimZMin:DimZMax-1) =        &
       &  (                                 &
       &   + var(DimXMin:DimXMax,DimZMin+1:DimZMax)     &
       &   - var(DimXMin:DimXMax,DimZMin:DimZMax-1)     &
       &  ) / DelZ
end function sf_dz_ss


function sf_dx_ff(var) 
  use gridset
  implicit none
  
  real(8), intent(in) :: var(DimXMin:DimXMax, DimZMin:DimZMax)
  real(8)             :: sf_dx_ff(DimXMin:DimXMax, DimZMin:DimZMax)
    
  sf_dx_ff = 0.0d0 
  sf_dx_ff(DimXMin+1:DimXMax,DimZMin:DimZMax) =           & 
       &  (                                       &
       &      var(DimXMin+1:DimXMax,DimZMin:DimZMax)   &
       &   -  var(DimXMin:DimXMax-1,DimZMin:DimZMax)   &
       &  ) / DelX
end function sf_dx_ff
  


!!!
!!! ff 格子点位置での微分
!!!

function ff_dz_fs(var) 
  use gridset
  implicit none

  real(8), intent(in) :: var(DimXMin:DimXMax, DimZMin:DimZMax)
  real(8)             :: ff_dz_fs(DimXMin:DimXMax, DimZMin:DimZMax)
    
  ff_dz_fs = 0.0d0 
  ff_dz_fs(DimXMin:DimXMax,DimZMin:DimZMax-1) =       & 
       &  (                                           &
       &      var(DimXMin:DimXMax,DimZMin+1:DimZMax)  &
       &   -  var(DimXMin:DimXMax,DimZMin:DimZMax-1)  &
       &  ) / DelZ
end function ff_dz_fs


function ff_dx_sf(var) 
  use gridset
  implicit none

  real(8), intent(in) :: var(DimXMin:DimXMax, DimZMin:DimZMax)
  real(8)             :: ff_dx_sf(DimXMin:DimXMax, DimZMin:DimZMax)
    
  ff_dx_sf = 0.0d0 
  ff_dx_sf(DimXMin:DimXMax-1,DimZMin:DimZMax) =           & 
       &  (                                       &
       &      var(DimXMin+1:DimXMax,DimZMin:DimZMax)   &
       &   -  var(DimXMin:DimXMax-1,DimZMin:DimZMax)   &
       &  ) / DelX
end function ff_dx_sf


