!
!=======================================================================
!
MODULE CLASSICAL_FLUID 
!
      USE ACCURACY_REAL
!
!
CONTAINS
!
!
!=======================================================================
!
      SUBROUTINE CFLUID_3D(R,N0,T,EPS,CF_TYPE,D,LAMBDA,ETA,ZETA) 
!
!  This subroutine computes the self-diffusion, thermal conductivity, 
!    shear viscosity and bulk viscosity of a classical 3D fluid 
!    composed of identical spheres.
!
!  References: (1) O. Kravchenko and M. Thachuk, J. Chem. Phys. 136, 044520 (2012)
!              (2) K. M. Dyer, B. M. Pettitt and G. Stell, J. Chem. Phys. 126,
!                     034502 (2007)
!              (3) J.-M. Bomont and J.-L. Bretonnet, Chem. Phys. 439, 85-94 (2014)
!                        
!
!  Input parameters:
!
!       * R        : sphere's radius (SI) 
!       * N0       : number density of spheres (SI)
!       * T        : temperature (SI)
!       * EPS      : depth of Lennard-Jones potential (SI)
!       * CF_TYPE  : type of classical fluid calculation
!                       CF_TYPE = 'SHS' smooth hard spheres
!                       CF_TYPE = 'RH1' rough hard spheres (Pidduck)
!                       CF_TYPE = 'RH2' rough hard spheres (Condiff-Lu-Dahler)
!                       CF_TYPE = 'RH3' rough hard spheres (McCoy-Sandler-Dahler)
!                       CF_TYPE = 'DCE' dilute Chapman-Enskog
!                       CF_TYPE = 'HCE' heavy (i.e. dense) Chapman-Enskog
!                       CF_TYPE = 'LJF' Lennard-Jones fluid
!
!
!  Note: The Lennard-Jones potential is written as
!
!                                  _                            _
!                                 |  (  2R  )^12     (  2R  )^6  |
!                  V(r) = 4*EPS * |  ( ---- )    -   ( ---- )    |
!                                 |_ (   r  )        (   r  )   _|
!
!
!  Output parameters:
!
!       * D        : (self-)diffusion coefficient
!       * LAMBDA   : thermal conductivity
!       * ETA      : shear viscosity
!       * ZETA     : bulk viscosity
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 10 Jun 2020
!
!
      USE REAL_NUMBERS,     ONLY : ZERO,ONE,TWO,THREE,FOUR,FIVE, &
                                   SIX,SEVEN,EIGHT,NINE,TEN,     &
                                   HALF,THIRD
      USE CONSTANTS_P1,     ONLY : M_E,K_B
      USE PI_ETC,           ONLY : PI,PI_INV
      USE PACKING_FRACTION, ONLY : PACK_FRAC_3D
!
      IMPLICIT NONE
!
      CHARACTER (LEN = 3)   ::  CF_TYPE
!
      REAL (WP)             ::  R,N0,T,EPS
      REAL (WP)             ::  D,LAMBDA,ETA,ZETA
      REAL (WP)             ::  SG,S2,S3,AL,AL2,AL3,AL4
      REAL (WP)             ::  DZ,L0,E0,Z0
      REAL (WP)             ::  K1,K2,NUM,DEN,C0,C1,C2
      REAL (WP)             ::  B,G,BRG,PF
      REAL (WP)             ::  TS,NS,Y,Z
!
      SG=R+R                                                        ! particle diameter
      S2=SG*SG                                                      !
      S3=S2*SG                                                      !
      B=TWO*PI*SG*S2*THIRD                                          ! 2nd virial coefficient
      AL=0.40E0_WP                                                  ! reduced moment of inertia
!                                                                   ! of sphere with uniform mass density
      AL2=AL*AL                                                     !
      AL3=AL2*AL                                                    !
      AL4=AL3*AL                                                    !
!
      K1=DSQRT(K_B*T*PI_INV/M_E)                                    !
      K2=DSQRT(K_B*T*PI_INV*M_E)                                    !
!
!  Computing the packing fraction
!
      PF=PACK_FRAC_3D(N0,SG,'HSM')                                  !
!
!  Carnahan-Starling value of contact value of radial distribution
!
      G=(ONE-HALF*PF) / (ONE-PF)**3                                 ! ref. 1 eq. (32)
!
      BRG=B*N0*G                                                    
!
      IF(CF_TYPE == 'SHS') THEN                                     !
!
        NUM=ONE+AL                                                  !
        DEN=ONE+AL+AL                                               !
        D=THREE*K1/(EIGHT*N0*S2)                                    ! ref. 1 eq. (17) 
!
        NUM=12.0E0_WP * (ONE+AL)**2 * (                           & !
                                       37.0E0_WP + 151.0E0_WP*AL +& !
                                       50.0E0_WP*AL2              & !
                                      )                             !
        DEN=25.0E0_WP*( 12.0E0_WP     +  75.0E0_WP*AL  +          & !
                       101.0E0_WP*AL2 + 102.0E0_WP*AL3            & !
                      )                                             !
        LAMBDA=75.0E0_WP*K_B*K1/(64.0E0_WP*S2)                      ! ref. 1 eq. (18)
!
        NUM=SIX*(ONE+AL)*(ONE+AL)                                   !
        DEN=SIX+13.0E0_WP*AL                                        !
        ETA=FIVE*K2/(16.0E0_WP*S2)                                  ! ref. 1 eq. (19)
!
        ZETA=ZERO                                                   !
!
      ELSE IF(CF_TYPE == 'RH1') THEN                                !
!
        NUM=ONE+AL                                                  !
        DEN=ONE+AL+AL                                               !
        DZ=THREE*K1/(EIGHT*N0*S2)                                   ! 
        D=DZ*NUM/DEN                                                ! ref. 1 eq. (17)
!
        NUM=12.0E0_WP * (ONE+AL)**2 * ( 37.0E0_WP    +            & !
                                       151.0E0_WP*AL +            & ! 
                                        50.0E0_WP*AL2             & !
                                      )                             !
        DEN=25.0E0_WP*( 12.0E0_WP     +  75.0E0_WP*AL  +          & !
                       101.0E0_WP*AL2 + 102.0E0_WP*AL3            & !
                      )                                             !
        L0=75.0E0_WP*K_B*K1/(64.0E0_WP*S2)                          !
        LAMBDA=L0*NUM/DEN                                           ! ref. 1 eq. (18)
!
        NUM=SIX*(ONE+AL)*(ONE+AL)                                   !
        DEN=SIX+13.0E0_WP*AL                                        !
        E0=FIVE*K2/(16.0E0_WP*S2)                                   !
        ETA=E0*NUM/DEN                                              ! ref. 1 eq. (19)
!
        NUM=(ONE+AL)*(ONE+AL)                                       !
        DEN=AL                                                      !
        Z0=K2/(32.0E0_WP*S2)                                        !
        ZETA=Z0*NUM/DEN                                             ! ref. 1 eq. (20)
!
      ELSE IF(CF_TYPE == 'RH2') THEN                                !
!
        NUM=ONE+AL                                                  !
        DEN=ONE+AL+AL                                               !
        DZ=THREE*K1/(EIGHT*N0*S2)                                   ! 
        D=DZ*NUM/DEN                                                ! 
        NUM=PI*AL*(ONE+AL)                                          !
        DEN=TWO*(ONE+AL+AL)*(FIVE+NINE*AL+EIGHT*AL2)                !
        D=D/(ONE + NUM/DEN)                                         ! ref. 1 eq. (21)
!
        NUM=FOUR*(ONE+AL)*( 1121.0E0_WP     +  733.0E0_WP*AL  +   & !
                           13449.0E0_WP*AL2 + 9490.0E0_WP*AL3 +   & !
                           2000.0E0_WP*AL4                        & !
                          )                                         !
        DEN=25.0E0_WP*( 116.0E0_WP     +  853.0E0_WP*AL  +        & !
                       1707.0E0_WP*AL2 + 2266.0E0_WP*AL3 +        & !
                       1360.0E0_WP*AL4                            & !
                      )                                             !
        L0=75.0E0_WP*K_B*K1/(64.0E0_WP*S2)                          !
        LAMBDA=L0*NUM/DEN                                           ! ref. 1 eq. (22)
!
        NUM=TWO*(ONE+AL)*(ONE+AL)*(THREE+TEN*AL)                    !
        DEN=SIX+33.0E0_WP*AL+35.0E0_WP*AL2                          !
        E0=FIVE*K2/(16.0E0_WP*S2)                                   !
        ETA=E0*NUM/DEN                                              ! ref. 1 eq. (23)
!
        NUM=(ONE+AL)*(ONE+AL)                                       !
        DEN=AL                                                      !
        Z0=K2/(32.0E0_WP*S2)                                        !
        ZETA=Z0*NUM/DEN                                             ! ref. 1 eq. (20)
!
      ELSE IF(CF_TYPE == 'RH3') THEN                                !
!
        NUM=ONE+AL                                                  !
        DEN=ONE+AL+AL                                               !
        DZ=THREE*K1/(EIGHT*N0*S2)                                   ! 
        D=DZ*NUM/DEN                                                ! 
        NUM=PI*AL*(ONE+AL)                                          !
        DEN=TWO*(ONE+AL+AL)*(FIVE+NINE*AL+EIGHT*AL2)                !
        D=D/(ONE + NUM/DEN)                                         ! ref. 1 eq. (21)
!
        NUM=FOUR*(ONE+AL)*( 1121.0E0_WP     +  733.0E0_WP*AL  +   & !
                           13449.0E0_WP*AL2 + 9490.0E0_WP*AL3 +   & !
                            2000.0E0_WP*AL4                       & !
                          )                                         !
        DEN=25.0E0_WP*( 116.0E0_WP     +  853.0E0_WP*AL  +        & !
                       1707.0E0_WP*AL2 + 2266.0E0_WP*AL3 +        & !
                       1360.0E0_WP*AL4                            & !
                      )                                             !
        L0=75.0E0_WP*K_B*K1/(64.0E0_WP*S2)                          !
        LAMBDA=L0*NUM/DEN                                           ! ref. 1 eq. (22)
!
        NUM=TWO*( 731.0E0_WP + 4958.0E0_WP*AL  + 8005.0E0_WP*AL2 +& !
                               5650.0E0_WP*AL3 + 2000.0E0_WP*AL4  & !
                )                                                   !
        DEN=1121.0E0_WP + 7336.0E0_WP*AL  + 13449.0E0_WP*AL2 +    & !
                          9490.0E0_WP*AL3 +  2000.0E0_WP*AL4        !
        C1=NUM/DEN                                                  !
!
        C0=501.0E0_WP + 3355.0E0_WP*AL  + 4860.0E0_WP*AL2 +       & !
                        3850.0E0_WP*AL3 + 2000.0E0_WP*AL4           !
        NUM=16.0E0_WP*( 116.0E0_WP     +  853.0E0_WP*AL  +        & !
                       1707.0E0_WP*AL2 + 2266.0E0_WP*AL3 +        & !
                       1360.0E0_WP*AL4                            & !
                      ) * PI_INV/(ONE+AL)                           !
        NUM=C0+NUM                                                  !
        C2=NUM/DEN                                                  !
        LAMBDA=LAMBDA/G * (ONE + C1*BRG + C2*BRG*BRG)               ! ref. 1 eq. (29)
!
        NUM=TWO*(ONE+AL)*(ONE+AL)*(THREE+TEN*AL)                    !
        DEN=SIX+33.0E0_WP*AL+35.0E0_WP*AL2                          !
        E0=FIVE*K2/(16.0E0_WP*S2)                                   !
        ETA=E0*NUM/DEN                                              ! ref. 1 eq. (23)
        C1=0.40E0_WP*(TWO+FIVE*AL)/(ONE+AL)                         !
        NUM=SIX*( SIX + 33.0E0_WP*AL + 35.0E0_WP*AL2              & !
                     ) * (FOUR+SEVEN*AL)                            !
        DEN=PI*(THREE+TEN*AL)*(ONE+AL)                              !
        C2=( (TWO+FIVE*AL)**2 + NUM/DEN ) / (25.0E0_WP*(ONE+AL)**2) !
        ETA=ETA/G * (ONE  + C1*BRG + C2*BRG*BRG)                    ! ref. 1 eq. (26)
!
        NUM=(ONE+AL)*(ONE+AL)                                       !
        DEN=AL                                                      !
        Z0=K2/(32.0E0_WP*S2)                                        !
        ZETA=Z0*NUM/DEN                                             ! ref. 1 eq. (20)
        C1=TWO                                                      !
        C2=ONE + 32.0E0_WP*AL/(PI*(ONE+AL)**2)                      !
        ZETA=ZETA/G * (ONE  + C1*BRG + C2*BRG*BRG)                  ! ref. 1 eq. (27)
!
      ELSE IF(CF_TYPE == 'DCE') THEN                                !
!
        NUM=ONE+AL                                                  !
        DEN=ONE+AL+AL                                               !
        D=1.019E0_WP*THREE*K1/(EIGHT*N0*S2)                         ! ref. 3 eq. (19) 
!
        NUM=12.0E0_WP * (ONE+AL)**2 * (  37.0E0_WP    +           & !
                                        151.0E0_WP*AL +           & !
                                         50.0E0_WP*AL2            & !
                                      )                             !
        DEN=25.0E0_WP*( 12.0E0_WP     +  75.0E0_WP*AL +           & !
                       101.0E0_WP*AL2 + 102.0E0_WP*AL3            & !
                      )                                             !
        LAMBDA=1.025E0_WP*75.0E0_WP*K_B*K1/(64.0E0_WP*S2)           ! ref. 3 eq. (21)
!
        NUM=SIX*(ONE+AL)*(ONE+AL)                                   !
        DEN=SIX+13.0E0_WP*AL                                        !
        ETA=1.016E0_WP*FIVE*K2/(16.0E0_WP*S2)                       ! ref. 3 eq. (20)
!
        ZETA=ZERO                                                   !
!
      ELSE IF(CF_TYPE == 'HCE') THEN                                !
!
        Z=FOUR*PF*G                                                 ! ref. 3 eq. (4)
!
        NUM=ONE+AL                                                  !
        DEN=ONE+AL+AL                                               !
        D=1.019E0_WP*THREE*K1/(EIGHT*N0*S2)                         !
        D=D*FOUR*PF/Z                                               ! ref. 3 eq. (15) 
!
        NUM=12.0E0_WP * (ONE+AL)**2 * ( 37.0E0_WP    +            & !
                                       151.0E0_WP*AL +            & !
                                        50.0E0_WP*AL2             & !
                                      )                             !
        DEN=25.0E0_WP*( 12.0E0_WP     +  75.0E0_WP*AL  +          & !
                       101.0E0_WP*AL2 + 102.0E0_WP*AL3            & !
                      )                                             !
        LAMBDA=1.025E0_WP*75.0E0_WP*K_B*K1/(64.0E0_WP*S2)           !
        LAMBDA=LAMBDA*FOUR*PF*(ONE/Z + 1.2E0_WP + 0.755E0_WP*Z)     ! ref. 3 eq. (18)
!
        NUM=SIX*(ONE+AL)*(ONE+AL)                                   !
        DEN=SIX+13.0E0_WP*AL                                        !
        ETA=1.016E0_WP*FIVE*K2/(16.0E0_WP*S2)                       !
        ETA=ETA*FOUR*PF*(ONE/Z + 0.8E0_WP + 0.761E0_WP*Z)           ! ref. 3 eq. (16)
!
        ZETA=ETA*FOUR*PF*1.002E0_WP*Z                               ! ref. 3 eq. (17)
!
      ELSE IF(CF_TYPE == 'LJF') THEN                                !
!
        TS=K_B*T/EPS                                                ! T*
        NS=N0*S3                                                    ! rho*
        Y=TWO*PI*NS*THIRD                                           !
!
        DZ=0.375E0_WP*DSQRT(TS*PI_INV/M_E)/SG                       !
        D=DZ/(NS*G)                                                 ! ref. 2 eq. (3)
!
        LAMBDA=ZERO                                                 ! not provided
!
        E0=0.3125E0_WP*DSQRT(M_E*TS*PI_INV)/S2                      !
        ETA=E0*(ONE/G + 0.8E0_WP*Y + 0.761E0_WP*Y*Y*G)              ! ref. 2 eq. (4)
!
        ZETA=E0*1.002E0_WP*Y*Y*G                                    !
!
      END IF                                                        !
!
      END SUBROUTINE CFLUID_3D  
!
!=======================================================================
!
      SUBROUTINE CFLUID_2D(R,N0,T,CF_TYPE,D,LAMBDA,ETA,ZETA) 
!
!  This subroutine computes the self-diffusion, thermal conductivity, 
!    shear viscosity and bulk viscosity of a classical 2D fluid 
!    composed of identical spheres.
!
!  References: (1) R. Garcia-Rojo, S. Luding and J. J. Brey, 
!                     Phys. Rev. E 74, 061395 (2006)
!                        
!
!  Input parameters:
!
!       * R        : disks radius (SI) 
!       * N0       : number density of spheres (SI)
!       * T        : temperature (SI)
!       * CF_TYPE  : type of classical fluid calculation
!                       CF_TYPE = 'DHD' dense hard disks
!
!
!  Output parameters:
!
!       * D        : (self-)diffusion coefficient
!       * LAMBDA   : thermal conductivity
!       * ETA      : shear viscosity
!       * ZETA     : bulk viscosity
!
!   Author :  D. Sébilleau
!
!                                           Last modified : 10 Jun 2020
!
!
      USE REAL_NUMBERS,     ONLY : ONE,TWO,THREE,FOUR,SEVEN,  &
                                   EIGHT,NINE,HALF
      USE CONSTANTS_P1,     ONLY : M_E,K_B
      USE PI_ETC,           ONLY : PI_INV
      USE PACKING_FRACTION, ONLY : PACK_FRAC_2D
!
      IMPLICIT NONE
!
      CHARACTER*3 CF_TYPE
!
      REAL (WP)             ::  R,N0,T
      REAL (WP)             ::  K1,K2,SG,PF,G
      REAL (WP)             ::  D,LAMBDA,ETA,ZETA
!
      K1=DSQRT(K_B*T*PI_INV/M_E)                                    !
      K2=DSQRT(K_B*T*PI_INV*M_E)                                    !
!
      SG=R+R                                                        ! particle diameter
!
!  Computing the packing fraction
!
      PF=PACK_FRAC_2D(N0,SG,'HDM')                                  !
!
!  Henderson's value of contact value of radial distribution
!
      G=(ONE -SEVEN*PF/16.0E0_WP) / (ONE-PF)**2                     ! ref. 1 eq. (6)
!
      IF(CF_TYPE == 'DHD') THEN                                     !
        D=HALF*K1 / (N0*SG*G)                                       ! ref. 1 eq. (5)
        LAMBDA=TWO*K_B*K1* (                                       &!
                             ONE/G + THREE*PF +                    &!
                             (NINE/FOUR + FOUR*PI_INV)*G*PF*PF     &! ref. 1 eq. (24)
                           ) / SG                                   !
        ETA=HALF*K2* (                                             &!
                       ONE/G + TWO*PF +                            &!
                       (ONE+EIGHT*PI_INV)*G*PF*PF                  &! ref. 1 eq. (15)
                     )  / SG                                        !
        ZETA=EIGHT*K2*PF*PF*G*PI_INV/SG                             ! ref. 1 eq. (22)
      END IF                                                        !
!
      END SUBROUTINE CFLUID_2D  
!
END MODULE CLASSICAL_FLUID
