!
!=======================================================================
!
MODULE IQ_FUNCTIONS_2
!
!  This modules provides subroutines/functions to compute
!            static local-field factors I(q) = G(q,inf)
!
!  These I(q) DEPEND of the static structure factor S(q) 
!    through the function J(q):
!
!                                _                    _
!              h_bar omega_q    |                      |     3        m pi
!  I(q) = 4 ------------------- | < E_kin>  - < E_kin> | - --------- ------ J(q)
!            (h_bar omega_p)^2  |_        0           _|    4 k_F^3    e^2
!
!
!                                   d(r_s E_c)
!  Note:  < E_kin>  - < E_kin>  =  -----------
!                0                    d r_s
!
      USE ACCURACY_REAL
!
CONTAINS
!
!=======================================================================
!
      SUBROUTINE IQ_3D_2(X,RS,T,IQ) 
!
!  This function computes the function I(q) = G(q,infinity) 
!    for 3D systems
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * RS       : Wigner-Seitz radius (in units of a_0)
!       * T        : temperature in SI
!       * IQ_TYPE  : type of approximation for I(q)
!                       IQ_TYPE  = 'GKM' Gorobchenko-Kohn-Maksimov
!                       IQ_TYPE  = 'HKA' Hong-Kim
!                       IQ_TYPE  = 'KU2' Kugler
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified :   5 Oct 2020
!
!
      USE REAL_NUMBERS,             ONLY : TWO,THREE,FOUR,HALF
      USE CONSTANTS_P1,             ONLY : H_BAR,M_E,E
      USE FERMI_SI,                 ONLY : KF_SI    
      USE PI_ETC,                   ONLY : PI
      USE ENERGIES,                 ONLY : EC_TYPE
      USE CORRELATION_ENERGIES
      USE PLASMON_ENE_SI
!
      IMPLICIT NONE
!
      CHARACTER (LEN = 3)   ::  IQ_TYPE
!
      REAL (WP), INTENT(IN) ::  X,RS,T
      REAL (WP)             ::  IQ
      REAL (WP)             ::  JQ
      REAL (WP)             ::  Q_SI,E_Q,D_KIN
      REAL (WP)             ::  EC,D_EC_1,D_EC_2
      REAL (WP)             ::  COEF1,COEF2
      REAL (WP)             ::  KF3,E2
!
      Q_SI  = TWO * KF_SI * X                                       !
      E_Q   = HALF * H_BAR * H_BAR * Q_SI * Q_SI / M_E              !
!
      KF3 = KF_SI * KF_SI * KF_SI                                   !
      E2  = E * E                                                   !
!
!  Computing the correlation energy and its derivatives
!
      EC = EC_3D(EC_TYPE,1,RS,T)                                    !
      CALL DERIVE_EC_3D(EC_TYPE,1,5,RS,T,D_EC_1,D_EC_2)             !
!
      D_KIN = EC + RS * D_EC_1                                      !
!
      IF(IQ_TYPE == 'HKA') THEN                                     !
        JQ = JQ_HKA_3D(X,RS,T)                                      !
      ELSE IF(IQ_TYPE == 'GKM') THEN                                !                                
        JQ = JQ_GKM_3D(X,RS,T)                                      !
      ELSE IF(IQ_TYPE == 'KU2') THEN                                !                                
        JQ = JQ_KU2_3D(X,RS,T)                                      !
      END IF                                                        !
!
      COEF1 = FOUR * E_Q / (ENE_P_SI * ENE_P_SI)                    !
      COEF2 = THREE * M_E * PI / (FOUR * KF3 * E2)                  !
!
      IQ = COEF1 * D_KIN - COEF2 * JQ                               !
!
      END SUBROUTINE IQ_3D_2 
!
!=======================================================================
!
      FUNCTION JQ_HKA_3D(X,RS,T)
!
!  This function computes the Hong-Kim J(q) function
!
!  Reference: J. Hong and C. Kim, Phys. Rev. 43, 1965-1971 (1991)
!
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * RS       : Wigner-Seitz radius (in units of a_0)
!       * T        : temperature in SI
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified :  20 Sep 2020
!
!
!
      USE DIMENSION_CODE,           ONLY : NZ_MAX
      USE REAL_NUMBERS,             ONLY : ZERO,ONE,FOUR,FIVE,SIX, &
                                           HALF,THIRD
      USE PI_ETC,                   ONLY : PI_INV
      USE SF_VALUES,                ONLY : SQ_TYPE
      USE INTEGRATION,              ONLY : INTEGR_L
      USE STRUCTURE_FACTOR_STATIC,  ONLY : STFACT_STATIC
!
      IMPLICIT NONE
!
      INTEGER               ::  IP
      INTEGER, PARAMETER    ::  N_I = 100      ! number of integration points
      INTEGER               ::  ID
!
      REAL (WP), INTENT(IN) ::  X,RS,T
      REAL (WP)             ::  JQ_HKA_3D
      REAL (WP)             ::  INTG(NZ_MAX)
      REAL (WP)             ::  I_STEP
      REAL (WP)             ::  K,P,K2,P2
      REAL (WP)             ::  PPK,PMK
      REAL (WP)             ::  SQ
      REAL (WP)             ::  INTGR
!
      REAL (WP)             ::  FLOAT,LOG,ABS
!
      REAL (WP), PARAMETER  ::  UP = SIX       ! upper bound for integration
!
      ID = 1                                                        !
!
      K  = X + X                                                    ! q / k_F
      K2 = K * K                                                    ! 
!
!  Initialization of integrand
!
      DO IP = 1, NZ_MAX                                             !
        INTG(IP) = ZERO                                             !
      END DO                                                        !
!
      I_STEP = UP / FLOAT(N_I -1)                                   ! integration step
!
!  Calculation of integrand
!
      DO IP = 1, N_I                                                !
!
        P  = FLOAT(IP - 1) * I_STEP                                 !
        P2 = P * P                                                  !
!
        PPK = P + K                                                 !
        PMK = P - K                                                 !
!
        CALL STFACT_STATIC(X,RS,T,SQ_TYPE,SQ)                       !
!
        INTG(IP) = P2 * (ONE - SQ) * (                            & !
                        FIVE / SIX - HALF * P2 /  K2 +            & !
                        (PMK * PPK)**2 * LOG(ABS(PPK / PMK)) /    & !  ref. (1) eq. (26)
                        (FOUR * P * K * K2)                       & !
                                     )                              !
!
      END DO                                                        !
!
!  Computing the integral
!
      CALL INTEGR_L(INTG,I_STEP,NZ_MAX,N_I,INTGR,ID)                !
!
      JQ_HKA_3D = THIRD * PI_INV * INTGR                            !  ref. (1) eq. (26)
!
      END FUNCTION JQ_HKA_3D
!
!=======================================================================
!
      FUNCTION JQ_GKM_3D(X,RS,T)
!
!  This function computes the Gorobchenko-Kohn-Maksimov J(q) function
!
!
!  Reference : V. D. Gorobchenko, V. N. Kohn and E. G. Maksimov, 
!                 in "The Dielectric Function of Condensed Systems", 
!                 ed. by L. V. Keldysh, D. A. Kirzhnitz and 
!                 A. A. Maradudin (Elsevier, 1989), pp. 87-219
!
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * RS       : Wigner-Seitz radius (in units of a_0)
!       * T        : temperature in SI
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified :  19 Sep 2020
!
!
!
      USE DIMENSION_CODE,           ONLY : NZ_MAX
      USE REAL_NUMBERS,             ONLY : ZERO,ONE,THREE,FOUR,FIVE,SIX,EIGHT
      USE SF_VALUES,                ONLY : SQ_TYPE
      USE INTEGRATION,              ONLY : INTEGR_L
      USE STRUCTURE_FACTOR_STATIC,  ONLY : STFACT_STATIC
!
      IMPLICIT NONE
!
      INTEGER               ::  IP
      INTEGER, PARAMETER    ::  N_I = 100      ! number of integration points
      INTEGER               ::  ID
!
      REAL (WP), INTENT(IN) ::  X,RS,T
      REAL (WP)             ::  JQ_GKM_3D
      REAL (WP)             ::  INTG(NZ_MAX)
      REAL (WP)             ::  I_STEP
      REAL (WP)             ::  K,P,K2,P2
      REAL (WP)             ::  PPK,PMK
      REAL (WP)             ::  SQ
      REAL (WP)             ::  INTGR
      REAL (WP)             ::  KF3
!
      REAL (WP)             ::  FLOAT,LOG,ABS
!
      REAL (WP), PARAMETER  ::  UP = SIX       ! upper bound for integration
!
      ID = 1                                                        !
!
      KF3 = ONE                                                     !
!
      K  = X + X                                                    ! q / k_F
      K2 = K * K                                                    ! 
!
!  Initialization of integrand
!
      DO IP = 1, NZ_MAX                                             !
        INTG(IP) = ZERO                                             !
      END DO                                                        !
!
      I_STEP = UP / FLOAT(N_I -1)                                   ! integration step
!
!  Calculation of integrand
!
      DO IP = 1, N_I                                                !
!
        P  = FLOAT(IP - 1) * I_STEP                                 !
        P2 = P * P                                                  !
!
        PPK = P + K                                                 !
        PMK = P - K                                                 !
!
        CALL STFACT_STATIC(X,RS,T,SQ_TYPE,SQ)                       !
!
        INTG(IP) = P2 * (ONE - SQ) * (                            & !
                      FIVE / EIGHT - THREE * P2 /  (EIGHT * K2) + & !
                      THREE* PMK * PPK * LOG(ABS(PPK / PMK)) /    & !  ref. (1) eq. (2.75)
                      (FOUR * FOUR * P * K * K2)                  & !
                                     )                              !
!
      END DO                                                        !
!
!  Computing the integral
!
      CALL INTEGR_L(INTG,I_STEP,NZ_MAX,N_I,INTGR,ID)                !
!
      JQ_GKM_3D = INTGR / KF3                                       !
!
      END FUNCTION JQ_GKM_3D
!
!=======================================================================
!
      FUNCTION JQ_KU2_3D(X,RS,T)
!
!  This function computes the Kugler J(q) function
!
!  Reference: (1) A. A. Kugler, Phys. Rev. A 1, 1688-1696 (1970)
!             (2) A. A. Kugler, J. Stat. Phys. 12, 35-87  (1975)
!
!  Note: A misprint in the expression of J(q,k) in ref. (1) 
!        has been corrected in ref. (2)
!
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * RS       : Wigner-Seitz radius (in units of a_0)
!       * T        : temperature in SI
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified :  19 Sep 2020
!
!
!
      USE DIMENSION_CODE,           ONLY : NZ_MAX
      USE REAL_NUMBERS,             ONLY : ZERO,ONE,FOUR,FIVE,SIX, &
                                           HALF
      USE PI_ETC,                   ONLY : PI_INV
      USE CONSTANTS_P1,             ONLY : M_E,E
      USE SF_VALUES,                ONLY : SQ_TYPE
      USE INTEGRATION,              ONLY : INTEGR_L
      USE STRUCTURE_FACTOR_STATIC,  ONLY : STFACT_STATIC
!
      IMPLICIT NONE
!
      INTEGER               ::  IP
      INTEGER, PARAMETER    ::  N_I = 100      ! number of integration points
      INTEGER               ::  ID
!
      REAL (WP), INTENT(IN) ::  X,RS,T
      REAL (WP)             ::  JQ_KU2_3D
      REAL (WP)             ::  INTG(NZ_MAX)
      REAL (WP)             ::  I_STEP
      REAL (WP)             ::  K,P,K2,P2,R,R2
      REAL (WP)             ::  PPK,PMK
      REAL (WP)             ::  SQ
      REAL (WP)             ::  INTGR
!
      REAL (WP)             ::  FLOAT,LOG,ABS
!
      REAL (WP), PARAMETER  ::  UP = SIX       ! upper bound for integration
!
      ID = 1                                                        !
!
      K  = X + X                                                    ! q / k_F
      K2 = K * K                                                    ! 
!
!  Initialization of integrand
!
      DO IP = 1, NZ_MAX                                             !
        INTG(IP) = ZERO                                             !
      END DO                                                        !
!
      I_STEP = UP / FLOAT(N_I -1)                                   ! integration step
!
!  Calculation of integrand
!
      DO IP = 1, N_I                                                !
!
        P  = FLOAT(IP - 1) * I_STEP                                 !
        P2 = P * P                                                  !
        R  = P  / K                                                 !
        R2 = P2 / K2                                                !
!
        PPK = P + K                                                 !
        PMK = P - K                                                 !
!
        CALL STFACT_STATIC(X,RS,T,SQ_TYPE,SQ)                       !
!
        INTG(IP) = P2 * (SQ - ONE) * (                            & !
                        FIVE / SIX - HALF * R2 +                  & !  ref. (1) eq. (5.6)
                        (R2 - ONE)**2 * LOG(ABS(PPK / PMK)) /     & !  corrected by ref. (2)
                        (FOUR * R)                                & !
                                     )                              !
!
      END DO                                                        !
!
!  Computing the integral
!
      CALL INTEGR_L(INTG,I_STEP,NZ_MAX,N_I,INTGR,ID)                !
!
      JQ_KU2_3D = E * E * PI_INV * INTGR  / M_E                     !  ref. (1) eq. (5.5)
!
      END FUNCTION JQ_KU2_3D
!
END MODULE IQ_FUNCTIONS_2
