!
!=======================================================================
!
MODULE NEVALINNA_FUNCTIONS 
!
!  This modules provides Nevalinna functions
!
! 
!
      USE ACCURACY_REAL
!
CONTAINS
!
!=======================================================================
!
      FUNCTION NEVAN2(X,Z,RS,T,TAU,NEV_TYPE)
!
!  This function computes the Nevalinna function Q_2(x,omega)
!
!  In an electron liquid, the Nevalinna function Q(x,z) plays the role 
!    of the dynamic local-field correction G(x,z).
!
!
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * Z        : dimensionless factor   --> Z = omega / omega_q 
!       * RS       : Wigner-Seitz radius (in units of a_0)
!       * T        : temperature in SI
!       * TAU      : relaxation time in SI
!       * NEV_TYPE : type of Nevalinna function used
!                      NEV_TYPE  = 'NONE' --> no function
!                      NEV_TYPE  = 'RELA' --> static value h(q) = i / tau
!                      NEV_TYPE  = 'STA1' --> static value h(q) 
!                      NEV_TYPE  = 'STA2' --> static value h(q)
!                      NEV_TYPE  = 'STA3' --> static value h(q)
!                      NEV_TYPE  = 'STA4' --> static value h(q)
!                      NEV_TYPE  = 'PEEL' --> Perel'-Eliashberg function
!                      NEV_TYPE  = 'PE76' --> Perel'-Eliashberg by V. Arkhipov et al
!                      NEV_TYPE  = 'CPP1' --> 
!                      NEV_TYPE  = 'CPP2' --> 
!                      NEV_TYPE  = 'CPP3' --> 
!                      NEV_TYPE  = 'CPP4' --> 
!                      NEV_TYPE  = 'PST1' --> 
!
!
!  Remark: The Nevalinna function has the dimension of a frequency omega
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 18 Nov 2020
!
!
      USE COMPLEX_NUMBERS,    ONLY : ZEROC,IC  
      USE LOSS_MOMENTS
!
      IMPLICIT NONE
!
      CHARACTER (LEN = 4)   ::  NEV_TYPE
!
      REAL (WP), INTENT(IN) ::  X,Z,T,RS,TAU
      REAL (WP)             ::  C0,C2,C4
      REAL (WP)             ::  OM12,OM22
!
      COMPLEX (WP)          ::  NEVAN2
!
!  Computing the moments of the loss function
!
      CALL LOSS_MOMENTS_AN(X,C0,C2,C4)                              !
!
      OM12 = C2 / C0                                                !
      OM22 = C4 / C2                                                !
!
      IF(NEV_TYPE == 'NONE') THEN                                   !
        NEVAN2 = ZEROC                                              !
      ELSE IF(NEV_TYPE == 'RELA') THEN                              !
        NEVAN2 = IC / TAU                                           !
      ELSE IF(NEV_TYPE == 'STA1') THEN                              !
        NEVAN2 = STA1(OM12,OM22)                                    !
      ELSE IF(NEV_TYPE == 'STA2') THEN                              !
        NEVAN2 = STA2(OM22,TAU)                                     !
      ELSE IF(NEV_TYPE == 'STA3') THEN                              !
        NEVAN2 = STA3(X,OM12,OM22)                                  !
      ELSE IF(NEV_TYPE == 'STA4') THEN                              !
        NEVAN2 = STA4(X,OM12,TAU)                                   !
      ELSE IF(NEV_TYPE == 'CPP1') THEN                              !
        NEVAN2 = CPP1(X,Z,RS,OM12,OM22)                             !
      ELSE IF(NEV_TYPE == 'CPP2') THEN                              !
        NEVAN2 = CPP2(X,Z,RS,TAU,OM12,OM22)                         !
      ELSE IF(NEV_TYPE == 'CPP3') THEN                              !
        NEVAN2 = CPP3(X,Z,OM22,TAU)                                 !
      ELSE IF(NEV_TYPE == 'CPP4') THEN                              !
        NEVAN2 = CPP4(X,Z,T,OM12,OM22)                              !
      ELSE IF(NEV_TYPE == 'PEEL') THEN                              !
        NEVAN2 = PEEL(X,Z,RS,OM12,OM22)                             !
      ELSE IF(NEV_TYPE == 'PE76') THEN                              !
        NEVAN2 = PE76(X,Z,RS,OM12,OM22)                             !
      ELSE IF(NEV_TYPE == 'PST1') THEN                              !
        NEVAN2 = PST1(X,Z,OM12,OM22)                                !
      END IF                                                        !
!
      END FUNCTION NEVAN2
!
!=======================================================================
!
      FUNCTION STA1(OM12,OM22)
!
!  This function computes a static Nevalinna function 
!
!
!  References: (1) Yu. V. Arkhipov et al, Contrib. Plasma Phys. 58, 
!                      967–975 (2018)
!
!
!  Input parameters:
!
!       * OM12     : omega_1^2 \  characteristic squared
!       * OM22     : omega_2^2 /       frequencies
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 18 Nov 2020
!
      USE REAL_NUMBERS,       ONLY : TWO
      USE COMPLEX_NUMBERS,    ONLY : IC  
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  OM12,OM22
!
      REAL (WP)             ::  SQRT
!
      COMPLEX (WP)          ::  STA1
!
      STA1 = IC * OM22 / SQRT(TWO * OM12)                           ! ref. (1) eq. (13)
!
      END FUNCTION STA1
!
!=======================================================================
!
      FUNCTION STA2(OM22,TAU)
!
!  This function computes a static Nevalinna function 
!
!
!  References: (1) Yu. V. Arkhipov et al, Contrib. Plasma Phys. 50, 
!                      165-176 (2010)
!
!
!  Input parameters:
!
!       * OM22     : omega_2^2       characteristic squared frequency
!       * TAU      : relaxation time (in SI)
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 18 Nov 2020
!
      USE REAL_NUMBERS,       ONLY : TWO
      USE COMPLEX_NUMBERS,    ONLY : IC 
      USE CONSTANTS_P1,       ONLY : H_BAR
      USE PLASMON_ENE_SI
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  OM22,TAU
!
      REAL (WP)             ::  OMP,OM2
!
      COMPLEX (WP)          ::  STA2
!
      OMP = ENE_P_SI / H_BAR                                        ! omega_p
      OM2 = OM22 - OMP * OMP                                        ! ref. (1) eq. (15)
!
      STA2 = IC * OM2 * TAU                                         ! ref. (1) eq. (29)
!
      END FUNCTION STA2
!
!=======================================================================
!
      FUNCTION STA3(X,OM12,OM22)
!
!  This function computes a static Nevalinna function 
!
!
!  References: (1) S. V. Adamjan, T. Meyer and I. M. Tkachenko, 
!                     Contrib. Plasma Phys. 29, 373-375 (1989)
!
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * OM12     : omega_1^2 \  characteristic squared
!       * OM22     : omega_2^2 /       frequencies
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 26 Nov 2020
!
      USE MATERIAL_PROP,      ONLY : DMN 
!
      USE REAL_NUMBERS,       ONLY : ONE,TWO,FOUR,HALF
      USE COMPLEX_NUMBERS,    ONLY : IC  
      USE PI_ETC,             ONLY : PI
      USE CONSTANTS_P1,       ONLY : BOHR,H_BAR,M_E
      USE FERMI_SI,           ONLY : KF_SI
      USE DFUNC_STATIC,       ONLY : RPA1_EPS_S_LG
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  X,OM12,OM22
      REAL (WP)             ::  EPSR,EPSI
      REAL (WP)             ::  Q_SI,OMQ
      
!
      COMPLEX (WP)          ::  STA3
!
      Q_SI = TWO * X * KF_SI                                        ! q in SI
!
      OMQ  = HALF * H_BAR * Q_SI * Q_SI / M_E                       ! omega_q
!
!  Computing the static RPA dielectric function
!
      CALL RPA1_EPS_S_LG(X,DMN,EPSR,EPSI)                           !
!
      STA3 = IC * EPSR * (EPSR - ONE) * HALF * PI * OMQ *         & !
                          BOHR * Q_SI * (OM22 / OM12 - ONE)         !
!
      END FUNCTION STA3
!
!=======================================================================
!
      FUNCTION STA4(X,OM12,TAU)
!
!  This function computes a static Nevalinna function 
!
!
!  References: (1) V. M. Adamyan and I. M. Tkachenko, 
!                     Contrib. Plasma Phys. 43,  252-257 (2003)
!
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * OM12     : omega_1^2    characteristic squared frequency
!       * TAU      : relaxation time (in SI)
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 27 Nov 2020
!
      USE REAL_NUMBERS,       ONLY : ONE,TWO,FOUR,HALF
      USE COMPLEX_NUMBERS,    ONLY : IC  
      USE PI_ETC,             ONLY : PI
      USE CONSTANTS_P1,       ONLY : H_BAR,M_E
      USE FERMI_SI,           ONLY : KF_SI,EF_SI 
      USE PLASMON_ENE_SI
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN)  ::  X,OM12,TAU
      REAL (WP)              ::  EPSR,EPSI
      REAL (WP)              ::  Q_SI,OMQ
      REAL (WP)              ::  OMP,OM220
      REAL (WP)              ::  OMP2,OMQ2
      REAL (WP)              ::  AV_KE
!
      COMPLEX (WP)           ::  STA4
!
      Q_SI = TWO * X * KF_SI                                        ! q in SI
!
      OMP  = ENE_P_SI / H_BAR                                       ! omega_p
      OMQ  = HALF * H_BAR * Q_SI * Q_SI / M_E                       ! omega_q
!
      OMP2 = OMP * OMP                                              !
      OMQ2 = OMQ * OMQ                                              !
!
!  Computing omega_2^2(0) = C_4(0) / C_2 --> with I(0) = 0
!
      OM220 = OMP2 * ( FOUR *  AV_KE * OMQ / H_BAR +             & !  
                       OMQ2 + OMP2                               & ! 
                     )                                             !
!
      STA4 = IC * TAU * OMP2 * (OM220 / OMP2 - ONE)                ! ref. (1), before eq. (29)
!
      END FUNCTION STA4
!
!=======================================================================
!
      FUNCTION PEEL(X,Z,RS,OM12,OM22)
!
!  This function computes the  Perel'-Eliashberg dynamic Nevalinna function 
!
!
!  References: (1) Yu. V. Arkhipov et al, Contrib. Plasma Phys. 55, 
!                      381-389 (2015)
!
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * Z        : dimensionless factor   --> Z = omega / omega_q 
!       * RS       : Wigner-Seitz radius (in units of a_0)
!       * OM12     : omega_1^2 \  characteristic squared
!       * OM22     : omega_2^2 /       frequencies
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 27 Nov 2020
!
      USE PLASMA,             ONLY : ZION
!
      USE REAL_NUMBERS,       ONLY : TWO,THREE,FIVE
      USE COMPLEX_NUMBERS,    ONLY : ONEC,IC  
      USE PI_ETC,             ONLY : PI
      USE SQUARE_ROOTS,       ONLY : SQR2
      USE CONSTANTS_P1,       ONLY : H_BAR
      USE FERMI_SI,           ONLY : KF_SI,VF_SI
      USE PLASMON_ENE_SI
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  X,Z,RS
      REAL (WP), INTENT(IN) ::  OM12,OM22
!
      REAL (WP)             ::  U,Q_SI,OM,OMP
      REAL (WP)             ::  A,NUM,DEN
!
      REAL (WP)             ::  SQRT
!
      COMPLEX (WP)          ::  PEEL
!
      Q_SI = TWO * X * KF_SI                                        ! q in SI
      U    = X * Z                                                  ! omega / (q * v_F)
      OM   = U * Q_SI * VF_SI                                       ! omega in SI
      OMP  = ENE_P_SI / H_BAR                                       ! omega_p
!
      A = SQR2 * RS**0.75E0_WP * ZION / THREE**1.25E0_WP            ! ref. (1) eq. (11)
!
      NUM = A * OMP * OMP * SQRT(OMP * OM)                          !
      DEN = OM22 - OM12                                             !
!
      PEEL = NUM * (ONEC + IC) / DEN                                ! ref. (1) eq. (12)
!
      END FUNCTION PEEL
!
!=======================================================================
!
      FUNCTION PE76(X,Z,RS,OM12,OM22)
!
!  This function computes the  Perel'-Eliashberg dynamic Nevalinna function 
!
!
!  References: (1) Yu. V. Arkhipov et al, Phys. Rev. E 76, 026403 (2007)
!
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * Z        : dimensionless factor   --> Z = omega / omega_q 
!       * RS       : Wigner-Seitz radius (in units of a_0)
!       * OM12     : omega_1^2 \  characteristic squared
!       * OM22     : omega_2^2 /       frequencies
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 18 Nov 2020
!
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  X,Z,RS
      REAL (WP), INTENT(IN) ::  OM12,OM22
!
      COMPLEX (WP)          ::  PE76
!
      PE76 = PEEL(X,Z,RS,OM12,OM22) + STA3(X,OM12,OM22)             !
!
      END FUNCTION PE76
!
!=======================================================================
!
      FUNCTION CPP1(X,Z,RS,OM12,OM22)
!
!  This function computes the  Perel'-Eliashberg dynamic Nevalinna function 
!
!
!  References: (1) Yu. V. Arkhipov et al, Contrib. Plasma Phys. 53, 
!                      375-384 (2013)
!
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * Z        : dimensionless factor   --> Z = omega / omega_q 
!       * RS       : Wigner-Seitz radius (in units of a_0)
!       * OM12     : omega_1^2 \  characteristic squared
!       * OM22     : omega_2^2 /       frequencies
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 24 Nov 2020
!
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  X,Z,RS 
      REAL (WP), INTENT(IN) ::  OM12,OM22
!
      COMPLEX (WP)          ::  CPP1
!
      CPP1 = PEEL(X,Z,RS,OM12,OM22) + STA1(OM12,OM22)               !
!
      END FUNCTION CPP1
!
!=======================================================================
!
      FUNCTION CPP2(X,Z,RS,TAU,OM12,OM22)
!
!  This function computes the  Perel'-Eliashberg dynamic Nevalinna function 
!
!
!  References: (1) Yu. V. Arkhipov et al, Contrib. Plasma Phys. 53, 
!                      375-384 (2013)
!
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * Z        : dimensionless factor   --> Z = omega / omega_q 
!       * RS       : Wigner-Seitz radius (in units of a_0)
!       * TAU      : relaxation time (in SI)
!       * OM12     : omega_1^2 \  characteristic squared
!       * OM22     : omega_2^2 /       frequencies
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 18 Nov 2020
!
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  X,Z,RS,TAU
      REAL (WP), INTENT(IN) ::  OM12,OM22
!
      COMPLEX (WP)          ::  CPP2
!
      CPP2 = PEEL(X,Z,RS,OM12,OM22) + STA2(OM22,TAU)                !
!
      END FUNCTION CPP2
!
!=======================================================================
!
      FUNCTION CPP3(X,Z,OM22,TAU)
!
!  This function computes a dynamic Nevalinna function 
!
!
!  References: (1) D. Ballester and I. M. Tkachenko, 
!                     Contrib. Plasma Phys. 45, 293-299 (2005)
!
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * Z        : dimensionless factor   --> Z = omega / omega_q 
!       * OM22     : omega_2^2       characteristic squared frequency
!       * TAU      : relaxation time (in SI)
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 18 Nov 2020
!
      USE REAL_NUMBERS,       ONLY : TWO 
      USE COMPLEX_NUMBERS,    ONLY : IC 
      USE CONSTANTS_P1,       ONLY : H_BAR
      USE FERMI_SI,           ONLY : KF_SI,VF_SI
      USE PLASMON_ENE_SI
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  X,Z,OM22,TAU
!
      REAL (WP)             ::  U,Q_SI,OM
      REAL (WP)             ::  OMP
      REAL (WP)             ::  ZETA,NUM
!
      COMPLEX (WP)          ::  CPP3
      COMPLEX (WP)          ::  DEN
!
      ZETA = 0.27E0_WP                                              !
!
      Q_SI = TWO * X * KF_SI                                        ! q in SI
      U    = X * Z                                                  ! omega / (q * v_F)
      OM   = U * Q_SI * VF_SI                                       ! omega in SI
!
      OMP = ENE_P_SI / H_BAR                                        ! omega_p
!
      NUM = - ZETA * OMP * OM22 * TAU                               !
      DEN = OM + IC * ZETA * OMP                                    !
!
      CPP3 = NUM / DEN                                              ! ref. (1) eq. (16)
!
      END FUNCTION CPP3
!
!=======================================================================
!
      FUNCTION CPP4(X,Z,T,OM12,OM22)
!
!  This function computes a dynamic Nevalinna function 
!
!
!  References: (1) Yu. V. Arkhipov et al, Contrib. Plasma Phys. 58, 
!                      967–975 (2018)
!
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * Z        : dimensionless factor   --> Z = omega / omega_q 
!       * T        : temperature in SI
!       * OM12     : omega_1^2 \  characteristic squared
!       * OM22     : omega_2^2 /       frequencies
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 18 Nov 2020
!
      USE REAL_NUMBERS,       ONLY : ONE
      USE COMPLEX_NUMBERS,    ONLY : IC  
      USE CONSTANTS_P1,       ONLY : K_B
      USE FERMI_SI,           ONLY : EF_SI 
      USE PI_ETC,             ONLY : PI_INV
!
      USE CHEMICAL_POTENTIAL, ONLY : MU_T
      USE SPECIFIC_INT_9
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  X,Z,T,OM12,OM22
!
      REAL (WP)             ::  U
      REAL (WP)             ::  ALPHA
      REAL (WP)             ::  KBT,D,ETA
      REAL (WP)             ::  INTG,XI
!
      COMPLEX (WP)          ::  CPP4
!
      U    = X * Z                                                  ! omega / (q * v_F)
!
      ALPHA = 0.99E0_WP                                             !
!
      KBT   = K_B * T                                               ! 
!
      D     = EF_SI / KBT                                           ! degeneracy
      ETA   = MU_T('3D',T) / KBT                                    !
!
!  Computing the integral Xi(U)
!
      CALL INT_XIZ(U,D,ETA,INTG)                                    !
      XI = PI_INV * INTG                                            !
!
      CPP4 =  STA1(OM12,OM22) / (                                 & !
              ALPHA + IC * (ALPHA - ONE) * XI                     & ! ref. (1) eq. (23)
                                )                                   !
!
      END FUNCTION CPP4
!
!=======================================================================
!
      FUNCTION PST1(X,Z,OM12,OM22)
!
!  This function computes a dynamic Nevalinna function 
!
!
!  References: (1) I. M. Tkachenko, Phys. Sciences and Tech. 5, 16-35 (2016)
!
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)  
!       * Z        : dimensionless factor   --> Z = omega / omega_q 
!       * OM12     : omega_1^2 \  characteristic squared
!       * OM22     : omega_2^2 /       frequencies
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 27 Nov 2020
!
      USE REAL_NUMBERS,       ONLY : TWO,TENTH,TTINY
      USE COMPLEX_NUMBERS,    ONLY : IC 
      USE PI_ETC,             ONLY : SQR_PI,PI
      USE CONSTANTS_P1,       ONLY : H_BAR
      USE EXT_FUNCTIONS,      ONLY : DAWSON
      USE MINMAX_VALUES
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  X,Z,OM12,OM22
!
      REAL (WP)             ::  U,U2
      REAL (WP)             ::  MAX_EXP,MIN_EXP
      REAL (WP)             ::  EXPO
!
      REAL (WP)             ::  EXP
!
      COMPLEX (WP)          ::  PST1
      COMPLEX (WP)          ::  ZF
!
!  Computing the max and min value of the exponent of e^x
!
      CALL MINMAX_EXP(MAX_EXP,MIN_EXP)                              !
!
      U  = X * Z                                                    ! omega / (q * v_F)
      U2 = U * U                                                    ! 
!
      IF(U2 > TENTH * MAX_EXP) THEN                                 !
        EXPO = TTINY                                                !
      ELSE                                                          !
        EXPO = EXP(- U2)                                            !
      END IF                                                        !
!
      ZF = IC * SQR_PI * EXPO - TWO * DAWSON(U)                     !
!
      PST1 = OM22 * ZF / SQRT(TWO * PI * OM12)                      ! ref. (1) eq. (57a)
!
      END FUNCTION PST1
!
END MODULE NEVALINNA_FUNCTIONS
