!
! Derivatives 1, 2 in 1-dim
!
module derivatives

CONTAINS

  subroutine FirstDeriv_1d(npts, dx, u, u_x)
    implicit none
    integer, intent(in) :: npts
    real, intent(in) :: dx
    real, dimension(:), intent(in) :: u
    real, dimension(:), intent(out) :: u_x
    real two_invdx
    integer i
    two_invdx = 1d0/(2d0*dx)
    ! central...
    do i=2,npts-1
       u_x(i)=(u(i+1)-u(i-1))*two_invdx
    end do
    ! forward...
    u_x(1)=(-3.*u(1)+4.*u(2)-u(3))*two_invdx
    ! backward
    u_x(npts)=(3.*u(npts)-4.*u(npts-1)+u(npts-2))*two_invdx
  end subroutine FirstDeriv_1d

  subroutine SecondDeriv_1d(npts, dx, u, u_xx)
    implicit none
    integer, intent(in) :: npts
    real, intent(in) :: dx
    real, dimension(:), intent(in) :: u
    real, dimension(:), intent(out) :: u_xx
    real inv_dx2
    integer i
    inv_dx2=1d0/(dx*dx)
    ! forward...
    u_xx(1)=(2.*u(1)-5.*u(2)+4.*u(3)-u(4))*inv_dx2
    ! central...
    do i=2,npts-1
       u_xx(i)=(u(i+1)-2.*u(i)+u(i-1))*inv_dx2
    end do
    ! backward
    u_xx(npts)=(2.*u(npts)-5.*u(npts-1)+4.*u(npts-2)-u(npts-3))*inv_dx2
  end subroutine SecondDeriv_1d

end module derivatives
