!
!=======================================================================
!
MODULE UTILITIES_3 
!
      USE ACCURACY_REAL
!
!  It contains the following functions/subroutines:
!
!             * SUBROUTINE EPS_TO_CHI(EPSR,EPSI,VC,CHIR,CHII)
!             * SUBROUTINE EPS_TO_PI(EPSR,EPSI,VC,PIR,PII)
!             * SUBROUTINE EPS_TO_SIGMA(X,Z,EPSR,EPSI,SIGMAR,SIGMAI)
!             * SUBROUTINE EPS_TO_SQO(X,Z,T,RS,DMN,EPSR,EPSI,VC,SQO)
!             * FUNCTION LOSS_TO_SF(X,Z,T,LOSS)
!             * FUNCTION SF_TO_LOSS(X,Z,T,SQO)
!             * SUBROUTINE SQO_TO_EPSI(X,Z,T,RS,DMN,VC,SQO,EPSI)
!
!
CONTAINS
!
!
!=======================================================================
!
      SUBROUTINE EPS_TO_CHI(EPSR,EPSI,VC,CHIR,CHII)
!
!  This subroutine computes the dielectric susceptibility, also called 
!    the density-density response function, from the knowledge 
!    of the dielectric function, following the formula
!
!                                1
!     EPS(q,omega) = ----------------------------
!                      1 + Vc(q) * CHI(q,omega)
!
!
!
!  Input parameters:
!
!       * EPSR     : real part of dielectric function
!       * EPSI     : imaginary part of dielectric function
!       * VC       : Coulomb potential in k-space
!
!
!  Output variables :
!
!       * CHIR     : real part of dielectric susceptibility
!       * CHII     : imaginary part of dielectric susceptibility
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified :  4 Jun 2020
!
!
      USE REAL_NUMBERS,    ONLY : ONE
      USE COMPLEX_NUMBERS, ONLY : IC
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN)  :: EPSR,EPSI,VC
      REAL (WP), INTENT(OUT) :: CHIR,CHII
!
      REAL (WP)              :: REAL,AIMAG
!
      COMPLEX (WP)           :: EPS,CHI
!
      EPS = EPSR + IC * EPSI                                        !
!
      CHI = (ONE / EPS - ONE) / VC                                  !
!
      CHIR = REAL(CHI,KIND=WP)                                      !
      CHII = AIMAG(CHI)                                             !
!
      END SUBROUTINE EPS_TO_CHI  
!
!=======================================================================
!
      SUBROUTINE EPS_TO_PI(EPSR,EPSI,VC,PIR,PII)
!
!  This subroutine computes irreducible polarizability, 
!    following the formula
!
!       EPS(q,omega) = 1 - Vc(q) * PI(q,omega)
!
!
!
!  Input parameters:
!
!       * EPSR     : real part of dielectric function
!       * EPSI     : imaginary part of dielectric function
!       * VC       : Coulomb potential in k-space
!
!
!  Output variables :
!
!       * PIR      : real part of irreducible polarizability
!       * PII      : imaginary part of irreducible polarizability
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified :  4 Jun 2020
!
      USE REAL_NUMBERS,    ONLY : ONE
      USE COMPLEX_NUMBERS, ONLY : IC
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN)  :: EPSR,EPSI,VC
      REAL (WP), INTENT(OUT) :: PIR,PII
!
      REAL (WP)              :: REAL,AIMAG
!
      COMPLEX (WP)           :: EPS,PPI
!
      EPS = EPSR + IC * EPSI                                        !
      PPI = (EPS - ONE) / VC                                        !
!
      PIR = REAL(PPI,KIND=WP)                                       !
      PII = AIMAG(PPI)                                              !
!
      END SUBROUTINE EPS_TO_PI
!
!=======================================================================
!
      SUBROUTINE EPS_TO_SIGMA(X,Z,EPSR,EPSI,SIGMAR,SIGMAI)
!
!  This subroutine computes conductivity, 
!    following the formula
!
!                                 i
!       EPS(q,omega) = 1 + ---------------  *  SIGMA(q,omega)
!                           omega * EPS_0
!
!
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * Z        : omega / omega_q        --> dimensionless
!       * EPSR     : real part of dielectric function
!       * EPSI     : imaginary part of dielectric function
!
!
!  Output variables :
!
!       * SIGMAR   : real part of conductivity
!       * SIGMAI   : imaginary part of conductivity
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 23 Oct 2020
!
      USE REAL_NUMBERS,     ONLY : ONE,HALF
      USE COMPLEX_NUMBERS,  ONLY : IC
      USE CONSTANTS_P1,     ONLY : EPS_0
      USE FERMI_SI,         ONLY : KF_SI,VF_SI
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN)  :: X,Z,EPSR,EPSI
      REAL (WP), INTENT(OUT) :: SIGMAR,SIGMAI
!
      REAL (WP)              :: Y,U
      REAL (WP)              :: Q_SI,OMEGA
!
      REAL (WP)              :: REAL,AIMAG
!
      COMPLEX (WP)           :: EPS,SIGMA
!
      Y  = X + X                                                    ! Y = q / k_F 
      U  = X * Z                                                    ! U = omega / (q v_F)
!
      Q_SI = Y * KF_SI                                              ! q in SI
!  
      OMEGA = Q_SI * VF_SI * U                                      ! omega in SI
!
      EPS = EPSR + IC * EPSI                                        !
!
      SIGMA = (ONE - EPS) * IC * OMEGA * EPS_0                      !
!
      SIGMAR = REAL(SIGMA,KIND=WP)                                  !
      SIGMAI = AIMAG(SIGMA)                                         !
!
      END SUBROUTINE EPS_TO_SIGMA
!
!=======================================================================
!
      SUBROUTINE EPS_TO_SQO(X,Z,T,RS,DMN,EPSR,EPSI,VC,SQO)
!
!  This subroutine computes dynamic structure factor, 
!    following the formula
!                                                                  _      _
!                2*h_bar                    1                     |    1   |
!  S(q,omega) = --------- *  -------------------------------  * Im| - ---  |
!                n*Vc(q)      1 - exp(-h_bar*omega / k_B*T)       |_  eps _|
!
!
!
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * Z        : omega / omega_q        --> dimensionless
!       * T        : temperature in SI
!       * RS       : Wigner-Seitz radius (in units of a_0)
!       * DMN      : problem dimension
!       * EPSR     : real part of dielectric function
!       * EPSI     : imaginary part of dielectric function
!       * VC       : Coulomb potential in k-space
!
!
!  Output variables :
!
!       * SQO      : dynamic structure factor
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 21 Dec 2020
!
!
      USE REAL_NUMBERS,     ONLY : ZERO,ONE,TWO,HALF
      USE COMPLEX_NUMBERS,  ONLY : IC
      USE CONSTANTS_P1,     ONLY : H_BAR,K_B
      USE FERMI_SI,         ONLY : KF_SI,VF_SI
      USE UTILITIES_1,      ONLY : RS_TO_N0
      USE MINMAX_VALUES
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN)  ::  X,Z,T,RS
      REAL (WP), INTENT(IN)  ::  EPSR,EPSI,VC
      REAL (WP), INTENT(OUT) ::  SQO
!
      REAL (WP)              ::  MAX_EXP,MIN_EXP
      REAL (WP)              ::  Y,U
      REAL (WP)              ::  Q_SI,OMEGA,EX,KOEF
      REAL (WP)              ::  IMG,EXPO
      REAL (WP)              ::  N0
!
      REAL (WP)              ::  EXP 
!
      CHARACTER (LEN = 2)    ::  DMN
!
!  Computing the max and min value of the exponent of e^x
!
      CALL MINMAX_EXP(MAX_EXP,MIN_EXP)                              !
!
      Y = X + X                                                     ! Y = q / k_F 
      U = X * Z                                                     ! U = omega / (q v_F)
!
      Q_SI = Y * KF_SI                                              ! q in SI
!  
      OMEGA = Q_SI * VF_SI * U                                      ! omega in SI
!               _      _
!              |    1   |
!  Computing Im| - ---  |
!              |_  eps _|
!
      IMG = EPSI / (EPSR * EPSR + EPSI * EPSI)                      !
!
!  Computing the electron density from the Wigner-Seitz radius
!
      N0 = RS_TO_N0(DMN,RS)                                         !
!
      EX = - H_BAR * OMEGA / (K_B * T)                              ! 
!
!  Checking if exp(- ex) can be represented
!
      IF(EX > MIN_EXP) THEN                                         !
        EXPO = EXP(EX)                                              !
      ELSE                                                          !
        EXPO = ZERO                                                 !
      END IF                                                        !
!
      KOEF = TWO * H_BAR / (N0 * VC)                                ! coef. of formula
!
      SQO = KOEF * ONE / (ONE - EXPO) *  IMG                        !
!
      END SUBROUTINE EPS_TO_SQO
!
!=======================================================================
!
      FUNCTION LOSS_TO_SF(X,Z,T,LOSS)
!
!  This function transforms a loss function L(q,omega) into a 
!    structure factor S(q,omega)

!  Note: It makes use of the fluctuation-dissipation theorem 
!        to obtain
!
!    S(q,omega) = (k_B T / Pi V_C) * B(h_bar omega / k_B T) * L(q,omega)
!
!    where B(x) is the Bose factor : B(x) = x / ( 1 - exp(-x) )
!
!
!  References: (1) Yu. V. Arkhipov et al, Contrib. Plasma Phys. 
!                      55, 381-389 (2015)
!
!
!           -->   Warning: 3D only at present  <--
!
!
!  Input parameters: 
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * Z        : omega / omega_q        --> dimensionless
!       * T        : temperature in SI
!       * LOSS     : value of the loss function
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified :  4 Jun 2020
!
!
      USE MATERIAL_PROP,    ONLY : DMN,RS
      USE SCREENING_TYPE
!
      USE REAL_NUMBERS,     ONLY : ONE,HALF
      USE CONSTANTS_P1,     ONLY : H_BAR,K_B
      USE FERMI_SI,         ONLY : KF_SI,VF_SI
      USE PI_ETC,           ONLY : PI_INV
!
      USE SCREENING_VEC
      USE COULOMB_K
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  X,Z,T,LOSS
      REAL (WP)             ::  LOSS_TO_SF
      REAL (WP)             ::  Y,U
      REAL (WP)             ::  KBT,XX,BOSE,COEF
      REAL (WP)             ::  Q_SI,OMEGA
      REAL (WP)             ::  KS_SI,VC
!
      REAL (WP)              ::  EXP 
!
      Y = X + X                                                     ! Y = q / k_F 
      U = X * Z                                                     ! U = omega / (q v_F)
!
      Q_SI = Y * KF_SI                                              ! q in SI
!  
      OMEGA = Q_SI * VF_SI * U                                      ! omega in SI
!
      KBT = K_B * T                                                 ! 
!
!  Computing the screening vector
!
      CALL SCREENING_VECTOR(SC_TYPE,DMN,X,RS,T,KS_SI)
!
!  Computation of the Coulomb potential
!
      CALL COULOMB_FF(DMN,'SIU',Q_SI,KS_SI,VC)                      !
!
!  Computation of the Bose factor
!
      XX   = H_BAR * OMEGA / KBT                                    ! 
      BOSE = XX / (ONE - EXP(- XX))                                 !
!
      COEF = PI_INV / (KBT * VC)                                    !
!
      LOSS_TO_SF = COEF * BOSE * LOSS                               !
!
      END FUNCTION LOSS_TO_SF  
!
!=======================================================================
!
      FUNCTION SF_TO_LOSS(X,Z,T,SQO)
!
!  This function transforms a structure factor S(q,omega) into a 
!    loss function L(q,omega) 

!  Note: It makes use of the fluctuation-dissipation theorem 
!        to obtain
!
!  L(q,omega) = S(q,omega) / ( (k_B T / Pi V_C) * B(h_bar omega / k_B T) )
!
!
!    where B(x) is the Bose factor : B(x) = x / ( 1 - exp(-x) )
!
!
!  References: (1) Yu. V. Arkhipov et al, Contrib. Plasma Phys. 
!                      55, 381-389 (2015)
!
!
!           -->   Warning: 3D only at present  <--
!
!
!
!  Input parameters: 
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * Z        : omega / omega_q        --> dimensionless
!       * T        : temperature in SI
!       * SQO      : value of the structure factor
!
!
!   Author :  D. Sébilleau
!
!
!                                           Last modified : 23 Oct 2020
!
      USE MATERIAL_PROP,    ONLY : DMN,RS
      USE SCREENING_TYPE
!
      USE REAL_NUMBERS,     ONLY : ONE,HALF
      USE CONSTANTS_P1,     ONLY : H_BAR,K_B
      USE FERMI_SI,         ONLY : KF_SI,VF_SI
      USE PI_ETC,           ONLY : PI_INV
!
      USE SCREENING_VEC
      USE COULOMB_K
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  X,Z,T,SQO
      REAL (WP)             ::  SF_TO_LOSS
      REAL (WP)             ::  Y,U
      REAL (WP)             ::  Q_SI,OMEGA
      REAL (WP)             ::  KBT,XX,BOSE,COEF
      REAL (WP)             ::  KS_SI,VC
!
      REAL (WP)              ::  EXP 
!
      Y = X + X                                                     ! Y = q / k_F 
      U = X * Z                                                     ! U = omega / (q v_F)
!
      Q_SI = Y * KF_SI                                              ! q in SI
!  
      OMEGA = Q_SI * VF_SI * U                                      ! omega in SI
!
      KBT = K_B * T                                                 ! 
!
!  Computing the screening vector
!
      CALL SCREENING_VECTOR(SC_TYPE,DMN,X,RS,T,KS_SI)
!
!  Computation of the Coulomb potential
!
      CALL COULOMB_FF(DMN,'SIU',Q_SI,KS_SI,VC)                      !
!
!  Computation of the Bose factor
!
      XX   = H_BAR * OMEGA / KBT                                    ! 
      BOSE = XX / (ONE - EXP(- XX))                                 !
!
      COEF = PI_INV / (KBT * VC)                                    !
!
      SF_TO_LOSS = SQO / (COEF * BOSE)                              !
!
      END FUNCTION SF_TO_LOSS  
!
!=======================================================================
!
      SUBROUTINE SQO_TO_EPSI(X,Z,T,RS,SQO,EPSI)
!
!  This subroutine computes the imaginary part of the dielectric function  
!    from the knowledge of the dynamic structure factor,
!    following the formula
!                                                                    _      _
!                 h_bar                       1                     |    1   |
!  S(q,omega) = ----------- *  -------------------------------  * Im| - ---  |
!                pi*n*Vc(q)     1 - exp(-h_bar*omega / k_B*T)       |_  eps _|
!
!
!
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * Z        : omega / omega_q        --> dimensionless
!       * T        : temperature in SI
!       * RS       : Wigner-Seitz radius (in units of a_0)
!       * SQO      : dynamic structure factor
!
!
!  Output variables :
!
!       * EPSI     : imaginary part of dielectric function
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified :  4 Jun 2020
!
!
      USE MATERIAL_PROP,    ONLY : DMN
      USE SCREENING_TYPE
!
      USE REAL_NUMBERS,     ONLY : ONE,TWO,HALF
      USE PI_ETC,           ONLY : PI
      USE CONSTANTS_P1,     ONLY : H_BAR,K_B
      USE FERMI_SI,         ONLY : KF_SI,VF_SI
!
      USE UTILITIES_1,      ONLY : RS_TO_N0
!
      USE SCREENING_VEC
      USE COULOMB_K
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN)  ::  X,Z,T,RS,SQO
      REAL (WP), INTENT(OUT) ::  EPSI
      REAL (WP)              ::  Y,U
      REAL (WP)              ::  Q_SI,OMEGA,KBT
      REAL (WP)              ::  N0,KS_SI,VC
      REAL (WP)              ::  EX,KOEF
!
      REAL (WP)              ::  EXP 
!
      Y = X + X                                                     ! Y = q / k_F 
      U = X * Z                                                     ! U = omega / (q v_F)
!
      Q_SI = Y * KF_SI                                              ! q in SI
!  
      OMEGA = Q_SI * VF_SI * U                                      ! omega in SI
!
      KBT = K_B * T                                                 ! 
!
!  Computing the screening vector
!
      CALL SCREENING_VECTOR(SC_TYPE,DMN,X,RS,T,KS_SI)
!
!  Computation of the Coulomb potential
!
      CALL COULOMB_FF(DMN,'SIU',Q_SI,KS_SI,VC)                      !
!
!  Computing the electron density from the Wigner-Seitz radius
!
      N0=RS_TO_N0(DMN,RS)                                           !
!
      EX= H_BAR * OMEGA / KBT                                       ! 
!
      KOEF = H_BAR / (PI * N0 * VC)                                 ! coef. of formula
!
      EPSI = - KOEF * ONE / ( (ONE - EXP(- EX)) * SQO )             !
!
!  Computing the real part
!
      END SUBROUTINE SQO_TO_EPSI
!
END MODULE UTILITIES_3
 
