!
!=======================================================================
!
MODULE MOMENTS_CALC
!
      USE ACCURACY_REAL
!
!  This module provides the functions/subroutines to compute
!    the moments of different functions
!
!
!
CONTAINS
!
!=======================================================================
!
      SUBROUTINE MOMENTS_LOSS_FUNCTION(X,N,MLO)
!
!  This module computes the moments of the loss function
!
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)
!       * N        : moment order
!
!
!  Output variables :
!
!       * MLO      : moment
!
!
!
!  The moments are defined by
!                                                 _             _
!                            / + INF             |               |
!                           |             n      |      - 1      |
!   < omega^n>    =     2   |        omega    Im | ------------- |   d omega
!                           |                    |  eps(q,omega) |
!                          / 0                   |_             _|
!
!
!
!   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 REAL_NUMBERS,       ONLY : ZERO,TWO,FOURTH,TTINY,INF
      USE FERMI_SI,           ONLY : KF_SI
!
      USE E_GRID
!
      USE DF_VALUES,           ONLY : D_FUNC
!
      USE INTEGRATION,         ONLY : INTEGR_L
      USE DFUNCL_STAN_DYNAMIC
!
      IMPLICIT NONE
!
      INTEGER,INTENT(IN)    ::  N
      INTEGER               ::  IE
      INTEGER               ::  ID
      INTEGER               ::  I_ZE
!
      REAL (WP), INTENT(IN) ::  X
      REAL (WP), INTENT(OUT)::  MLO
      REAL (WP)             ::  E,V,Z
      REAL (WP)             ::  EPSR,EPSI
      REAL (WP)             ::  ELF(NSIZE)
      REAL (WP)             ::  A
!
      IF(MOD(N,2) == 0 .AND. N /= 0) THEN                           !
        MLO =  ZERO                                                 !
        RETURN                                                      !
      END IF                                                        !
!
      I_ZE = 0                                                      ! switch for integrand = 0
!
!  Constructing the e-grid
!
      DO IE = 1, N_E                                                ! E_F
!
        E = E_MIN + FLOAT(IE - 1) * E_STEP                          ! in units of
        V = E                                                       ! hbar * omega / E_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(IE) = E**N * EPSI / ( (EPSR * EPSR + EPSI * EPSI) )     ! integrand function
!
        IF(ABS(ELF(IE)) >= TTINY) I_ZE = IE                         !
!
      END DO                                                        !
!
      IF(I_ZE > 0) THEN                                             !
!
!  Performing the e-integration with respect to E
!
        ID = 1                                                      !
        CALL INTEGR_L(ELF,E_STEP,NSIZE,N_E,A,ID)                    !
!
        MLO = TWO * A                                               !
!
      ELSE                                                          ! IN always = 0
!
        MLO = ZERO                                                  !
!
      END IF                                                        !
!
      END SUBROUTINE MOMENTS_LOSS_FUNCTION
!
!=======================================================================
!
      SUBROUTINE MOMENTS_STRUCT_FACTOR(X,N,MSF)
!
!  This module computes the moments of the dynamical structure factor
!
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)
!       * N        : moment order
!
!
!  Output variables :
!
!       * MLO      : moment
!
!
!
!  The moments are defined by
!
!                            / + INF
!                           |             n
!   < omega^n>    =     2   |        omega    S(q,omega)  d omega
!                           |
!                          / 0
!
!
!  Note: in the calculation of the moments of the loss function, q and omega
!        are respectively in units of k_F and E_F
!
!        --> we write the coefficient COEF in units of 1/ E_F
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 21 Oct 2020
!
!
      USE DIMENSION_CODE,     ONLY : NSIZE
      USE MATERIAL_PROP,      ONLY : RS
      USE EXT_FIELDS,         ONLY : T
!
      USE REAL_NUMBERS,       ONLY : ZERO,TWO,HALF,FOURTH,TTINY,INF
      USE CONSTANTS_P1,       ONLY : H_BAR,M_E
      USE FERMI_SI,           ONLY : EF_SI,KF_SI
      USE PI_ETC,             ONLY : PI_INV
!
      USE E_GRID
!
      USE PLASMON_ENE_SI
      USE SF_VALUES
      USE STRUCTURE_FACTOR_DYNAMIC
      USE MOMENTS,            ONLY : M_TYPE
      USE INTEGRATION,        ONLY : INTEGR_L
!
      IMPLICIT NONE
!
      INTEGER,INTENT(IN)    ::  N
      INTEGER               ::  IE
      INTEGER               ::  ID
      INTEGER               ::  I_ZE
      INTEGER               ::  LOGF
!
      REAL (WP), INTENT(IN) ::  X
      REAL (WP), INTENT(OUT)::  MSF
!
      REAL (WP)             ::  Q_SI,EQ_SI
      REAL (WP)             ::  COEF,MLO
      REAL (WP)             ::  E,V,Z
      REAL (WP)             ::  SQM(NSIZE)
      REAL (WP)             ::  SQO,A
!
      LOGF = 6                                                      ! log file unit
!
      IF(M_TYPE == 'EPS') THEN
!
        Q_SI = TWO * KF_SI * X                                      ! q in SI
!
        EQ_SI = HALF * H_BAR * H_BAR * Q_SI * Q_SI / M_E            ! h_bar omega_q in SI
        COEF  = TWO * PI_INV * (EQ_SI / ENE_P_SI) * EF_SI / ENE_P_SI! coefficient in units of 1/E_F
!
!  Computing the moments of the loss function
!
        CALL MOMENTS_LOSS_FUNCTION(X,N,MLO)                         !
!
        MSF = COEF * MLO                                            !
!
      ELSE IF(M_TYPE == 'SQO') THEN                                 !
!
      IF(SSTDY == ' STATIC') THEN                                   ! pathological case
        WRITE(LOGF,10)                                              !
        STOP                                                        !
      END IF                                                        !
!
!  Constructing the e-grid
!
        DO IE = 1, N_E                                              !
!
          E = E_MIN + FLOAT(IE - 1) * E_STEP                        ! in units of
          V = E                                                     ! hbar * omega / E_F
          Z = FOURTH * V / (X * X)                                  ! omega / omega_q
!
!  Computing the dynamical structure factor
!
        CALL STFACT_DYNAMIC(X,Z,RS,T,SQO_TYPE,SQ_TYPE,SQO)          !
!
          SQM(IE) = E**N * SQO                                      ! integrand function
!
          IF(ABS(SQM(IE)) >= TTINY) I_ZE = IE                       !
!
        END DO                                                      !
!
        IF(I_ZE > 0) THEN                                           !
!
!  Performing the e-integration with respect to E
!
          ID = 1                                                    !
          CALL INTEGR_L(SQM,E_STEP,NSIZE,N_E,A,ID)                  !
!
          MSF = TWO * A                                             !
!
        ELSE                                                        ! IN always = 0
!
          MSF = ZERO                                                !
!
        END IF                                                      !
!
      END IF                                                        !
!
!  Format:
!
  10  FORMAT(//,10X,'<<<<<  SSTDY PARAMETER WRONG  >>>>>',/        &
                10X,'<<<<<  CHANGE IN INPUT FILE   >>>>>',//)
!
      END SUBROUTINE MOMENTS_STRUCT_FACTOR
!
!=======================================================================
!
      SUBROUTINE MOMENTS_EPSILON(X,N,MEP)
!
!  This module computes the moments of the dynamical structure factor
!
!
!  Input parameters:
!
!       * X        : dimensionless factor   --> X = q / (2 * k_F)
!       * N        : moment order
!
!
!  Output variables :
!
!       * MEP      : moment
!
!
!
!  The moments are defined by
!
!                            / + INF              _            _
!                           |             n      |              |
!   < omega^n>    =     2   |        omega    Im | eps(q,omega) |   d omega
!                           |                    |_            _|
!                          / 0
!
!
!
!   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 REAL_NUMBERS,       ONLY : ZERO,TWO,FOURTH,TTINY,INF
      USE FERMI_SI,           ONLY : KF_SI
!
      USE E_GRID
!
      USE DF_VALUES,           ONLY : D_FUNC
!
      USE INTEGRATION,         ONLY : INTEGR_L
      USE INTEGRATION4
      USE DFUNCL_STAN_DYNAMIC
!
      IMPLICIT NONE
!
      INTEGER,INTENT(IN)    ::  N
      INTEGER               ::  IE
      INTEGER               ::  ID
      INTEGER               ::  I_ZE
!
      REAL (WP), INTENT(IN) ::  X
      REAL (WP), INTENT(OUT)::  MEP
      REAL (WP)             ::  E,V,Z
      REAL (WP)             ::  EPSR,EPSI
      REAL (WP)             ::  ELF(NSIZE)
      REAL (WP)             ::  A
!
      IF(MOD(N,2) == 0 .AND. N /= 0) THEN                           !
        MEP =  ZERO                                                 !
        RETURN                                                      !
      END IF                                                        !
!
      I_ZE = 0                                                      ! switch for integrand = 0
!
!  Constructing the e-grid
!
      DO IE = 1, N_E                                                ! E_F
!
        E = E_MIN + FLOAT(IE - 1) * E_STEP                          ! in units of
        V = E                                                       ! hbar * omega / E_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(IE) = E**N * EPSI                                       ! integrand function
!
        IF(ABS(ELF(IE)) >= TTINY) I_ZE = IE                         !
!
      END DO                                                        !
!
      IF(I_ZE > 0) THEN                                             !
!
!  Performing the e-integration with respect to E
!
        ID = 1                                                      !
        CALL INTEGR_L(ELF,E_STEP,NSIZE,N_E,A,ID)                    !
!
        MEP = TWO * A                                               !
!
      ELSE                                                          ! IN always = 0
!
        MEP = ZERO                                                  !
!
      END IF                                                        !
!
      END SUBROUTINE MOMENTS_EPSILON
!
END MODULE MOMENTS_CALC
