!
!=======================================================================
!
MODULE MEMORY_FUNCTIONS_F
!
!  This modules provides memory functions in terms of the frequency
!
!
!
      USE ACCURACY_REAL
!
CONTAINS
!
!=======================================================================
!
      FUNCTION MEMORY_F(V,TAU,TAU2,PCT,ALPHA,BETA,MEM_TYPE)
!
!  This function computes the memory function K(tau,omega)
!
!
!
!  Input parameters:
!
!       * V        : dimensionless factor   --> V = h_bar omega / E_F
!       * TAU      : relaxation time in SI
!       * TAU2     : second relaxation time in SI
!       * PCT      : weight of first function (0 < PCT <1)
!       * MEM_TYPE : type of memory function used
!                      MEM_TYPE  = 'NONE' --> no function
!                      MEM_TYPE  = 'DELT' --> delta function
!                      MEM_TYPE  = 'DGAU' --> double Gaussian functions
!                      MEM_TYPE  = 'EXPO' --> exponential function
!                      MEM_TYPE  = 'GAUS' --> Gaussian function
!                      MEM_TYPE  = 'LORE' --> Lorentzian function
!                      MEM_TYPE  = 'SINC' --> sinc function
!                      MEM_TYPE  = 'BES0' --> J_0(t) function
!                      MEM_TYPE  = 'BES1' --> J_1(t)/t function
!                      MEM_TYPE  = 'SEC2' --> sech^2(t) function
!                      MEM_TYPE  = 'COCO' --> Cole-Cole function
!                      MEM_TYPE  = 'CODA' --> Cole-Davidson function
!                      MEM_TYPE  = 'HANE' --> Habriliak-Negami function
!                      MEM_TYPE  = 'RAYI' --> Raganathan-Yip function
!                      MEM_TYPE  = 'LIHY' --> linearized hydrodynamic function
!       * ALPHA    : value of the Habriliak-Negami first parameter  (in ]0,1])
!       * BETA     : value of the Habriliak-Negami second parameter (in ]0,1])
!
!
!  Remark: The memory function has the dimension of a frequency omega
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 27 Jan 2021
!
!
      USE REAL_NUMBERS,       ONLY : ZERO
      USE FERMI_SI,           ONLY : EF_SI
      USE CONSTANTS_P1,       ONLY : H_BAR
!
      IMPLICIT NONE
!
      CHARACTER (LEN = 4)   ::  MEM_TYPE
!
      REAL (WP), INTENT(IN) ::  V,TAU,TAU2,PCT,ALPHA,BETA
!
      REAL (WP)             ::  OMEGA
!
      COMPLEX (WP)          ::  MEMORY_F
!
      OMEGA = V * EF_SI / H_BAR                                     ! omega in SI
!
      IF(MEM_TYPE == 'NONE') THEN                                   !
        MEMORY_F = ZERO                                             !
      ELSE IF(MEM_TYPE == 'DELT') THEN                              !
        MEMORY_F = DELTA_F(TAU,OMEGA)                               !
      ELSE IF(MEM_TYPE == 'DGAU') THEN                              !
        MEMORY_F = DGAUS_F(TAU,TAU2,PCT,OMEGA)                      !
      ELSE IF(MEM_TYPE == 'EXPO') THEN                              !
        MEMORY_F = EXPON_F(TAU,OMEGA)                               !
      ELSE IF(MEM_TYPE == 'GAUS') THEN                              !
        MEMORY_F = GAUSS_F(TAU,OMEGA)                               !
      ELSE IF(MEM_TYPE == 'LORE') THEN                              !
        MEMORY_F = LOREN_F(TAU,OMEGA)                               !
      ELSE IF(MEM_TYPE == 'SINC') THEN                              !
        MEMORY_F = SINCF_F(TAU,OMEGA)                               !
      ELSE IF(MEM_TYPE == 'BES0') THEN                              !
        MEMORY_F = BES_0_F(TAU,OMEGA)                               !
      ELSE IF(MEM_TYPE == 'BES1') THEN                              !
        MEMORY_F = BES_1_F(TAU,OMEGA)                               !
      ELSE IF(MEM_TYPE == 'SEC2') THEN                              !
        MEMORY_F = SECH2_F(TAU,OMEGA)                               !
      ELSE IF(MEM_TYPE == 'COCO') THEN                              !
        MEMORY_F = CO_CO_F(TAU,OMEGA,ALPHA)                         !
      ELSE IF(MEM_TYPE == 'CODA') THEN                              !
        MEMORY_F = CO_DA_F(TAU,OMEGA,BETA)                          !
      ELSE IF(MEM_TYPE == 'HANE') THEN                              !
        MEMORY_F = HA_NE_F(TAU,OMEGA,ALPHA,BETA)                    !
      END IF                                                        !
!
      END FUNCTION MEMORY_F
!
!=======================================================================
!
      FUNCTION DELTA_F(TAU,OMEGA)
!
!  This function computes the frequency memory function when
!    the time-dependent function is a delta function
!
!
!  Input parameters:
!
!       * TAU      : relaxation time in SI
!       * OMEGA    : frequency in SI
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 26 Jan 2021
!
!
      USE REAL_NUMBERS,       ONLY : ONE,HALF
      USE PI_ETC,             ONLY : PI_INV
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  TAU,OMEGA
!
      COMPLEX (WP)          ::  DELTA_F
!
      COMPLEX (WP)          ::  CMPLX
!
      DELTA_F = CMPLX(HALF * PI_INV / TAU)                          !
!
      END FUNCTION DELTA_F
!
!=======================================================================
!
      FUNCTION DGAUS_F(TAU,TAU2,PCT,OMEGA)
!
!  This function computes the frequency memory function when
!    the time-dependent function is sum of 2 Gaussian functions
!
!
!  Input parameters:
!
!       * TAU      : relaxation time in SI
!       * TAU2     : second relaxation time in SI
!       * PCT      : seconf relaxation time in SI
!       * OMEGA    : frequency in SI
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 30 Apr 2021
!
!
      USE MINMAX_VALUES
!
      USE REAL_NUMBERS,       ONLY : ZERO,ONE,FOURTH
      USE PI_ETC,             ONLY : PI
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  TAU,TAU2,PCT,OMEGA
!
      REAL (WP)             ::  EXPO1,EXPO2
      REAL (WP)             ::  MAX_EXP,MIN_EXP
      REAL (WP)             ::  NUM1,DEN1,NUM2,DEN2
!
      REAL (WP)             ::  EXP
!
      COMPLEX (WP)          ::  DGAUS_F
!
      COMPLEX (WP)          ::  CMPLX
!
!  Computing the max and min value of the exponent of e^x
!
      CALL MINMAX_EXP(MAX_EXP,MIN_EXP)                              !
!
      EXPO1 = FOURTH * TAU  * TAU  * OMEGA * OMEGA                  !
      EXPO2 = FOURTH * TAU2 * TAU2 * OMEGA * OMEGA                  !
!
      IF(- EXPO1 > MIN_EXP) THEN                                    !
        NUM1 = EXP(- EXPO1)                                         !
        DEN1 = PI * TAU                                             !
      ELSE                                                          !
        NUM1 = ZERO                                                 !
        DEN1 = ONE                                                  !
      END IF                                                        !
!
      IF(- EXPO2 > MIN_EXP) THEN                                    !
        NUM2 = EXP(- EXPO2)                                         !
        DEN2 = PI * TAU2                                            !
      ELSE                                                          !
        NUM2 = ZERO                                                 !
        DEN2 = ONE                                                  !
      END IF                                                        !
!
      DGAUS_F =          PCT * CMPLX(NUM1 / DEN1,KIND=WP) +       & !
                 (ONE - PCT) * CMPLX(NUM2 / DEN2,KIND=WP)           !
!
      END FUNCTION DGAUS_F
!
!=======================================================================
!
      FUNCTION EXPON_F(TAU,OMEGA)
!
!  This function computes the frequency memory function when
!    the time-dependent function is a exponential function
!
!
!  Input parameters:
!
!       * TAU      : relaxation time in SI
!       * OMEGA    : frequency in SI
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 26 Jan 2021
!
!
      USE REAL_NUMBERS,       ONLY : ONE
      USE PI_ETC,             ONLY : PI_INV
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  TAU,OMEGA
!
      REAL (WP)             ::  DENOM
!
      COMPLEX (WP)          ::  EXPON_F
!
      COMPLEX (WP)          ::  CMPLX
!
      DENOM = TAU * (ONE + TAU * TAU * OMEGA * OMEGA)           !
!
      EXPON_F = CMPLX(PI_INV / DENOM)                           !
!
      END FUNCTION EXPON_F
!
!=======================================================================
!
      FUNCTION GAUSS_F(TAU,OMEGA)
!
!  This function computes the frequency memory function when
!    the time-dependent function is a Gaussian function
!
!
!  Input parameters:
!
!       * TAU      : relaxation time in SI
!       * OMEGA    : frequency in SI
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 21 Apr 2021
!
!
      USE MINMAX_VALUES
!
      USE REAL_NUMBERS,       ONLY : ZERO,ONE,FOURTH
      USE PI_ETC,             ONLY : PI
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  TAU,OMEGA
!
      REAL (WP)             ::  EXPO
      REAL (WP)             ::  MAX_EXP,MIN_EXP
      REAL (WP)             ::  NUM,DEN
!
      REAL (WP)             ::  EXP
!
      COMPLEX (WP)          ::  GAUSS_F
!
      COMPLEX (WP)          ::  CMPLX
!
!  Computing the max and min value of the exponent of e^x
!
      CALL MINMAX_EXP(MAX_EXP,MIN_EXP)                              !
!
      EXPO = FOURTH * TAU * TAU * OMEGA * OMEGA                     !
!
      IF(- EXPO > MIN_EXP) THEN                                     !
        NUM = EXP(- EXPO)                                           !
        DEN = PI * TAU                                              !
      ELSE                                                          !
        NUM = ZERO                                                  !
        DEN = ONE                                                   !
      END IF                                                        !
!
      GAUSS_F = CMPLX(NUM / DEN,KIND=WP)                            !
!
      END FUNCTION GAUSS_F
!
!=======================================================================
!
      FUNCTION LOREN_F(TAU,OMEGA)
!
!  This function computes the frequency memory function when
!    the time-dependent function is a Lorentzian function
!
!
!  Input parameters:
!
!       * TAU      : relaxation time in SI
!       * OMEGA    : frequency in SI
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 21 Apr 2021
!
!
      USE MINMAX_VALUES
!
      USE REAL_NUMBERS,       ONLY : ZERO,ONE
      USE PI_ETC,             ONLY : PI
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  TAU,OMEGA
!
      REAL (WP)             ::  EXPO
      REAL (WP)             ::  MAX_EXP,MIN_EXP
      REAL (WP)             ::  NUM,DEN
!
      REAL (WP)             ::  EXP
!
      COMPLEX (WP)          ::  LOREN_F
!
      COMPLEX (WP)          ::  CMPLX
!
!  Computing the max and min value of the exponent of e^x
!
!
      CALL MINMAX_EXP(MAX_EXP,MIN_EXP)                              !
!
      EXPO = TAU * OMEGA                                            !
!
      IF(- EXPO > MIN_EXP) THEN                                     !
        NUM = EXP(- EXPO)                                           !
        DEN = PI * TAU                                              !
      ELSE                                                          !
        NUM = ZERO                                                  !
        DEN = ONE                                                   !
      END IF                                                        !
!
      LOREN_F = CMPLX(NUM / DEN,KIND=WP)                            !
!
      END FUNCTION LOREN_F
!
!=======================================================================
!
      FUNCTION SINCF_F(TAU,OMEGA)
!
!  This function computes the frequency memory function when
!    the time-dependent function is a sinc function
!
!
!  Input parameters:
!
!       * TAU      : relaxation time in SI
!       * OMEGA    : frequency in SI
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 27 Jan 2021
!
!
      USE REAL_NUMBERS,       ONLY : ONE
      USE COMPLEX_NUMBERS,    ONLY : ZEROC
      USE PI_ETC,             ONLY : PI_INV
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  TAU,OMEGA
!
      COMPLEX (WP)          ::  SINCF_F
!
      COMPLEX (WP)          ::  CMPLX
!
      IF(OMEGA * TAU <= ONE) THEN                                   !
        SINCF_F = CMPLX(PI_INV / TAU)                               !
      ELSE                                                          !
        SINCF_F = ZEROC                                             !
      END IF                                                        !
!
      END FUNCTION SINCF_F
!
!=======================================================================
!
      FUNCTION BES_0_F(TAU,OMEGA)
!
!  This function computes the frequency memory function when
!    the time-dependent function is a J_0 function
!
!
!  Input parameters:
!
!       * TAU      : relaxation time in SI
!       * OMEGA    : frequency in SI
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 26 Jan 2021
!
!
      USE REAL_NUMBERS,       ONLY : ONE
      USE PI_ETC,             ONLY : PI_INV
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  TAU,OMEGA
!
      REAL (WP)             ::  DENOM
!
      REAL (WP)             ::  SQRT
!
      COMPLEX (WP)          ::  BES_0_F
!
      COMPLEX (WP)          ::  CMPLX
!
      DENOM = TAU * SQRT(ONE - TAU * TAU * OMEGA * OMEGA)           !
!
      BES_0_F = CMPLX(PI_INV / DENOM)                               !
!
      END FUNCTION BES_0_F
!
!=======================================================================
!
      FUNCTION BES_1_F(TAU,OMEGA)
!
!  This function computes the frequency memory function when
!    the time-dependent function is a J_1(t)/t function
!
!
!  Input parameters:
!
!       * TAU      : relaxation time in SI
!       * OMEGA    : frequency in SI
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 27 Jan 2021
!
!
      USE REAL_NUMBERS,       ONLY : ONE,HALF,FOURTH
      USE PI_ETC,             ONLY : PI_INV
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  TAU,OMEGA
!
      REAL (WP)             ::  NUM
!
      REAL (WP)             ::  SQRT
!
      COMPLEX (WP)          ::  BES_1_F
!
      COMPLEX (WP)          ::  CMPLX
!
      NUM = SQRT(ONE - TAU * TAU * OMEGA * OMEGA * FOURTH)          !
!
      BES_1_F = CMPLX(HALF * PI_INV * NUM / TAU)                    !
!
      END FUNCTION BES_1_F
!
!=======================================================================
!
      FUNCTION SECH2_F(TAU,OMEGA)
!
!  This function computes the frequency memory function when
!    the time-dependent function is a sech^2(t) function
!
!
!  Input parameters:
!
!       * TAU      : relaxation time in SI
!       * OMEGA    : frequency in SI
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 27 Jan 2021
!
!
      USE REAL_NUMBERS,       ONLY : ONE,HALF
      USE PI_ETC,             ONLY : PI
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  TAU,OMEGA
!
      REAL (WP)             ::  DENOM
!
      REAL (WP)             ::  SINH
!
      COMPLEX (WP)          ::  SECH2_F
!
      COMPLEX (WP)          ::  CMPLX
!
      DENOM = SINH(PI * HALF * OMEGA * TAU)                         !
!
      SECH2_F = CMPLX(HALF * OMEGA / DENOM)                         !
!
      END FUNCTION SECH2_F
!
!=======================================================================
!
      FUNCTION CO_CO_F(TAU,OMEGA,ALPHA)
!
!  This function computes the Cole-Cole memory function
!
!
!  References: (1) A. A. Khamzin, R. R. Nigmatullin, and I. I. Popov,
!                  Theor. Math. Phys. 173, 1604–1619 (2012)
!
!
!  Input parameters:
!
!       * TAU      : relaxation time in SI
!       * OMEGA    : frequency in SI
!       * ALPHA    : value of the Habriliak-Negami first parameter  (in ]0,1])
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 27 Jan 2021
!
!
      USE REAL_NUMBERS,       ONLY : ONE,HALF
      USE PI_ETC,             ONLY : PI,PI_INV
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  TAU,OMEGA,ALPHA
!
      REAL (WP)             ::  EXPO,NUM,DEN
!
      REAL (WP)             ::  COS
!
      COMPLEX (WP)          ::  CO_CO_F
!
      COMPLEX (WP)          ::  CMPLX
!
      EXPO = ONE - ALPHA                                             !
      NUM  = COS(HALF * EXPO * PI) * OMEGA**EXPO                     !
      DEN  = TAU**ALPHA                                              !
!
      CO_CO_F = CMPLX(NUM / DEN)                                     !
!
      END FUNCTION CO_CO_F
!
!=======================================================================
!
      FUNCTION CO_DA_F(TAU,OMEGA,BETA)
!
!  This function computes the Cole-Davidson memory function
!
!
!  References: (1) A. A. Khamzin, R. R. Nigmatullin, and I. I. Popov,
!                  Theor. Math. Phys. 173, 1604–1619 (2012)
!
!
!  Input parameters:
!
!       * TAU      : relaxation time in SI
!       * OMEGA    : frequency in SI
!       * BETA     : value of the Habriliak-Negami second parameter (in ]0,1])
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 27 Jan 2021
!
!
      USE REAL_NUMBERS,       ONLY : ONE
      USE COMPLEX_NUMBERS,    ONLY : IC
      USE PI_ETC,             ONLY : PI_INV
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  TAU,OMEGA,BETA
!
      REAL (WP)             ::  REAL
!
      COMPLEX (WP)          ::  CO_DA_F
      COMPLEX (WP)          ::  NUM,DEN
!
      COMPLEX (WP)          ::  CMPLX
!
      NUM = IC * OMEGA * PI_INV                                     !
      DEN = (ONE + IC * OMEGA * TAU)**BETA - ONE                    !
!
      CO_DA_F = CMPLX( REAL(NUM / DEN,KIND=WP) )                    !
!
      END FUNCTION CO_DA_F
!
!=======================================================================
!
      FUNCTION HA_NE_F(TAU,OMEGA,ALPHA,BETA)
!
!  This function computes the Havriliak-Negami memory function
!
!
!  References: (1) A. A. Khamzin, R. R. Nigmatullin, and I. I. Popov,
!                  Theor. Math. Phys. 173, 1604–1619 (2012)
!
!
!  Input parameters:
!
!       * TAU      : relaxation time in SI
!       * OMEGA    : frequency in SI
!       * ALPHA    : value of the Habriliak-Negami first parameter  (in ]0,1])
!       * BETA     : value of the Habriliak-Negami second parameter (in ]0,1])
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 27 Jan 2021
!
!
      USE REAL_NUMBERS,       ONLY : ONE
      USE COMPLEX_NUMBERS,    ONLY : IC
      USE PI_ETC,             ONLY : PI_INV
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  TAU,OMEGA,ALPHA,BETA
!
      REAL (WP)             ::  REAL
!
      COMPLEX (WP)          ::  HA_NE_F
      COMPLEX (WP)          ::  NUM,DEN
!
      COMPLEX (WP)          ::  CMPLX
!
      NUM = IC * OMEGA * PI_INV                                     !
      DEN = ( ONE + (IC * OMEGA * TAU)**ALPHA )**BETA - ONE         !
!
      HA_NE_F = CMPLX( REAL(NUM / DEN,KIND=WP) )                    !
!
      END FUNCTION HA_NE_F
!
!=======================================================================
!
END MODULE MEMORY_FUNCTIONS_F
!
!=======================================================================
!
MODULE MEMORY_FUNCTIONS_T
!
!  This modules provides memory functions in terms of the time
!
!
!
      USE ACCURACY_REAL
!
CONTAINS
!
!=======================================================================
!
      FUNCTION MEMORY_T(T,TAU,TAU2,PCT,ALPHA,BETA,MEM_TYPE)
!
!  This function computes the memory function K(t,tau)
!
!
!
!  Input parameters:
!
!       * T        : time in SI
!       * TAU      : relaxation time in SI
!       * TAU2     : second relaxation time in SI
!       * PCT      : weight of first function (0 < PCT <1)
!       * MEM_TYPE : type of memory function used
!                      MEM_TYPE  = 'NONE' --> no function
!                      MEM_TYPE  = 'DELT' --> delta function
!                      MEM_TYPE  = 'DGAU' --> double Gaussian functions
!                      MEM_TYPE  = 'EXPO' --> exponential function
!                      MEM_TYPE  = 'GAUS' --> Gaussian function
!                      MEM_TYPE  = 'LORE' --> Lorentzian function
!                      MEM_TYPE  = 'SINC' --> sinc function
!                      MEM_TYPE  = 'BES0' --> J_0(t) function
!                      MEM_TYPE  = 'BES1' --> J_1(t)/t function
!                      MEM_TYPE  = 'SEC2' --> sech^2(t) function
!                      MEM_TYPE  = 'COCO' --> Cole-Cole function
!                      MEM_TYPE  = 'CODA' --> Cole-Davidson function
!                      MEM_TYPE  = 'HANE' --> Habriliak-Negami function
!       * ALPHA    : value of the Habriliak-Negami first parameter  (in ]0,1])
!       * BETA     : value of the Habriliak-Negami second parameter (in ]0,1])
!
!
!  Remark: The memory function has the dimension of a frequency omega
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 26 Jan 2021
!
!
      USE REAL_NUMBERS,       ONLY : ZERO
!
      IMPLICIT NONE
!
      CHARACTER (LEN = 4)   ::  MEM_TYPE
!
      REAL (WP), INTENT(IN) ::  T,TAU,TAU2,PCT,ALPHA,BETA
      REAL (WP)             ::  MEMORY_T
!
      IF(MEM_TYPE == 'NONE') THEN                                   !
        MEMORY_T = ZERO                                             !
      ELSE IF(MEM_TYPE == 'DELT') THEN                              !
        MEMORY_T = DELTA_T(T,TAU)                                   !
      ELSE IF(MEM_TYPE == 'DGAU') THEN                              !
        MEMORY_T = DGAUS_T(T,TAU,TAU2,PCT)                          !
      ELSE IF(MEM_TYPE == 'EXPO') THEN                              !
        MEMORY_T = EXPON_T(T,TAU)                                   !
      ELSE IF(MEM_TYPE == 'GAUS') THEN                              !
        MEMORY_T = GAUSS_T(T,TAU)                                   !
      ELSE IF(MEM_TYPE == 'LORE') THEN                              !
        MEMORY_T = LOREN_T(T,TAU)                                   !
      ELSE IF(MEM_TYPE == 'SINC') THEN                              !
        MEMORY_T = SINCF_T(T,TAU)                                   !
      ELSE IF(MEM_TYPE == 'BES0') THEN                              !
        MEMORY_T = BES_0_T(T,TAU)                                   !
      ELSE IF(MEM_TYPE == 'BES1') THEN                              !
        MEMORY_T = BES_1_T(T,TAU)                                   !
      ELSE IF(MEM_TYPE == 'SEC2') THEN                              !
        MEMORY_T = SECH2_T(T,TAU)                                   !
      ELSE IF(MEM_TYPE == 'COCO') THEN                              !
        MEMORY_T = CO_CO_T(T,TAU,ALPHA)                             !
      ELSE IF(MEM_TYPE == 'CODA') THEN                              !
        MEMORY_T = CO_DA_T(T,TAU,BETA)                              !
      ELSE IF(MEM_TYPE == 'HANE') THEN                              !
!        MEMORY_T = HA_NE_T(T,TAU,ALPHA,BETA)                        !
      END IF                                                        !
!
      END FUNCTION MEMORY_T
!
!=======================================================================
!
      FUNCTION DELTA_T(T,TAU)
!
!  This function computes the time-dependent memory function
!     as a delta function
!
!
!  Input parameters:
!
!       * T        : time in SI
!       * TAU      : relaxation time in SI
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 20 Jan 2021
!
!
      USE BASIC_FUNCTIONS,    ONLY : DELTA
!
      IMPLICIT NONE
!
      INTEGER               ::  I_D
!
      REAL (WP), INTENT(IN) ::  T,TAU
      REAL (WP)             ::  DELTA_T
!
      REAL (WP)             ::  EPSI
!
!  Parameters of the numerical delta function
!
      EPSI = 1.0E-10_WP                                             !
      I_D  = 2                                                      !
!
      DELTA_T = DELTA(T,I_D,EPSI) / TAU                             !
!
      END FUNCTION DELTA_T
!
!=======================================================================
!
      FUNCTION DGAUS_T(T,TAU,TAU2,PCT)
!
!  This function computes the time-dependent memory function
!     as a sum of two Gaussian function1
!
!
!  Input parameters:
!
!       * T        : time in SI
!       * TAU      : relaxation time in SI
!       * TAU2     : second relaxation time in SI
!       * PCT      : weight of first function (0 < PCT <1)
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 30 A 2021
!
!
      USE REAL_NUMBERS,       ONLY : ONE,TWO
      USE PI_ETC,             ONLY : SQR_PI
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  T,TAU,TAU2,PCT
      REAL (WP)             ::  DGAUS_T
!
      REAL (WP)             ::  EXPO1,DEN1
      REAL (WP)             ::  EXPO2,DEN2
!
      REAL (WP)             ::  EXP
!
      EXPO1 = (T / TAU)**2                                          !
      DEN1  = TAU * TAU * SQR_PI                                    !
!
      EXPO2 = (T / TAU2)**2                                         !
      DEN2  = TAU2 * TAU2 * SQR_PI                                  !
!
      DGAUS_T = TWO * (                                           & !
                                PCT * EXP(- EXPO1) / DEN1 +       & !
                        (ONE - PCT) * EXP(- EXPO2) / DEN2         & !
                      )                                             !
!
      END FUNCTION DGAUS_T
!
!=======================================================================
!
      FUNCTION EXPON_T(T,TAU)
!
!  This function computes the time-dependent memory function
!     as an exponential function
!
!
!  Input parameters:
!
!       * T        : time in SI
!       * TAU      : relaxation time in SI
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 26 Jan 2021
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  T,TAU
      REAL (WP)             ::  EXPON_T
!
      REAL (WP)             ::  EXPO,DEN
!
      REAL (WP)             ::  EXP
!
      EXPO = T / TAU                                                !
      DEN  = TAU * TAU                                              !
!
      EXPON_T = EXP(- EXPO) / DEN                                   !
!
      END FUNCTION EXPON_T
!
!=======================================================================
!
      FUNCTION GAUSS_T(T,TAU)
!
!  This function computes the time-dependent memory function
!     as a Gaussian function
!
!
!  Input parameters:
!
!       * T        : time in SI
!       * TAU      : relaxation time in SI
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 27 Jan 2021
!
!
      USE REAL_NUMBERS,       ONLY : TWO
      USE PI_ETC,             ONLY : SQR_PI
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  T,TAU
      REAL (WP)             ::  GAUSS_T
!
      REAL (WP)             ::  EXPO,DEN
!
      REAL (WP)             ::  EXP
!
      EXPO = (T / TAU)**2                                           !
      DEN  = TAU * TAU * SQR_PI                                     !
!
      GAUSS_T = TWO * EXP(- EXPO) / DEN                             !
!
      END FUNCTION GAUSS_T
!
!=======================================================================
!
      FUNCTION LOREN_T(T,TAU)
!
!  This function computes the time-dependent memory function
!     as a Lorentzian function
!
!
!  Input parameters:
!
!       * T        : time in SI
!       * TAU      : relaxation time in SI
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 20 Jan 2021
!
!
      USE REAL_NUMBERS,       ONLY : ONE,TWO
      USE PI_ETC,             ONLY : PI
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  T,TAU
      REAL (WP)             ::  LOREN_T
!
      REAL (WP)             ::  EXPO,DEN
!
      EXPO = (T / TAU)**2                                           !
      DEN  = TAU * TAU * PI * (ONE + EXPO)                          !
!
      LOREN_T = TWO / DEN                                           !
!
      END FUNCTION LOREN_T
!
!=======================================================================
!
      FUNCTION SINCF_T(T,TAU)
!
!  This function computes the time-dependent memory function
!     as a sinc function
!
!
!  Input parameters:
!
!       * T        : time in SI
!       * TAU      : relaxation time in SI
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 28 Jan 2021
!
!
      USE REAL_NUMBERS,       ONLY : ZERO,TWO
      USE PI_ETC,             ONLY : PI
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  T,TAU
      REAL (WP)             ::  SINCF_T
!
      REAL (WP)             ::  EXPO,NUM,DEN
!
      REAL (WP)             ::  SIN
!
      EXPO = T / TAU                                                !
      NUM  = TWO * SIN(EXPO)                                        !
      DEN  = TAU * TAU * PI * EXPO                                  !
!
      IF(EXPO == ZERO) THEN                                         !
        SINCF_T = TWO / (TAU * TAU * PI)                            !
      ELSE                                                          !
        SINCF_T = NUM / DEN                                         !
      END IF                                                        !
!
      END FUNCTION SINCF_T
!
!=======================================================================
!
      FUNCTION BES_0_T(T,TAU)
!
!  This function computes the time-dependent memory function
!     as a J_0(t) function
!
!
!  Input parameters:
!
!       * T        : time in SI
!       * TAU      : relaxation time in SI
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 20 Jan 2021
!
!
      USE BESSEL,             ONLY :  BESSJ0
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  T,TAU
      REAL (WP)             ::  BES_0_T
!
      REAL (WP)             ::  EXPO,DEN
!
      EXPO = T / TAU                                                !
      DEN  = TAU * TAU                                              !
!
      BES_0_T = BESSJ0(EXPO) / DEN                                  !
!
      END FUNCTION BES_0_T
!
!=======================================================================
!
      FUNCTION BES_1_T(T,TAU)
!
!  This function computes the time-dependent memory function
!     as a J_1(t)/t function
!
!
!  Input parameters:
!
!       * T        : time in SI
!       * TAU      : relaxation time in SI
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 20 Jan 2021
!
!
      USE REAL_NUMBERS,       ONLY :  ZERO,ONE,TWO
      USE BESSEL,             ONLY :  BESSJ1
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  T,TAU
      REAL (WP)             ::  BES_1_T
!
      REAL (WP)             ::  EXPO,DEN
!
      EXPO = TWO * T / TAU                                          !
      DEN  = TAU * T                                                !
!
      IF(EXPO == ZERO) THEN                                         !
        BES_1_T = ONE / (TAU * TAU)                                 !
      ELSE                                                          !
        BES_1_T = BESSJ1(EXPO) / DEN                                !
      END IF                                                        !
!
      END FUNCTION BES_1_T
!
!=======================================================================
!
      FUNCTION SECH2_T(T,TAU)
!
!  This function computes the time-dependent memory function
!     as a sech^2(t) function
!
!
!  Input parameters:
!
!       * T        : time in SI
!       * TAU      : relaxation time in SI
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 20 Jan 2021
!
!
      USE REAL_NUMBERS,       ONLY : ONE
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  T,TAU
      REAL (WP)             ::  SECH2_T
!
      REAL (WP)             ::  EXPO,DEN
!
      EXPO = T / TAU                                                !
      DEN  = TAU * TAU * COSH(EXPO) * COSH(EXPO)                    !
!
      SECH2_T = ONE / DEN                                           !
!
      END FUNCTION SECH2_T
!
!=======================================================================
!
      FUNCTION CO_CO_T(T,TAU,ALPHA)
!
!  This function computes the time-dependent memory function
!     as a Cole-Cole function
!
!
!  References: (1) A. A. Khamzin, R. R. Nigmatullin, and I. I. Popov,
!                  Theor. Math. Phys. 173, 1604–1619 (2012)
!
!
!  Input parameters:
!
!       * T        : time in SI
!       * TAU      : relaxation time in SI
!       * ALPHA    : value of the Habriliak-Negami first parameter  (in ]0,1])
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 28 Jan 2021
!
!
      USE REAL_NUMBERS,       ONLY : ZERO,ONE,TWO,SMALL
      USE EXT_FUNCTIONS,      ONLY : DLGAMA
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  T,TAU,ALPHA
      REAL (WP)             ::  CO_CO_T
!
      REAL (WP)             ::  NUM,DEN
!
      REAL (WP)             ::  EXP
!
      IF(T == ZERO) THEN                                            !
        NUM  = ONE / SMALL                                          !
      ELSE                                                          !
        NUM  = (T / TAU)**(ALPHA - TWO)                             !
      END IF                                                        !
      DEN  = TAU**2 * EXP( DLGAMA(ALPHA - ONE) )                    !
!
      CO_CO_T = NUM / DEN                                           ! ref. (1) eq. (23)
!
      END FUNCTION CO_CO_T
!
!=======================================================================
!
      FUNCTION CO_DA_T(T,TAU,BETA)
!
!  This function computes the time-dependent memory function
!     as a Cole-Davidson function
!
!
!  References: (1) A. A. Khamzin, R. R. Nigmatullin, and I. I. Popov,
!                  Theor. Math. Phys. 173, 1604–1619 (2012)
!
!
!  Input parameters:
!
!       * T        : time in SI
!       * TAU      : relaxation time in SI
!       * BETA     : value of the Habriliak-Negami first parameter  (in ]0,1])
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 24 Feb 2021
!
!
      USE REAL_NUMBERS,       ONLY : ZERO,ONE,SMALL
!      USE EXT_FUNCTIONS,      ONLY : MLFV,MLFVDERIV
      USE MOD_MLF_GARRAPPA
!
      IMPLICIT NONE
!
      INTEGER               ::  P
!
      REAL (WP), INTENT(IN) ::  T,TAU,BETA
      REAL (WP)             ::  CO_DA_T
!
      REAL (WP)             ::  S,EXPO,COEF1,COEF2
      REAL (WP)             ::  NUM,DEN
!
      REAL (WP)             ::  EXP
!
      COMPLEX (WP)          ::  Z
!
      COMPLEX (WP)          ::  CMPLX
!
      P     = 6                                                     ! accuracy: 10^(-P)
!
      S     = T / TAU                                               !
      EXPO  = S**BETA                                               !
      Z     = CMPLX(EXPO)                                           !
      IF(T /= ZERO) THEN                                            !
        NUM  = EXP(- S) * EXPO / (S * S)                            !
      END IF                                                        !
      DEN   = TAU**2                                                !
      COEF1 = BETA - ONE - S                                        !
      COEF2 = BETA * EXPO                                           !
!
      IF(T == ZERO) THEN                                            !
        CO_DA_T = ONE / (SMALL * DEN)                               !
      ELSE                                                          !
!        CO_DA_T = NUM * ( COEF1 * REAL(MLFV(BETA,BETA,Z,P)) +     & !
!                          COEF2 * REAL(MLFVDERIV(BETA,BETA,Z,P)) )& !
!                      / DEN                                         !
        CO_DA_T = NUM * ( COEF1 * REAL(GENMLF(BETA,BETA,ONE,Z)) + & !
                          COEF2 * REAL(MLD_GARRAPPA(BETA,BETA,Z)) & !
                        ) / DEN                                     !
      END IF                                                        !
!
      END FUNCTION CO_DA_T
!
!=======================================================================
!
END MODULE MEMORY_FUNCTIONS_T
