module Derivate_Field_UniformGrid1D

  ! モジュール引用 ; Use statements
  !

  !* gtool *****
  !*

  !
  !
  !
  use dc_types, only: DP

  ! 宣言文 ; Declaration statements
  !
  implicit none
  private

  ! 公開手続き
  ! Public procedures
  !
  public :: delx_2ord_3pts_ufGrid, deldelx_2ord_3pts_ufGrid

contains

function delx_2ord_3pts_ufGrid(field1D, DelX) result(del_field1D)

  ! 宣言文 ; Declaration statements
  !
  real(DP), intent(in) :: field1D(:,:)
  real(DP), intent(in) :: DelX
  real(DP) :: del_field1D(size(field1D,1), size(field1D,2))

  ! 作業変数
  ! Work variables
  !
  integer :: k
  integer :: kMax
  real(DP) :: TwoDelX

  ! 実行文 ; Executable statements
  !

  kMax = size(field1D,1)
  TwoDelX = 2.0d0 * DelX

  do k=2, kMax-1
    del_field1D(k,:) = ( field1D(k+1,:) - field1D(k-1,:) ) / TwoDelX
  end do

  del_field1D(1,:) =  ( field1D(2,:)  - field1D(1,:) ) / DelX
  del_field1D(kMax,:) =  ( field1D(kMax,:) - field1D(kMax-1,:) ) / DelX
  
!  del_field1D(1,:) =  ( - 3.0d0 * field1D(1,:) + 4.0d0 * field1D(2,:) - field1D(3,:) ) / TwoDelX
!  del_field1D(kMax,:) =  ( 3.0d0 * field1D(kMax,:) - 4.0d0 * field1D(kMax-1,:) + field1D(kMax-2,:) ) / TwoDelX

!  del_field1D(1,:) =  &
!  ( &
!  -25d0 * field1D(1,:) + 48d0 * field1D(2,:) - 36d0 * field1D(3,:) + 16d0 * field1D(4,:) - 3d0 * field1D(5,:) &
! ) / ( 12d0 * DelX )

!  del_field1D(kMax,:) =  &
!  ( &
!  &   25d0 * field1D(KMax,:) - 48d0 * field1D(kMax-1,:) + 36d0 * field1D(kMax-2,:) & 
!  &   - 16d0 * field1D(kMax-3,:) + 3d0 * field1D(kMax-4,:) &
!  & ) / ( 12d0 * DelX )
  
end function delx_2ord_3pts_ufGrid

function deldelx_2ord_3pts_ufGrid(field1D, DelX) result(deldel_field1D)

  ! 宣言文 ; Declaration statements
  !
  real(DP), intent(in) :: field1D(:,:)
  real(DP), intent(in) :: DelX
  real(DP) :: deldel_field1D(size(field1D,1), size(field1D,2))

  ! 作業変数
  ! Work variables
  !
  integer :: k
  integer :: kMax
  real(DP) :: DelXDelX

  ! 実行文 ; Executable statements
  !

  kMax = size(field1D,1)
  DelXDelX = DelX**2

  do k=2, kMax-1
    deldel_field1D(k,:) = ( field1D(k+1,:) + field1D(k-1,:) - 2.0d0 * field1D(k,:) ) / DelXDelX
  end do

  deldel_field1D(1,:) =  &
  ( &
  2.0d0 * field1D(1,:) - 5.0d0 * field1D(2,:) + 4.0d0 * field1D(3,:) - field1D(4,:) &
  ) / DelXDelX 
  
  deldel_field1D(kMax,:) = &
  ( &
  2.0d0 * field1D(kMax,:) - 5.0d0 * field1D(kMax-1,:) + 4.0d0 * field1D(kMax-2,:) - field1D(kMax-3,:) &
  ) / DelXDelX

!  deldel_field1D(1,:) =  &
!  ( &
!  & 45d0 * field1D(1,:) - 154d0 * field1D(2,:) + 214d0 * field1D(3,:) & 
!  & - 156d0 * field1D(4,:) + 61d0 * field1D(5,:) - 10d0 * field1D(6,:) &
!  ) / ( 12d0 * DelXDelX ) 

!  deldel_field1D(kMax,:) =  &
!  ( &
!  & 45d0 * field1D(kMax,:) - 154d0 * field1D(kMax-1,:) + 214d0 * field1D(kMax-2,:) & 
!  & - 156d0 * field1D(kMax-3,:) + 61d0 * field1D(kMax-4,:) - 10d0 * field1D(kMax-5,:) &
!  ) / ( 12d0 * DelXDelX ) 


end function deldelx_2ord_3pts_ufGrid


end module Derivate_Field_UniformGrid1D
