!
!---------------------------------------------------------------------
!
MODULE BASIC_FUNCTIONS
!
!  This module contains basic functions of general use:
!
!           * Lorentzian
!           * Gaussian
!           * Numerical Dirac Delta 
!           * Slater-type and Gaussian-type orbitals
!
!  Modules used: ACCURACY_REAL
!                PI_ETC
!                SQUARE_ROOTS
!                REAL_NUMBERS
!                FACTORIALS
!
      USE ACCURACY_REAL
      USE PI_ETC
      USE SQUARE_ROOTS
      USE REAL_NUMBERS
      USE FACTORIALS
!
CONTAINS
!
!---------------------------------------------------------------------
!
      FUNCTION LORENTZIAN(X,X0,GAMMA)
!
!  This function computes the Lorentzian function L(x) normalized to unity:
!
!           L(x) = 1/pi * gamma / ([x - x0]^2 + gamma^2)
!
!  Input parameters:
!
!           X          :  value at which the function is computed 
!           X0         :  center paramameter
!           GAMMA      :  half width at half maximum
!
!  Output parameter:
!
!           LORENTZIAN :  value of the function at X
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified :  5 Aug 2020
!
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN)      ::   X,X0,GAMMA
      REAL (WP)                  ::   LORENTZIAN
!
      LORENTZIAN = PI_INV * GAMMA / ( (X-X0)*(X-X0) + GAMMA*GAMMA  )!
!      
      END FUNCTION LORENTZIAN
!
!---------------------------------------------------------------------
!
      FUNCTION GAUSSIAN(X,X0,SIGMA)
!
!  This function computes the Gaussian function G(x)  normalized to unity:
!
!           G(x) = (1/sigma sqrt(2 pi)) * exp[ -1/2 * (x-x0)^2 / sigma^2 ]
!
!
!  Input parameters:
!
!           X          :  value at which the function is computed 
!           X0         :  expected value
!           SIGMA      :  variance
!
!  Output parameter:
!
!           GAUSSIAN   :  value of the function at X
!
!  Note: the half width at half maximum is given by sigma * sqrt[2 Ln(2)]
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified :  5 Aug 2020
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN)      ::   X,X0,SIGMA
      REAL (WP)                  ::   GAUSSIAN
!
      REAL (WP)                  ::   EXP
!
      GAUSSIAN = PI_INV * EXP(-HALF * (X - X0) * (X - X0) /       & !
                 (SIGMA * SIGMA) ) / (SIGMA * SQR2)                 !
!
      END FUNCTION GAUSSIAN
!
!---------------------------------------------------------------------
!
      FUNCTION DELTA(X,I_D,EPSI)
!
!  This function computes the numerical Dirac Delta function
!
!
!  Input parameters:
!
!           X          :  value at which the function is computed
!           I_D        :  type of numerical approximation used
!
!                     = 1  :  lim [ eps -> 0 ] 1/pi eps/(x^2 + eps^2)
!                     = 2  :  lim [ eps -> 0 ] 1/(pi*x) sin(x/eps)
!                     = 3  :  lim [ eps -> 0 ] 1/2 eps |x|^{eps-1}
!                     = 4  :  lim [ eps -> 0 ] 1/(2*sqrt(pi eps}) e^{- x^2/(4 eps)}
!                     = 5  :  lim [ eps -> 0 ] 1/(2 eps) e^{- |x|/eps)
!                     = 6  :  lim [ eps -> 0 ] 1/eps Ai(x/eps)
!                     = 7  :  lim [ eps -> 0 ] 1/eps J_{1/eps}([x+1]/eps)
!                     = 8  :  lim [ eps -> 0 ] | 1/eps e^{- x^2/eps} Ln(2x/eps)
!           EPSI       :  small eps value 
!
!  Output parameter:
!
!           DELTA      :  value of the function at X
!
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified :  5 Aug 2020
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN)      ::   X
      REAL (WP)                  ::   DELTA
      REAL (WP)                  ::   EPSI
!
      REAL (WP)                  ::   SIN,ABS,EXP,SQRT
!
      INTEGER, INTENT(IN)        ::   I_D
!
      IF(I_D == 1) THEN                                             !
        DELTA = PI_INV * EPSI / ( X * X + EPSI * EPSI)              !
      ELSE IF(I_D == 2) THEN                                        !
        DELTA = PI_INV * SIN( X / EPSI) / X                         !
      ELSE IF(I_D == 3) THEN                                        !
        DELTA = HALF * EPSI * ABS(X)**(EPSI-1)                      !
      ELSE IF(I_D == 4) THEN                                        !
        DELTA = HALF * EXP( - FOURTH * X * X / EPSI) /            & !
                (SQR_PI * SQRT(EPSI))                               !
      ELSE IF(I_D == 5) THEN                                        !
        DELTA = HALF * EXP(- ABS(X) / EPSI) /EPSI                   !
      END IF
!
      END FUNCTION DELTA
!
!---------------------------------------------------------------------
!
      FUNCTION STO(N,ALPHA,R)
!
!  This function computes Slater-type orbitals normalized to unity::
!
!           STO = A * r^{n-1} * e^{- zeta r}
!
!
!  Input parameters:
!
!           N          :  principal quantum number
!           ALPHA      :  function parameter
!           R          :  value at which the function is computed
!
!  Output parameter:
!
!           STO        :  value of the function at R
!
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified :  5 Aug 2020
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN)      ::   ALPHA,R
      REAL (WP)                  ::   STO
      REAL (WP)                  ::   A,TWOZ
!
      REAL (WP)                  ::   SQRT,EXP
!
      INTEGER, INTENT(IN)        ::   N
!
      TWOZ = TWO * ALPHA                                            !
      A = TWOZ**N * SQRT(TWOZ / FAC(2*N))                           !
      STO = A * R**(N-1) * EXP(-ALPHA * R)                          ! normalisation constant
!
      END FUNCTION STO
!
!---------------------------------------------------------------------
!
      FUNCTION GTO(N,ALPHA,R)
!
!  This function computes Gaussian-type orbitals normalized to unity::
!
!           GTO = A * r^{n-1} * e^{- zeta r^2}
!
!
!  Input parameters:
!
!           N          :  principal quantum number
!           ALPHA      :  function parameter
!           R          :  value at which the function is computed
!
!  Output parameter:
!
!           GTO        :  value of the function at R
!
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified :  5 Aug 2020
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN)      ::   ALPHA,R
      REAL (WP)                  ::   GTO
      REAL (WP)                  ::   A,TWOZ,NN
      REAL (WP)                  ::   GAMMA
!
      REAL (WP)                  ::   SQRT,EXP
!
      INTEGER, INTENT(IN)        ::   N
!
      TWOZ = TWO * ALPHA                                            !
      NN = N + HALF                                                 !
      GAMMA = SQR_PI * FAC(2*N) / (FOUR**N * FAC(N))                !
      A = SQRT(TWO * TWOZ**NN / GAMMA)                              ! normalisation constant
      GTO = A * R**(N-1) * EXP(-ALPHA * R * R)                      !
!
      END FUNCTION GTO
!
END MODULE BASIC_FUNCTIONS
