!
!=======================================================================
!
MODULE SPECIFIC_INT_9
!
!  This module provides integrals to compute the real part 
!    of the dielectric function
!
!
      USE ACCURACY_REAL
      USE ACCURACY_INTEGER
      USE MINMAX_VALUES
!
CONTAINS
!
!=======================================================================
!
      SUBROUTINE INT_XIZ(X,A,B,INTG)
!
!  This subroutine computes an integral often used 
!   to compute the real part of the dielectric function
!
!
!  Reference: (1) Yu. V. Arkhipov et al, 
!                     Contrib. Plasma Phys. 58, 967–975 (2018)
!
! 
!
!  Input parameters:
!
!       * X        : dimensionless parameter
!       * A        : parameter of the exponential
!       * B        : parameter of the exponential
!
!  Output parameters:
!
!       * INTG     : integral 1
!
!
!
!
!                / + INF
!               |           1 + exp(B)           1      
!  INTG(x) =    |      ---------------------  ------- dy
!               |       exp(A y^2) + exp(B)    y - x
!              / - INF
!
!
!
!  Warning: the integrand becomes infinite when y = x. We correct 
!           this problem by making a linear interpolation at this value
!
!  Warning: the exponential can come quickly too large or too small 
!           to be represented. We need to test it exponent against 
!           MAX_EXP and MIN_EXP which represents the limits of the 
!           representation of e^x for real numbers of kind WP
!
! 
!
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 27 Nov 2020
!
!
      USE REAL_NUMBERS,             ONLY : ZERO,ONE,TWO,HALF,LARGE,TTINY
      USE INTEGRATION,              ONLY : INTEGR_L
!
      IMPLICIT NONE
!
      INTEGER (IW), PARAMETER ::  N_I = 1000            ! number of integration steps
      INTEGER (IW)            ::  I                     ! loop index
      INTEGER (IW)            ::  I0                    ! pathological index
      INTEGER (IW)            ::  ID                    ! integration variable
!
      REAL (WP), INTENT(IN)   ::  X,A,B
      REAL (WP), INTENT(OUT)  ::  INTG
      REAL (WP)               ::  MAX_EXP,MIN_EXP
      REAL (WP)               ::  EXA,EXB
      REAL (WP)               ::  Y_MIN,Y_MAX,Y_STEP
      REAL (WP)               ::  Y,Y2
      REAL (WP)               ::  F(N_I)
      REAL (WP)               ::  AY2,NUM,DEN
!
      REAL (WP)               ::  FLOAT,EXP
!
!  Computing the max and min value of the exponent of e^x
!
      CALL MINMAX_EXP(MAX_EXP,MIN_EXP)                              !
!
      ID = 2                                                        ! integrand /= 0 at 0
!
      I0 = 0                                                        ! counter for pathological case
!
!  Evaluation of the exp(B)
!
      IF(B >= ZERO) THEN                                            !
        IF(B < HALF * MAX_EXP) THEN                                 !
          EXB = EXP(B)                                              !
        ELSE                                                        !
          EXB = LARGE                                               ! <-- e^{b} too large for being represented
        END IF                                                      !
      ELSE                                                          !
        IF(B > HALF * MIN_EXP) THEN                                 !
          EXB = EXP(B)                                              !
        ELSE                                                        !
          EXB = TTINY                                               ! <-- e^{b} too small for being represented
        END IF                                                      !
      END IF                                                        !
!
      Y_MIN  = - 4.0E0_WP                                           !
      Y_MAX  =   4.0E0_WP                                           !
      Y_STEP = (Y_MAX - Y_MIN) / FLOAT(N_I - 1)                     !
!
!  Initialization of integrand function
!
      DO I = 1, N_I                                                 !
        F(I) = TTINY                                                !
      END DO                                                        !
!
!  Computing the integrand function
!
      DO I = 1, N_I                                                 !
!
        Y  = Y_MIN + FLOAT(I - 1) * Y_STEP                          !
        Y2 = Y * Y                                                  !
!
        AY2 = A * Y2                                                ! 
!
!  Evaluation of the exp(Ay^2)
!
        IF(AY2 >= ZERO) THEN                                        !
          IF(AY2 < HALF * MAX_EXP) THEN                             !
            EXA = EXP(AY2)                                          !
          ELSE                                                      !
            EXA = LARGE                                             ! <-- e^{ay^2} too large for being represented
          END IF                                                    !
        ELSE                                                        !
          IF(AY2 > HALF * MIN_EXP) THEN                             !
            EXA = EXP(AY2)                                          !
          ELSE                                                      !
            EXA = TTINY                                             ! <-- e^{ay^2} too small for being represented
          END IF                                                    !
        END IF                                                      !
!
!  Case where calculation is not done 
!
        IF(Y == X) THEN                                             !
          F(I) = LARGE                                              !
          I0   = I                                                  !
          GO TO 10                                                  !
        END IF                                                      !
!
!  Computing the integrand function
!
        NUM = ONE + EXB                                             !
        DEN = (EXA + EXB) * (Y - X)                                 !
!
        F(I) = NUM / DEN                                            !
!
  10    CONTINUE
!
      END DO                                                        !
!
!  Correcting the pathological values
!      through linear interpolation
!
      IF(I0 /= 0) THEN                                              !
        IF(I0 == 1) THEN                                            !
          F(I0) = TWO * F(I0+1) - F(I0+2)                           !
        ELSE IF (I0 == N_I) THEN                                    !
          F(I0) = TWO * F(I0-1) - F(I0-2)                           !
        ELSE                                                        !
          F(I0) = HALF * (F(I0-1) + F(I0+1))                        !
        END IF                                                      !
      END IF                                                        !
!
!  Computing the integral
!
      CALL INTEGR_L(F,Y_STEP,N_I,N_I,INTG,ID)                       !  
!
      END SUBROUTINE INT_XIZ
!
END MODULE SPECIFIC_INT_9
 
