!=======================================================================
!
MODULE IMFP
!
      USE ACCURACY_REAL
!
CONTAINS
!
!
!=======================================================================
!
      SUBROUTINE MEAN_FREE_PATH(EK,MFP)
!
!  This subroutine computes the electron inelastic mean free path
!
!
!  Reference: (1)   D. R. Penn, Phys. Rev. B 13, 5248-5254 (1976)
!             (2)   B. Da, H. Shinotsuka, H. Yoshikawa, Z.J. Ding and
!                   S. Tanuma, Phys. Rev. Lett. 113, 063201 (2014)
!
!
!  Input parameters:
!
!       * EK       : electron kinetic energy (in SI)
!
!
!  Output variables :
!
!       * IMPF     : inelastic mean free path (in SI)
!
!
!   Note: eps(q,omega) is in fact stored as a function of Y = q / k_F
!         and V = hbar omega / E_F
!
!         Therefore, in order to be consistent, the integrations have
!         to be performed in Y and V
!
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 30 Apr 2021
!
!
      USE DIMENSION_CODE,      ONLY : NSIZE
      USE MATERIAL_PROP,       ONLY : RS
      USE EXT_FIELDS,          ONLY : T
!
      USE Q_GRID,              ONLY : Q_MIN
      USE E_GRID,              ONLY : E_MIN
!
      USE REAL_NUMBERS,        ONLY : ZERO,ONE,TWO,HALF,FOURTH,SMALL,TTINY,INF
      USE PI_ETC,              ONLY : PI
      USE FERMI_SI,            ONLY : EF_SI,KF_SI
      USE CONSTANTS_P1,        ONLY : BOHR,H_BAR,M_E
      USE ENE_CHANGE,          ONLY : EV
!
      USE DF_VALUES,           ONLY : D_FUNC
!
      USE INTEGRATION,         ONLY : INTEGR_L
      USE INTEGRATION4
      USE DFUNCL_STAN_DYNAMIC
!
      IMPLICIT NONE
!
      INTEGER               ::  IQ,IE
      INTEGER               ::  ID
      INTEGER               ::  I_ZQ,I_ZE
!
      INTEGER, PARAMETER    ::  NE_MAX = 2000    ! max. number of points in e-grid
      INTEGER, PARAMETER    ::  NQ_MAX = 1000    ! max. number of points in q-grid
!
      REAL (WP), INTENT(IN) ::  EK
      REAL (WP), INTENT(OUT)::  MFP
      REAL (WP)             ::  MIN_E,MAX_E,MIN_Q,MAX_Q
      REAL (WP)             ::  STEP_E,STEP_Q
      REAL (WP)             ::  E,Q
      REAL (WP)             ::  X,V,Z,EKF,KOEF
      REAL (WP)             ::  EPSR,EPSI
      REAL (WP)             ::  ELF(NSIZE),IN(NSIZE)
      REAL (WP)             ::  A,B
!
      REAL (WP)             ::  FLOAT,SQRT
!
      EKF  = EK / EF_SI                                             ! in units of E_F
!
      KOEF = EKF * PI * BOHR / RS                                   !
!
      MIN_E  = E_MIN                                                ! in units of E_F
      MAX_E  = EKF - ONE                                            ! in units of E_F
      STEP_E = (MAX_E - MIN_E) / FLOAT(NE_MAX - 1)                  ! in units of E_F
!
!  Constructing the e-grid
!
      DO IE = 1, NE_MAX                                             ! E_F
!
        E = MIN_E + FLOAT(IE - 1) * STEP_E                          ! in units of
        V = E                                                       ! hbar * omega / E_F
!
!  Constructing the q-grid
!
        MIN_Q  = MAX( Q_MIN, SQRT(EKF) - SQRT(EKF - V) )            ! for Z to be defined
        MAX_Q  = SQRT(EKF) + SQRT(EKF - V)                          ! in units of k_F
        STEP_Q = (MAX_Q - MIN_Q) / FLOAT(NQ_MAX - 1)                ! in units of k_F
!
        I_ZQ = 0                                                    ! switch for integrand = 0
!
        DO IQ = 1, NQ_MAX                                           !
!
          Q = MIN_Q + FLOAT(IQ - 1) * STEP_Q                        ! in units of k_F
!
          X = HALF * Q                                              ! (q / 2k_F)
          Z = FOURTH * V / (X * X)                                  ! omega / omega_q
!
!  Computing the dielectric function epsilon(q,E)
!
          CALL DFUNCL_DYNAMIC(X,Z,RS,T,D_FUNC,IE,EPSR,EPSI)         !
!
!  Computing the loss function ELF = Im [ -1 / epsilon(q,E) ]
!
          ELF(IQ) = EPSI / ( (EPSR * EPSR + EPSI * EPSI) * Q)       ! integrand function
!
!          IF(ELF(IQ) /= ZERO) I_ZQ = IQ                             !
          IF(ELF(IQ) == ZERO)  ELF(IQ) = SMALL                           !
!
        END DO                                                      ! end of q-grid
!
!        IF(I_ZQ > 0) THEN                                           !
!
!  Performing the q-integration
!
          ID = 1                                                    ! EPSI = 0 at origin
          CALL INTEGR_L(ELF,STEP_Q,NSIZE,NQ_MAX,A,ID)               !
!
!        ELSE                                                        ! ELF always = 0
!
!          A = TTINY                                                 !
!
!        END IF                                                      !
!
!  Constructing the e-integrand
!
        IN(IE) = A                                                  !
!
!        IF(A /= ZERO) I_ZE = IE                                     !
        IF(IN(IE) == ZERO)  IN(IE) = SMALL                           !
!
      END DO                                                        ! end of e-grid
!
!      IF(I_ZE > 0) THEN                                             !
!
!  Performing the e-integration
!
        ID = 1                                                      !
        CALL INTEGR_L(IN,STEP_E,NSIZE,NE_MAX,B,ID)                  !
!
!      ELSE                                                          ! IN always = 0
!
!        B = TTINY                                                   !
!
!      END IF                                                        !
!
      MFP =  KOEF / B                                               ! ref. (2) eq. (2)
!
      END SUBROUTINE MEAN_FREE_PATH
!
END MODULE IMFP
