!
!=======================================================================
!
MODULE PLASMON_DAMPING 
!
      USE ACCURACY_REAL
!
!
CONTAINS
!
!=======================================================================
!
      SUBROUTINE PLAS_DAMP_EG_3D(X,RS,T,TAU,PD_TYPE,PL_DISP,SQ_TYPE,  &
                                 GQ_TYPE,EC_TYPE,IQ_TYPE,GAMMA_Q)
!
! This subroutine computes the plasmon damping in the 3D case. 
!
!                    --->  electron gas case  <---
!
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * RS       : Wigner-Seitz radius (in units of a_0)
!       * T        : system temperature in SI
!       * TAU      : relaxation time (used for damping)  in SI
!       * PD_TYPE  : method used to compute the plasmon damping (3D)
!                       PD_TYPE = 'NONE'   --> no plasmon damping
!                       PD_TYPE = 'CALL'   --> Callen approximation
!                       PD_TYPE = 'DGKA'   --> DuBois-Gilinsky-Kivelson approximation
!                       PD_TYPE = 'FEWA'   --> Fetter and Walecka approximation
!                       PD_TYPE = 'JEWS'   --> Jewsbury approximation
!                       PD_TYPE = 'LITI'   --> Giuliani-Quinn lifetime approximation
!                       PD_TYPE = 'MOPE'   --> Molinari-Peerani approximation
!                       PD_TYPE = 'NPSA'   --> Ninham-Powel-Swanson approximation
!                       PD_TYPE = 'SGAA'   --> Segui-Gervasoni-Arista approximation
!       * PL_DISP  : method used to compute the dispersion (3D)
!       * SQ_TYPE  : structure factor approximation (3D)
!       * GQ_TYPE  : local-field correction type (3D)
!       * EC_TYPE  : type of correlation energy functional
!       * IQ_TYPE  : type of approximation for I(q)
!
!
!  Output variables :
!
!       * GAMMA_Q  : plasmon damping in SI
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 11 Jun 2020
!
!
      USE REAL_NUMBERS,     ONLY : ZERO
!
      IMPLICIT NONE
!
      CHARACTER (LEN = 7)   ::  PL_DISP
      CHARACTER (LEN = 6)   ::  EC_TYPE
      CHARACTER (LEN = 4)   ::  PD_TYPE,GQ_TYPE
      CHARACTER (LEN = 3)   ::  SQ_TYPE,IQ_TYPE
!
      REAL (WP)             ::  X,RS,T,TAU
      REAL (WP)             ::  GAMMA_Q
!
      IF(PD_TYPE == 'NONE') THEN                                    !
        GAMMA_Q = ZERO                                              !
      ELSE IF(PD_TYPE == 'CALL') THEN                               !
        GAMMA_Q = CALL_PD_3D(X,RS,T)                                !
      ELSE IF(PD_TYPE == 'DGKA') THEN                               !
        GAMMA_Q = DGKA_PD_3D(X,RS,T)                                !
      ELSE IF(PD_TYPE == 'FEWA') THEN                               !
        GAMMA_Q = FEWA_PD_3D(X,RS)                                  !
      ELSE IF(PD_TYPE == 'JEWS') THEN                               !
        GAMMA_Q = JEWS_PD_3D(X,RS)                                  !
      ELSE IF(PD_TYPE == 'LITI') THEN                               !
        GAMMA_Q = LITI_PD_3D(X,TAU)                                 !
      ELSE IF(PD_TYPE == 'MOPE') THEN                               !
        GAMMA_Q = MOPE_PD_3D(X,RS,T)                                !
      ELSE IF(PD_TYPE == 'NPSA') THEN                               !
        GAMMA_Q = NPSA_PD_3D(X,RS,T)                                !
      ELSE IF(PD_TYPE == 'SGAA') THEN                               !
        GAMMA_Q = SGAA_PD_3D(X,RS,T,PL_DISP,SQ_TYPE,GQ_TYPE,      & !
                             EC_TYPE,IQ_TYPE)                       !
      END IF                                                        !
!
      END SUBROUTINE PLAS_DAMP_EG_3D
!
!=======================================================================
!
      FUNCTION CALL_PD_3D(X,RS,T)
!
!  This function computes the plasmon damping gamma_q in the 
!    Callen approximation for the Landau damping
!    in a Maxwellian 3D plasma
!
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * RS       : Wigner-Seitz radius (in units of a_0)
!       * T        : system temperature in SI
!
!
!  Output variables :
!
!       * CALL_PD_3D  : plasmon damping (dimensionless)
!
!   References: (1) J. D. Callen, Physics of Plasmas 21, 052106 (2014)
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 11 Jun 2020
!
!
      USE REAL_NUMBERS,     ONLY : EIGHT,HALF
      USE CONSTANTS_P1,     ONLY : H_BAR
      USE FERMI_SI,         ONLY : KF_SI
      USE PI_ETC,           ONLY : SQR_PI
      USE SCREENING_VEC,    ONLY : DEBYE_VECTOR
      USE PLASMON_ENE_SI
!
      IMPLICIT NONE
!
      REAL (WP)             ::  X,RS,T,Y,U,U2,U3
      REAL (WP)             ::  CALL_PD_3D
      REAL (WP)             ::  KD_SI
      REAL (WP)             ::  NUM,DEN
!
      REAL (WP)             ::  SQRT,EXP
!
      Y = X + X                                                     ! q / k_F
!
      CALL DEBYE_VECTOR('3D',T,RS,KD_SI)                            !
!
      U  = KD_SI / (Y * KF_SI)                                      ! q /k_D
      U2 = U * U                                                    !
      U3 = U2 * U                                                   !
!
      NUM = ENE_P_SI * U3 * SQR_PI                                  !
      DEN = H_BAR * SQRT(EIGHT)                                     !
!
      CALL_PD_3D = NUM* EXP(- HALF * U2 - 1.5E0_WP) / DEN           ! ref. (1) eq. (9)
!
      END FUNCTION CALL_PD_3D
!
!=======================================================================
!
      FUNCTION DGKA_PD_3D(X,RS,T)
!
!  This function computes the plasmon Landau damping gamma_q in the 
!    DuBois-Gilinsky-Kivelson approximation 
!
!   References: 
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * RS       : Wigner-Seitz radius (in units of a_0)
!       * T        : system temperature in SI
!
!
!  Output variables :
!
!       * DGKA_PD_3D  : plasmon damping 
!
!   References: (1) D. F. DuBois, V. Gilinsky and M. G. Kivelson, 
!                      Phys. Rev. Lett. 8, 419 (1962)
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 11 Jun 2020
!
!
      USE REAL_NUMBERS,     ONLY : TWO,FOUR
      USE CONSTANTS_P1,     ONLY : H_BAR,M_E,K_B
      USE FERMI_SI,         ONLY : KF_SI
      USE PI_ETC,           ONLY : PI3
      USE SCREENING_VEC,    ONLY : DEBYE_VECTOR
      USE EULER_CONST,      ONLY : EUMAS
      USE UTILITIES_1,      ONLY : RS_TO_N0
      USE PLASMON_ENE_SI
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  X,RS,T
      REAL (WP)             ::  DGKA_PD_3D
      REAL (WP)             ::  Y,Q_SI,KT_SI,XX,YY
      REAL (WP)             ::  N0,KD_SI
      REAL (WP)             ::  NUM,DEN
!
      REAL (WP)             ::  SQRT,LOG,EXP
!
      Y = X + X                                                     ! q / k_F
!
      Q_SI = Y * KF_SI                                              ! q in SI
!
      N0 = RS_TO_N0('3D',RS)                                        !
!
      CALL DEBYE_VECTOR('3D',T,RS,KD_SI)                            !
!
      KT_SI = SQRT(M_E * K_B*T / (H_BAR * H_BAR))                   ! De Broglie thermal wave vector
      XX    = Q_SI / KD_SI                                          !
      YY    = KT_SI / KD_SI                                         !
!
      NUM = TWO * XX * XX * KD_SI * KD_SI * KD_SI                   !
      DEN = 15.0E0_WP * SQRT(PI3) * N0                              !
!
      DGKA_PD_3D = ENE_P_SI * NUM * LOG( FOUR * YY *EXP(- EUMAS) )& !
                                    / DEN                            ! ref. (1) eq. (2)
!
      END FUNCTION DGKA_PD_3D
!
!=======================================================================
!
      FUNCTION FEWA_PD_3D(X,RS)
!
!  This function computes the plasmon damping gamma_q in the 
!    Fetter and Walecka approximation
!
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * RS       : Wigner-Seitz radius (in units of a_0)
!
!
!  Output variables :
!
!       * FEWA_PD_3D  : plasmon damping (dimensionless)
!
!   References: (1) A. L. Fetter  and J. D. Walecka, 
!                      "Quantum Theory of Many-Particle Systems",
!                      McGraw-Hill, ex. 9.12 p. 324
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 11 Jun 2020
!
!
      USE REAL_NUMBERS,     ONLY : ONE
      USE FERMI_SI,         ONLY : EF_SI
      USE PI_ETC,           ONLY : PI3
      USE UTILITIES_1,      ONLY : ALFA
!
      IMPLICIT NONE
!
      REAL (WP)             ::  X,RS,Y
      REAL (WP)             ::  FEWA_PD_3D
      REAL (WP)             ::  ALPHA
!
      REAL (WP)             ::  SQRT
!
      Y     = X + X                                                 ! q / k_F
      ALPHA = ALFA('3D')                                            !
!
      FEWA_PD_3D = EF_SI * SQRT(ALPHA * RS * PI3) *               & !
                           (Y-ONE) * (Y-ONE)                        ! ref. (1) ex. (9.12)
!
      END FUNCTION FEWA_PD_3D
!
!=======================================================================
!
      FUNCTION JEWS_PD_3D(X,RS)
!
!  This function computes the plasmon damping gamma_q in the 
!    Jewsbury approximation
!
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * RS       : Wigner-Seitz radius (in units of a_0)
!
!
!  Output variables :
!
!       * JEWS_PD_3D  : plasmon damping (dimensionless)
!
!   References: (1) P. Jewsbury, Aust. J. Phys. 32, 361-368 (1979)
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 11 Jun 2020
!
!
      USE REAL_NUMBERS,     ONLY : HALF
!
      IMPLICIT NONE
!
      REAL (WP)             ::  X,RS,Y
      REAL (WP)             ::  JEWS_PD_3D
      REAL (WP)             ::  G0,G1
!
      REAL (WP)             ::  SQRT
!
      Y     = X + X                                                 ! q / k_F
!
      G0 = 0.033E0_WP * RS                                          ! ref. (1) eq. (25b)
      G1 = 0.15E0_WP * SQRT(RS)                                     ! ref. (1) eq. (25a)
! 
      JEWS_PD_3D = HALF * (G0 + G1 * Y * Y)                         ! ref. (1) eq. (24) 
!
      END FUNCTION JEWS_PD_3D
!
!=======================================================================
!
      FUNCTION LITI_PD_3D(X,TAU)
!
!  This function computes the plasmon damping gamma_q in the 
!    Giuliani-Quinn approximation
!
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * TAU      : relaxation time (used for damping)  in SI
!
!
!  Output variables :
!
!       * LITI_PD_3D  : plasmon damping (dimensionless)
!
!   References: (1) G. F. Giuliani and J. J. Quinn, Phys. Rev. B 29, 
!                      2321 (1984)
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 11 Jun 2020
!
!
      USE REAL_NUMBERS,     ONLY : ONE,TWO
!
      IMPLICIT NONE
!
      REAL (WP)             ::  X,TAU,Y
      REAL (WP)             ::  LITI_PD_3D
!
      Y     = X + X                                                 ! q / k_F
!
      LITI_PD_3D = (ONE + Y) / (TWO + Y) * ONE / TAU                ! ref. (1) eq. (2)
!
      END FUNCTION LITI_PD_3D
!
!=======================================================================
!
      FUNCTION MOPE_PD_3D(X,RS,T)
!
!  This function computes the plasmon damping gamma_q in the 
!    Molinari-Peerani approximation for the Landau damping
!    in a Maxwellian 3D plasma
!
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * RS       : Wigner-Seitz radius (in units of a_0)
!       * T        : system temperature in SI
!
!
!  Output variables :
!
!       * MOPE_PD_3D  : plasmon damping (dimensionless)
!
!   References: (1) V. G. Molinari and P. Peerani, 
!                      Il Nuovo Cimento D 5, 527 (1985)
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 11 Jun 2020
!
!
      USE REAL_NUMBERS,     ONLY : HALF
      USE CONSTANTS_P1,     ONLY : H_BAR,M_E,K_B
      USE FERMI_SI,         ONLY : KF_SI
      USE PI_ETC,           ONLY : SQR_PI
      USE PLASMON_ENE_SI
!
      IMPLICIT NONE
!
      REAL (WP)             ::  X,RS,T,Y,U,U2,U3
      REAL (WP)             ::  MOPE_PD_3D
      REAL (WP)             ::  Q_SI,BETA
      REAL (WP)             ::  NUM,DEN
!
      REAL (WP)             ::  SQRT,EXP
!
      Y     = X + X                                                 ! q / k_F
!
      Q_SI = Y  *KF_SI                                              ! q in SI
!
      BETA = HALF  *M_E / (K_B * T)                                 ! ref. (1), after eq. (10)
!
      U  = ENE_P_SI / (H_BAR * Q_SI)                                ! omega_p / q
      U2 = U * U                                                    !
      U3 = U2 * U                                                   !
!
      NUM = SQR_PI * SQRT(BETA * BETA * BETA) * ENE_P_SI * U3       !
      DEN = H_BAR                                                   !
!
      MOPE_PD_3D = NUM * EXP(- BETA * U2 - 1.5E0_WP) / DEN          ! ref. (1) between (24) and (25)
!
      END FUNCTION MOPE_PD_3D
!
!=======================================================================
!
      FUNCTION NPSA_PD_3D(X,RS,T)
!
!  This function computes the plasmon damping gamma_q in the 
!    Ninham-Powel-Swanson approximation 
!
!   References: 
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * RS       : Wigner-Seitz radius (in units of a_0)
!       * T        : system temperature in SI
!
!
!  Output variables :
!
!       * NPSA_PD_3D  : plasmon damping 
!
!   References: (1) B. W. Ninham, C. J. Powell and N. Swanson, 
!                      Phys. Rev. 145, 209 (1966)
!                   H. T. Nguyen-Truong, J. Phys. Chem. C 119, 
!                      7883-7887 (2015)
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 11 Jun 2020
!
!
      USE REAL_NUMBERS,     ONLY : ZERO,ONE,TWO,THREE,FOUR,FIVE
      USE FERMI_SI,         ONLY : EF_SI
      USE PI_ETC,           ONLY : PI
      USE UTILITIES_1,      ONLY : ALFA
      USE PLASMON_ENE_SI
!
      IMPLICIT NONE
!
      REAL (WP)             ::  X,RS,T,Q_C,Y
      REAL (WP)             ::  NPSA_PD_3D
      REAL (WP)             ::  GAMMA_Q,Y2,Y4,OM0
      REAL (WP)             ::  ALPHA
!
      REAL (WP)             ::  SQRT,LOG
!
      Y     = X + X                                                 ! q / k_F
!
!  plasmon cut-off in q
!
      ALPHA = ALFA('3D')                                            !
      Q_C   = ALPHA * SQRT(THREE / RS)                              ! ref. (1b) eq. (14)
!
      OM0 = ALPHA * ALPHA * SQRT(THREE * RS)                        ! ref. (1b) eq. (14)
!
      IF(Y <= Q_C) THEN                                             !
        Y2      = Y * Y                                             !
        Y4      = Y2 * Y2                                           !
        GAMMA_Q = PI * OM0 * OM0 * OM0 * (FIVE * LOG(TWO) + ONE) *& !
                  Y2 / 30.0E0_WP                      +           & !
                  PI * OM0 * ( 30.0E0_WP *LOG(TWO)    +           & ! 
                               37.0E0_WP / FOUR       -           & ! ref. (1b) eq. (14)
                               13.0E0_WP * OM0 * OM0  /           & !
                               16.0E0_WP                          & !
                             ) * Y4                                 ! dimensionless
!
        NPSA_PD_3D = GAMMA_Q * EF_SI                                ! in SI
      ELSE                                                          !
        NPSA_PD_3D = ZERO                                           !
      END IF                                                        !
!
      END FUNCTION NPSA_PD_3D
!
!=======================================================================
!
      FUNCTION SGAA_PD_3D(X,RS,T,PL_DISP,SQ_TYPE,GQ_TYPE,EC_TYPE,  &
                          IQ_TYPE)
!
!  This function computes the plasmon damping gamma_q in the 
!    Segui-Gervasoni-Arista approximation 
!
!   References: (1) S. Segui, J. L. Gervasoni and N. R. Arista, Nucl. Instr. 
!                      Meth. Phys. Res. B 408, 217-222 (2017)
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * RS       : Wigner-Seitz radius (in units of a_0)
!       * T        : system temperature in SI
!       * PL_DISP  : method used to compute the dispersion (3D)
!       * SQ_TYPE  : structure factor approximation (3D)
!       * GQ_TYPE  : local-field correction type (3D)
!       * EC_TYPE  : type of correlation energy functional
!       * IQ_TYPE  : type of approximation for I(q)
!
!
!  Output variables :
!
!       * SGAA_PD_3D  : plasmon damping 
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 11 Jun 2020
!
!
      USE REAL_NUMBERS,     ONLY : HALF
      USE CONSTANTS_P1,     ONLY : H_BAR,M_E,E
      USE FERMI_SI,         ONLY : KF_SI
      USE PLASMON_DISP_REAL
      USE PLASMON_ENE_SI
!
      IMPLICIT NONE
!
      CHARACTER (LEN = 7)   ::  PL_DISP
      CHARACTER (LEN = 6)   ::  EC_TYPE
      CHARACTER (LEN = 4)   ::  PD_TYPE,GQ_TYPE
      CHARACTER (LEN = 3)   ::  SQ_TYPE,IQ_TYPE
!
      REAL (WP), INTENT(IN) ::  X,RS,T
      REAL (WP)             ::  SGAA_PD_3D
      REAL (WP)             ::  Y,Q_SI
      REAL (WP)             ::  RQ_SI,ENE_P_Q,OM_Q,OM_QQ,K1_SI
      REAL (WP)             ::  NUM,DEN
!
      Y     = X + X                                                 ! q / k_F
!
      Q_SI = Y * KF_SI                                              !
!
!  Computing the plasmon dispersion
!
      CALL PLASMON_DISP_3D(X,RS,T,PL_DISP,ENE_P_Q)                  !
      OM_Q = ENE_P_Q / H_BAR                                        ! omega_q
! 
      OM_QQ = HALF * H_BAR * Q_SI * Q_SI / M_E                      !
!
      K1_SI = M_E * (OM_Q - OM_QQ) / (H_BAR * Q_SI)                 !
!
      NUM = M_E * E * E * ENE_P_SI * ENE_P_SI *                   & !
                 (KF_SI * KF_SI - K1_SI * K1_SI)                    ! ref. (1) eq. (17)
      DEN = H_BAR * H_BAR * H_BAR * H_BAR *                       & !
            Q_SI * Q_SI * Q_SI * OM_Q                               !
!
      SGAA_PD_3D = NUM / DEN                                        ! in SI
!
      END FUNCTION SGAA_PD_3D
!
!=======================================================================
!
      SUBROUTINE EXACT_DAMPING(IX,IDERIV,N_E,EN,EPSR,EPSI,EN_Q,GAMMA_Q)
!
!  This subroutine computes the plasmon damping gamma_q according to 
!
!                            Im[ epsilon ]    |
!        gamma_q    =    -   _______________  |
!                                             |
!                     d Re[ epsilon ]/d omega | omega=Omega_q
!
!     where epsilon is the dielectric function.
!
!
!  Input parameters:
!
!       * IX       : index of q-point     
!       * IDERIV   : type of n_point formula used for derivation (n = IDERIV)
!       * N_E      : number of energy points
!       * EN       : energy grid in units of E_F
!       * EPSR     : real part of the dielectric function at q
!       * EPSI     : imaginary part of the dielectric function at q
!       * EN_Q     : plasmon energy at q in units of E_F
!
!
!  Output parameters:
!
!       * GAMMA_Q  : plasmon damping coefficient in units of E_F
!
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 22 Oct 2020
!
!
      USE DIMENSION_CODE,      ONLY : NSIZE
      USE REAL_NUMBERS,        ONLY : ONE
      USE DERIVATION
      USE INTERPOLATION,       ONLY : INTERP_NR,SPLINE,SPLINT
      USE OUTFILES,            ONLY : FN
!
      IMPLICIT NONE
!
      INTEGER, INTENT(IN)   ::  IX,IDERIV,N_E
!
      REAL (WP), INTENT(IN) ::  EN(NSIZE)
      REAL (WP), INTENT(IN) ::  EPSR(NSIZE),EPSI(NSIZE)
      REAL (WP), INTENT(IN) ::  EN_Q
!
      REAL (WP), INTENT(OUT)::  GAMMA_Q 
!
      REAL (WP)             ::  H
      REAL (WP)             ::  DEPSR(NSIZE)
      REAL (WP)             ::  DEPSR_Q,EPSI_Q
!
      H        = EN(2) - EN(1)                                      ! step for energy derivation
!
!  Derivation of EPSR(N) using a n-point formula --> result in DEPSR(N)
!
      CALL DERIV_1(EPSR,N_E,IDERIV,H,DEPSR)                         !
!
!  Cubic spline interpolation of DEPSR(N) and EPSI(N) at E = EN_Q_ 
!
      CALL INTERP_NR(6,EN,DEPSR,N_E,EN_Q,DEPSR_Q)                   !
      CALL INTERP_NR(6,EN,EPSI,N_E,EN_Q,EPSI_Q)                     !
!
      GAMMA_Q = - EPSI_Q / DEPSR_Q                                  ! units of E_F
!
      END SUBROUTINE EXACT_DAMPING
!
END MODULE PLASMON_DAMPING 
