!
!=======================================================================
!
MODULE CALCULATORS_2
!
      USE ACCURACY_REAL
!
!  This module contains the subroutines allowing to compute
!    various properties of the electron/plasma liquids:
!
!          * plasmon dispersion            : CALC_PDI
!          * electron-hole dispersion      : CALC_EHD
!          * two electron-hole dispersion  : CALC_E2D
!          * k-space e-e potential         : CALC_EEK
!          * r-space e-e potential         : CALC_EER
!          * plasmon kinetic energy        : CALC_EKP
!
CONTAINS
!
!=======================================================================
!
      SUBROUTINE CALC_PDI(X)
!
!
!  This subroutine computes the analytical plasmon dispersion
!    without damping
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)
!
!
!  Output variables :
!
!       * ENE_P_Q  : plasmon energy at q in J
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 16 Dec 2020
!
!
!
      USE MATERIAL_PROP,      ONLY : RS,DMN
      USE EXT_FIELDS,         ONLY : T
      USE REAL_NUMBERS,       ONLY : ONE,TWO
      USE FERMI_SI,           ONLY : EF_SI,KF_SI
      USE PLASMON_DISPERSION
      USE PLASMON_DISP_REAL
      USE SCREENING_TYPE
      USE SCREENING_VEC
      USE COULOMB_K
!
      USE OUT_VALUES_2,       ONLY : I_PD
      USE PRINT_FILES,        ONLY : IO_PD
!
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  X
!
      REAL (WP)             ::  ENE_P_Q
      REAL (WP)             ::  Y
!
      IF(PL_DISP == '  EXACT') GO TO 10                             !
!
      Y  = X + X                                                    ! q / k_F
!
      IF(DMN == '3D') THEN                                          !
        CALL PLASMON_DISP_3D(X,RS,T,PL_DISP,ENE_P_Q)                !
      ELSE IF(DMN == '2D') THEN                                     !
        CALL PLASMON_DISP_2D(X,RS,T,PL_DISP,ENE_P_Q)                !
      ELSE IF(DMN == '1D') THEN                                     !
        CALL PLASMON_DISP_1D(X,RS,T,PL_DISP,ENE_P_Q)                !
      END IF                                                        !
!
!  Writes the plasmon dispersion as a function of x
!
      IF(I_PD == 1) THEN                                            !
        WRITE(IO_PD,*) Y,ENE_P_Q / EF_SI                            ! x : q/k_F, y : E/E_F
      END IF                                                        !
!
  10  RETURN                                                        !
!
      END SUBROUTINE CALC_PDI
!
!=======================================================================
!
      SUBROUTINE CALC_EHD
!
! This subroutine gives the electron-hole pair dispersion curves.
!
!         --->     The result is given in eV     <---
!
! We have written: hbar^2 / 2m = a_0^2 * Ryd where a_0 is Bohr's radius
!                                            and Ryd is one Rydberg in eV
!
!
!  Output variables :
!
!       * EH_M     : right-handside dispersion curve
!       * EH_P     : left-handside dispersion curve
!
!
!  In order to compare to the plasmon dispersion, where the coeffiecients
!    of (hbar omega)^2 have been stored, we store here the coefficients
!    of (EH_M)^2 = AE(0)+AE(1)*Q + AE(2)*Q^2 + AE(3)*Q^3 + AE(4)*Q^4
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 15 Sep 2020
!
!
      USE DIMENSION_CODE,   ONLY : NSIZE
      USE MATERIAL_PROP,    ONLY : DMN
      USE REAL_NUMBERS,     ONLY : ZERO,ONE,TWO,FOUR,FOURTH
      USE CONSTANTS_P1,     ONLY : BOHR
      USE FERMI_SI,         ONLY : KF_SI
      USE ENE_CHANGE,       ONLY : RYD
      USE DISP_COEF_EH
!
      USE Q_GRID
!
      USE OUT_VALUES_2,     ONLY : I_EH
      USE PRINT_FILES,      ONLY : IO_EH
!
      IMPLICIT NONE
!
      REAL (WP)             ::  QM,Q
      REAL (WP)             ::  EH_P(NSIZE),EH_M(NSIZE)
!
      REAL (WP)             ::  EF,KF,Y,Q0,Q02,STEP
!
      REAL (WP)             ::  FLOAT,ABS
!
      INTEGER               ::  QN,I,IO
!
      KF = BOHR * KF_SI                                             ! k_F in unit of a_O^{-1}
      EF = KF * KF * RYD                                            ! E_F in eV
!
      STEP = Q_STEP * KF_SI                                         ! step in SI
!
!  Initialisation of the coefficients
!
      DO I = 0, 6                                                   !
        AE(I) = ZERO                                                !
      END DO                                                        !
!
!  Loop on q-points
!
      DO QN = 1, N_Q                                                !
!
        Q = Q_MIN * KF_SI + FLOAT(QN - 1) * STEP                    ! step incremented
!
        Q0  = BOHR * Q                                              ! q in unit of a_O^{-1}
        Q02 = Q0 * Q0                                               !
        Y = Q0 / KF                                                 ! dimensionless momentum
!
        IF(DMN == '3D') THEN                                        !
!
!..........  3D case  ..........
!
          EH_P(QN) = (Q02 + TWO * Q0 * KF) * RYD                    !
          EH_M(QN) = (Q02 - TWO * Q0 * KF) * RYD                    !
          AE(2)    = FOUR * KF * KF * FOURTH                        ! division by 4 because
          AE(3)    = FOUR * KF * FOURTH                             !  AU = Hartree = 2 Rydbergs
          AE(4)    = ONE * FOURTH                                   !  and AE in AU
!
        ELSE IF(DMN == '2D') THEN                                   !
!
!..........  2D case  ..........
!
!  Reference: G. F. Giuliani and J. J. Quinn, Phys. Rev. B 26, 4421 (1982)
!
          EH_P(QN) = (TWO * Q0 * KF + Q02) * RYD                    !
          EH_M(QN) = (TWO * Q0 * KF - Q02) * RYD                    !
          AE(2)    = FOUR * KF * KF * FOURTH                        ! division by 4 because
          AE(3)    = FOUR * KF * FOURTH                             !  AU = Hartree = 2 Rydbergs
          AE(4)    = ONE * FOURTH                                   !  and AE in AU
!
        ELSE IF(DMN == '1D') THEN                                   !
!
!..........  1D case  ..........
!
          EH_P(QN) = ABS(Q02 + TWO * Q0 * KF) * RYD                 !
          EH_M(QN) = ABS(Q02 - TWO * Q0 * KF) * RYD                 !
          AE(2)    = FOUR * KF * KF * FOURTH                        ! division by 4 because
          AE(3)    = FOUR * KF * FOURTH                             !  AU = Hartree = 2 Rydbergs
          AE(4)    = ONE * FOURTH                                   !  and AE in AU
!
        END IF                                                      !
!
!  Writes the dispersion curves E/E_F as a function of q/k_F
!
        IF(I_EH == 1) THEN                                          !
          WRITE(IO_EH,*) Y,EH_P(QN) / EF,EH_M(QN) / EF              ! x : q/k_F, y : E/E_F
        END IF                                                      !
!
      END DO                                                        !
!
      END SUBROUTINE CALC_EHD
!
!=======================================================================
!
      SUBROUTINE CALC_E2D
!
! This subroutine gives the 2 electron-hole pairs dispersion curves.
!
!  Note: in this case, there is no letf-hand side, but only a limit
!        on the right-hand side
!
!  References: (1) M. E. Bachlechner, A. Holas, H. M. Böhm and A. Schinner,
!                     Nucl. Instr. and Meth. B 115, 23-26 (1996)
!
!         --->     The result is given in eV     <---
!
!
!  Output variables :
!
!       * TWO_EH_M : right-handside dispersion curve
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 15 Sep 2020
!
!
      USE DIMENSION_CODE,   ONLY : NSIZE
      USE MATERIAL_PROP,    ONLY : DMN
      USE REAL_NUMBERS,     ONLY : ZERO,TWO
      USE CONSTANTS_P1,     ONLY : BOHR
      USE FERMI_SI,         ONLY : KF_SI
      USE ENE_CHANGE,       ONLY : RYD
!
      USE Q_GRID
!
      USE OUT_VALUES_2,     ONLY : I_E2
      USE PRINT_FILES,      ONLY : IO_E2
!
      IMPLICIT NONE
!
      INTEGER               ::  QN
!
      REAL (WP)             ::  QM,Q
      REAL (WP)             ::  Y,Q0,Q02,XN,STEP
      REAL (WP)             ::  N_EH_M
      REAL (WP)             ::  EF,KF
!
      REAL (WP)             ::  FLOAT
!
      XN = TWO                                                      ! number of e-h pairs created
!
      STEP = Q_STEP * KF_SI                                         ! step in SI
!
      KF = BOHR * KF_SI                                             ! k_F in unit of a_O^{-1}
      EF = KF * KF * RYD                                            ! E_F in eV
!
!  Loop on q-points
!
      DO QN = 1, N_Q                                                !
!
        Q = Q_MIN * KF_SI +  FLOAT(QN - 1) * STEP                   ! step incremented
!
        Q0  = BOHR * Q                                              ! q in unit of a_O^{-1}
        Q02 = Q0 * Q0                                               !
        Y   = Q0 / KF                                               ! dimensionless momentum
!
        IF(DMN == '3D') THEN                                        !
!
!..........  3D case  ..........
!
          IF(Y <= TWO * XN) THEN                                    !
            N_EH_M = ZERO                                           !
          ELSE                                                      !
            N_EH_M = (Q02 - TWO * XN * Q0 * KF) * RYD / XN          ! ref. (1) eq. (9)
          END IF                                                    !
!
        ELSE IF(DMN == '2D') THEN                                   !
!
!..........  2D case  ..........
!
          CONTINUE
!
        ELSE IF(DMN == '1D') THEN                                   !
!
!..........  1D case  ..........
!
          CONTINUE
!
!
        END IF                                                      !
!
!  Writes the dispersion curves E/E_F as a function of q/k_F
!
        IF(I_E2 == 1) THEN                                          !
          WRITE(IO_E2,*) Y,N_EH_M / EF                              ! x : q/k_F, y : E/E_F
        END IF                                                      !
!
      END DO                                                        !
!
      END SUBROUTINE CALC_E2D
!
!=======================================================================
!
      SUBROUTINE CALC_EEK(X)
!
!
!  This subroutine computes the electron-electron interaction potential
!    in the k-space
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified :  7 Oct 2020
!
!
      USE DIMENSION_CODE,           ONLY : NSIZE
      USE MATERIAL_PROP,            ONLY : DMN,RS
      USE EXT_FIELDS,               ONLY : T
      USE UNITS
      USE SCREENING_TYPE
      USE SCREENING_VEC
      USE INTERACTION_POTENTIALS_K
!
      USE Q_GRID
!
      USE EL_ELE_INTER
!
      USE REAL_NUMBERS,             ONLY : ONE
      USE FERMI_AU,                 ONLY : KF_AU
      USE FERMI_SI,                 ONLY : KF_SI
!
      USE OUT_VALUES_2,             ONLY : I_CK
      USE PRINT_FILES,              ONLY : IO_CK
!
      IMPLICIT NONE
!
      INTEGER               ::  IQ
!
      REAL (WP), INTENT(IN) ::  X
      REAL (WP)             ::  KS_SI,KS
      REAL (WP)             ::  Q,VQ
!
      REAL (WP)             ::  FLOAT
!
!  Computing the screening vector
!
      CALL SCREENING_VECTOR(SC_TYPE,DMN,X,RS,T,KS_SI)               !
!
!  Screening vector in units of UNIK
!
      IF(UNIK == 'SI') THEN                                         !
        KS = KS_SI                                                  !
      ELSE IF(UNIK == 'AU') THEN                                    !
        KS = KS_SI * KF_AU / KF_SI                                  !
      END IF                                                        !
!
!  Loop on q-points
!
      DO IQ = 1,N_Q                                                 !
!
        Q = Q_MIN * KF_SI + FLOAT(IQ - 1) * Q_STEP                  ! step incremented
!
        CALL INTERACT_POT_K_3D(INT_POT,UNIT,UNIK,ONE,ONE,ONE,ONE, & !
                               Q,KS,VQ)                             !
!
        IF(I_CK == 1) THEN                                          !
          WRITE(IO_CK,*) Q,VQ                                       !
        END IF                                                      !
!
      END DO                                                        !
!
      END SUBROUTINE CALC_EEK
!
!=======================================================================
!
      SUBROUTINE CALC_EER(X)
!
!
!  This subroutine computes the electron-electron interaction potential
!    in the real space
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 14 Apr 2021
!
!
      USE DIMENSION_CODE,           ONLY : NSIZE
      USE MATERIAL_PROP,            ONLY : DMN,RS
      USE EXT_FIELDS,               ONLY : T
      USE SCREENING_TYPE
      USE SCREENING_VEC
      USE INTERACTION_POTENTIALS_R
!
      USE R_GRID
!
      USE REAL_NUMBERS,             ONLY : ONE
      USE FERMI_AU,                 ONLY : KF_AU
      USE FERMI_SI,                 ONLY : KF_SI
!
      USE OUT_VALUES_2,             ONLY : I_CR
      USE PRINT_FILES,              ONLY : IO_CR
!
      IMPLICIT NONE
!
      CHARACTER (LEN = 3)   ::  UNIT
!
      INTEGER               ::  IR
!
      REAL (WP), INTENT(IN) ::  X
      REAL (WP)             ::  KS_SI,KS
      REAL (WP)             ::  R,VR
!
      REAL (WP)             ::  FLOAT
!
      UNIT = 'CGS'                                                  !
!
!  Computing the screening vector
!
      CALL SCREENING_VECTOR(SC_TYPE,DMN,X,RS,T,KS_SI)               !
!
!  Screening vector in units of 1/a_0
!
      KS = KS_SI * KF_AU / KF_SI                                    !
!
      DO IR = 1,N_R                                                 ! r loop
!
        R = R_MIN + FLOAT(IR - 1) * R_STEP                          ! r/a0 point
!
        CALL INTERACT_POT_R_3D(UNIT,R,ONE,ONE,KS,VR)                !
!
        IF(I_CR == 1) THEN                                          !
          WRITE(IO_CR,*) R,VR                                       !
        END IF                                                      !
!
      END DO                                                        !
!
      END SUBROUTINE CALC_EER
!
!=======================================================================
!
      SUBROUTINE CALC_EKP(X)
!
!
!  This subroutine computes the plasmon kinetic energy
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 29 Oct 2020
!
!
!
      USE OUT_VALUES_2,             ONLY : I_PK
      USE PRINT_FILES,              ONLY : IO_PK
!
      IMPLICIT NONE
!
      REAL (WP), INTENT(IN) ::  X
      REAL (WP)             ::  Y,Y2
!
      Y  = X + X                                                    ! q / k_F
      Y2 = Y * Y                                                    !
!
      IF(I_PK == 1) THEN                                          !
        WRITE(IO_PK,*) X,Y2                                       !
      END IF                                                      !
!
      END SUBROUTINE CALC_EKP
!
END MODULE CALCULATORS_2
