eos_gas.F90       coverage:  61.11 %func     47.32 %block


     1) module EOS_Gas_module
     2)  
     3)   use PFLOTRAN_Constants_module
     4) 
     5)   implicit none
     6) 
     7)   private
     8)   
     9) #include "petsc/finclude/petscsys.h"
    10) 
    11)   ! module variables
    12)   PetscReal :: constant_density
    13)   PetscReal :: constant_enthalpy
    14)   PetscReal :: constant_viscosity
    15)   PetscReal :: constant_henry
    16)   PetscBool :: hydrogen
    17)   PetscReal :: Tc
    18)   PetscReal :: Pc
    19)   PetscReal :: acentric
    20)   PetscReal :: coeff_a
    21)   PetscReal :: coeff_b
    22)   
    23)   ! exponential
    24)   PetscReal :: exponent_reference_density
    25)   PetscReal :: exponent_reference_pressure
    26)   PetscReal :: exponent_gas_compressibility
    27) 
    28)   ! This is the offset added to temperature [C] used to calculate the energy
    29)   ! equation of state.  Swithing between 0. and 273.15 greatly changes results.
    30) #if defined(MATCH_TOUGH2)
    31)   PetscReal, parameter :: T_energy_offset = 0.d0
    32) #else
    33)   PetscReal, parameter :: T_energy_offset = 273.15d0
    34) #endif
    35) 
    36)   ! In order to support generic EOS subroutines, we need the following:
    37)   ! 1. An interface declaration that defines the argument list (best to have 
    38)   !    "Dummy" appended.
    39)   ! 2. A procedure pointer that is initially set to null.  This pointer is
    40)   !    pointed to the appropriate subroutine later on (e.g. EOSGasInit())
    41)   ! 3. An interface for derivative/non-derivative versions
    42) 
    43)   ! procedure pointer declarations
    44)   procedure(EOSGasViscosityDummy), pointer :: EOSGasViscosityPtr => null()
    45)   procedure(EOSGasDensityEnergyDummy), pointer :: &
    46)     EOSGasDensityEnergyPtr => null()
    47)   procedure(EOSGasDensityDummy), pointer :: EOSGasDensityPtr => null()
    48)   procedure(EOSGasEnergyDummy), pointer :: EOSGasEnergyPtr => null()
    49)   procedure(EOSGasHenryDummy), pointer :: EOSGasHenryPtr => null()
    50)   
    51)   ! interface blocks
    52)   interface
    53)     subroutine EOSGasViscosityDummy(T, P_comp, P_gas, Rho_comp, V_mix, ierr)
    54)       implicit none
    55)       PetscReal, intent(in) :: T        ! temperature [C]
    56)       PetscReal, intent(in) :: P_comp   ! air pressure [Pa]
    57)       PetscReal, intent(in) :: P_gas    ! gas pressure [Pa]
    58)       PetscReal, intent(in) :: Rho_comp ! air density [C]
    59)       PetscReal, intent(out) :: V_mix   ! mixture viscosity
    60)       PetscErrorCode, intent(out) :: ierr
    61)     end subroutine EOSGasViscosityDummy
    62)     subroutine EOSGasDensityDummy(T,P,Rho_gas,dRho_dT,dRho_dP,ierr)
    63)       implicit none
    64)       PetscReal, intent(in) :: T        ! temperature [C]
    65)       PetscReal, intent(in) :: P        ! pressure [Pa]
    66)       PetscReal, intent(out) :: Rho_gas ! gas density [kmol/m^3]
    67)       PetscReal, intent(out) :: dRho_dT ! derivative gas density wrt temperature
    68)       PetscReal, intent(out) :: dRho_dP ! derivative gas density wrt pressuret
    69)       PetscErrorCode, intent(out) :: ierr
    70)     end subroutine EOSGasDensityDummy
    71)     subroutine EOSGasEnergyDummy(T,P,H,dH_dT,dH_dP,U,dU_dT,dU_dP,ierr)
    72)       implicit none
    73)       PetscReal, intent(in) :: T        ! temperature [C]
    74)       PetscReal, intent(in) :: P        ! pressure [Pa]
    75)       PetscReal, intent(out) :: H       ! enthalpy [J/kmol]
    76)       PetscReal, intent(out) :: dH_dT   ! derivative enthalpy wrt temperature
    77)       PetscReal, intent(out) :: dH_dP   ! derivative enthalpy wrt pressure
    78)       PetscReal, intent(out) :: U       ! internal energy [J/kmol]
    79)       PetscReal, intent(out) :: dU_dT   ! deriv. internal energy wrt temperature
    80)       PetscReal, intent(out) :: dU_dP   ! deriv. internal energy wrt pressure
    81)       PetscErrorCode, intent(out) :: ierr
    82)     end subroutine EOSGasEnergyDummy
    83)     subroutine EOSGasDensityEnergyDummy(T,P,Rho_gas,dRho_dT,dRho_dP, &
    84)                                         H,dH_dT,dH_dP,U,dU_dT,dU_dP,ierr)
    85)       implicit none
    86)       PetscReal, intent(in) :: T        ! temperature [C]
    87)       PetscReal, intent(in) :: P        ! pressure [Pa]
    88)       PetscReal, intent(out) :: Rho_gas ! gas density [kmol/m^3]
    89)       PetscReal, intent(out) :: dRho_dT ! derivative gas density wrt temperature
    90)       PetscReal, intent(out) :: dRho_dP ! derivative gas density wrt pressuret
    91)       PetscReal, intent(out) :: H       ! enthalpy [J/kmol]
    92)       PetscReal, intent(out) :: dH_dT   ! derivative enthalpy wrt temperature
    93)       PetscReal, intent(out) :: dH_dP   ! derivative enthalpy wrt pressure
    94)       PetscReal, intent(out) :: U       ! internal energy [J/kmol]
    95)       PetscReal, intent(out) :: dU_dT   ! deriv. internal energy wrt temperature
    96)       PetscReal, intent(out) :: dU_dP   ! deriv. internal energy wrt pressure
    97)       PetscErrorCode, intent(out) :: ierr
    98)     end subroutine EOSGasDensityEnergyDummy
    99)     subroutine EOSGasHenryDummy(T,Psat,Hc)
   100)       implicit none
   101)       PetscReal, intent(in) :: T        ! temperature [C]
   102)       PetscReal, intent(in) :: Psat     ! saturation pressure
   103)       PetscReal, intent(out) :: Hc      ! Henry's constant
   104)     end subroutine EOSGasHenryDummy
   105)   end interface
   106)   
   107)   ! interfaces for derivative/non-derivative versions that are visible outside
   108)   ! the module.
   109)   interface EOSGasViscosity
   110)     procedure EOSGasViscosityNoDerive
   111) !    procedure EOSGasViscosityDerive
   112)   end interface
   113)   interface EOSGasDensity
   114)     procedure EOSGasDensityNoDerive
   115)     procedure EOSGasDensityDerive
   116)   end interface
   117)   interface EOSGasEnergy
   118)     procedure EOSGasEnergyNoDerive
   119)     procedure EOSGasEnergyDerive
   120)   end interface
   121)   interface EOSGasDensityEnergy
   122)     procedure EOSGasDenEnthNoDerive
   123)     procedure EOSGasDenEnthDerive
   124)   end interface
   125)   interface EOSGasHenry
   126)     procedure EOSGasHenryNoDerive
   127) !    procedure EOSGasHenryDerive
   128)   end interface
   129) 
   130)   ! the "public" definition that makes subroutines visible outside.
   131)   public :: EOSGasInit, &
   132)             EOSGasVerify, &
   133)             EOSGasViscosity, &
   134)             EOSGasDensity, &
   135)             EOSGasEnergy, &
   136)             EOSGasDensityEnergy, &
   137)             EOSGasHenry, &
   138)             EOSGasInputRecord, &
   139)             EOSGasTest
   140)             
   141)   public :: EOSGasSetDensityIdeal, &
   142)             EOSGasSetEnergyIdeal, &
   143)             EOSGasSetDensityRKS, &
   144)             EOSGasSetDensityPRMethane, &
   145)             EOSGasSetEnergyIdealMethane, &
   146)             EOSGasSetDensityConstant, &
   147)             EOSGasSetEnergyConstant, &
   148)             EOSGasSetViscosityConstant, &
   149)             EOSGasSetHenry, &
   150)             EOSGasSetHenryConstant
   151)  
   152)   contains
   153) 
   154) ! ************************************************************************** !
   155) 
   156) subroutine EOSGasInit()
   157) 
   158)   implicit none
   159)   
   160)   constant_density = UNINITIALIZED_DOUBLE
   161)   constant_viscosity = UNINITIALIZED_DOUBLE
   162)   constant_enthalpy = UNINITIALIZED_DOUBLE
   163)   constant_henry = UNINITIALIZED_DOUBLE
   164) 
   165)   EOSGasDensityEnergyPtr => EOSGasDensityEnergyGeneral
   166)   EOSGasDensityPtr => EOSGasDensityIdeal
   167)   EOSGasEnergyPtr => EOSGasEnergyIdeal
   168)   EOSGasViscosityPtr => EOSGasViscosity1
   169)   EOSGasHenryPtr => EOSGasHenry_air_noderiv
   170)   
   171) end subroutine EOSGasInit
   172) 
   173) ! ************************************************************************** !
   174) 
   175) subroutine EOSGasVerify(ierr,error_string)
   176) 
   177)   implicit none
   178)   
   179)   PetscErrorCode, intent(out) :: ierr
   180)   character(len=MAXSTRINGLENGTH), intent(out) :: error_string
   181)   
   182)   ierr = 0
   183)   
   184)   error_string = ''
   185)   if ((associated(EOSGasDensityPtr,EOSGasDensityIdeal) .and. &
   186)         Initialized(constant_density)) .or. &
   187)       (associated(EOSGasDensityPtr,EOSGasDensityRKS) .and. &
   188)         Initialized(constant_density)) .or. &
   189)       (associated(EOSGasEnergyPtr,EOSGasEnergyIdeal) .and. &
   190)         Initialized(constant_enthalpy)) &
   191)      ) then
   192)     ierr = 1
   193)   endif
   194) 
   195)   if (associated(EOSGasDensityPtr,EOSGasDensityConstant) .and. &
   196)       Uninitialized(constant_density)) then
   197)     error_string = trim(error_string) // &
   198)       ' CONSTANT density not set.'
   199)     ierr = 1
   200)   endif
   201)   
   202)   if (associated(EOSGasEnergyPtr,EOSGasEnergyConstant) .and. &
   203)       Uninitialized(constant_enthalpy)) then
   204)     error_string = trim(error_string) // &
   205)       ' CONSTANT enthalpy not set.'
   206)     ierr = 1
   207)   endif
   208)   
   209)   if ((associated(EOSGasViscosityPtr, &
   210)                   EOSGasViscosityConstant) .and. &
   211)        Uninitialized(constant_viscosity)) .or. &
   212)       (associated(EOSGasViscosityPtr, &
   213)                   EOSGasViscosity1) .and. &
   214)        Initialized(constant_viscosity))) then
   215)     ierr = 1
   216)   endif
   217)   
   218)   if (associated(EOSGasHenryPtr, &
   219)                  EOSGasHenryConstant) .and. &
   220)       Uninitialized(constant_henry)) then
   221)     error_string = trim(error_string) // " Henry's constant not set"
   222)     ierr = 1
   223)   endif
   224)   
   225)   if (associated(EOSGasDensityPtr,EOSGasDensityRKS)) then
   226)     if (hydrogen) then
   227)       ! Assign default hydrogen parameters if not assigned
   228)       if (Uninitialized(Tc)) then
   229)         Tc = 41.67d0
   230)         ierr = 5
   231)         error_string = trim(error_string) // " Tc"
   232)       endif
   233)       if (Uninitialized(Pc)) then
   234)         Pc = 2.1029d6
   235)         ierr = 5
   236)         error_string = trim(error_string) // " Pc"
   237)       endif
   238)       if (Uninitialized(coeff_a)) then
   239)         coeff_a = 0.42747d0
   240)         ierr = 5
   241)         error_string = trim(error_string) // " omega_a"
   242)       endif
   243)       if (Uninitialized(coeff_b)) then
   244)         coeff_b = 0.08664d0
   245)         ierr = 5
   246)         error_string = trim(error_string) // " omega_b"
   247)       endif
   248)     else
   249)       if (Uninitialized(Tc) .or. Uninitialized(coeff_a) .or. &
   250)         Uninitialized(Pc) .or. Uninitialized(coeff_b) .or. &
   251)         Uninitialized(acentric)) then
   252)           error_string = trim(error_string) // &
   253)           " RKS parameters not set for non-hydrogen gas"
   254)           ierr = 1
   255)       endif
   256)     endif
   257)   endif
   258) 
   259)       
   260) end subroutine EOSGasVerify
   261) 
   262) ! ************************************************************************** !
   263) 
   264) subroutine EOSGasSetDensityIdeal()
   265) 
   266)   implicit none
   267)   
   268)   EOSGasDensityEnergyPtr => EOSGasDensityEnergyGeneral
   269)   EOSGasDensityPtr => EOSGasDensityIdeal
   270)   
   271) end subroutine EOSGasSetDensityIdeal
   272) 
   273) ! ************************************************************************** !
   274) 
   275) subroutine EOSGasSetDensityRKS(h,rks_tc,rks_pc,rks_acen,rks_omegaa,rks_omegab)
   276) 
   277)   implicit none
   278) 
   279)   PetscBool :: h
   280)   PetscReal :: rks_tc
   281)   PetscReal :: rks_pc
   282)   PetscReal :: rks_acen
   283)   PetscReal :: rks_omegaa
   284)   PetscReal :: rks_omegab
   285)   
   286)   hydrogen = h
   287)   Tc = rks_tc
   288)   Pc = rks_pc
   289)   acentric = rks_acen
   290)   coeff_a = rks_omegaa
   291)   coeff_b = rks_omegab
   292)   
   293)   EOSGasDensityEnergyPtr => EOSGasDensityEnergyGeneral
   294)   EOSGasDensityPtr => EOSGasDensityRKS
   295)   
   296) end subroutine EOSGasSetDensityRKS
   297) 
   298) ! ************************************************************************** !
   299) 
   300) subroutine EOSGasSetDensityPRMethane()
   301) 
   302)   implicit none
   303)   
   304)   EOSGasDensityEnergyPtr => EOSGasDensityEnergyGeneral
   305)   EOSGasDensityPtr => EOSGasDensityPRMethane
   306)   
   307) end subroutine EOSGasSetDensityPRMethane
   308) 
   309) ! ************************************************************************** !
   310) 
   311) subroutine EOSGasSetEnergyIdeal()
   312) 
   313)   implicit none
   314)   
   315)   EOSGasDensityEnergyPtr => EOSGasDensityEnergyGeneral
   316)   EOSGasEnergyPtr => EOSGasEnergyIdeal
   317)   
   318) end subroutine EOSGasSetEnergyIdeal
   319) 
   320) ! ************************************************************************** !
   321) 
   322) subroutine EOSGasSetEnergyIdealMethane()
   323) 
   324)   implicit none
   325)   
   326)   EOSGasDensityEnergyPtr => EOSGasDensityEnergyGeneral
   327)   EOSGasEnergyPtr => EOSGasEnergyIdealMethane
   328)   
   329) end subroutine EOSGasSetEnergyIdealMethane
   330) 
   331) ! ************************************************************************** !
   332) 
   333) subroutine EOSGasSetDensityConstant(density)
   334) 
   335)   implicit none
   336)   
   337)   PetscReal :: density
   338)   
   339)   constant_density = density  
   340)   EOSGasDensityEnergyPtr => EOSGasDensityEnergyGeneral
   341)   EOSGasDensityPtr => EOSGasDensityConstant
   342)   
   343) end subroutine EOSGasSetDensityConstant
   344) 
   345) ! ************************************************************************** !
   346) 
   347) subroutine EOSGasSetEnergyConstant(enthalpy)
   348) 
   349)   implicit none
   350)   
   351)   PetscReal :: enthalpy
   352)   
   353)   constant_enthalpy = enthalpy  
   354)   EOSGasDensityEnergyPtr => EOSGasDensityEnergyGeneral
   355)   EOSGasEnergyPtr => EOSGasEnergyConstant
   356)   
   357) end subroutine EOSGasSetEnergyConstant
   358) 
   359) ! ************************************************************************** !
   360) 
   361) subroutine EOSGasSetViscosityConstant(viscosity)
   362) 
   363)   implicit none
   364)   
   365)   PetscReal :: viscosity
   366)   
   367)   constant_viscosity = viscosity  
   368)   EOSGasViscosityPtr => EOSGasViscosityConstant
   369)   
   370) end subroutine EOSGasSetViscosityConstant
   371) 
   372) ! ************************************************************************** !
   373) 
   374) subroutine EOSGasSetHenry()
   375) 
   376)   implicit none
   377)   
   378)   EOSGasHenryPtr => EOSGasHenry_air_noderiv
   379)   
   380) end subroutine EOSGasSetHenry
   381) 
   382) ! ************************************************************************** !
   383) 
   384) subroutine EOSGasSetHenryConstant(henrys_constant)
   385) 
   386)   implicit none
   387)   
   388)   PetscReal :: henrys_constant
   389)   
   390)   constant_henry = henrys_constant
   391)   EOSGasHenryPtr => EOSGasHenryConstant
   392)   
   393) end subroutine EOSGasSetHenryConstant
   394) 
   395) ! ************************************************************************** !
   396) 
   397) subroutine EOSGasViscosityNoDerive(T, P_comp, P_gas, Rho_comp, V_mix, ierr)
   398) 
   399)   implicit none
   400) 
   401)   PetscReal, intent(in) :: T        ! temperature [C]
   402)   PetscReal, intent(in) :: P_comp   ! air pressure [Pa]
   403)   PetscReal, intent(in) :: P_gas    ! gas pressure [Pa]
   404)   PetscReal, intent(in) :: Rho_comp ! air density [C]
   405)   PetscReal, intent(out) :: V_mix   ! mixture viscosity
   406)   PetscErrorCode, intent(out) :: ierr
   407)   
   408)   call EOSGasViscosityPtr(T, P_comp, P_gas, Rho_comp, V_mix, ierr)
   409)   
   410) end subroutine EOSGasViscosityNoDerive
   411) 
   412) ! ************************************************************************** !
   413) #if 0
   414) subroutine EOSGasViscosityDerive(T, P_comp, P_gas, Rho_comp, V_mix, ierr)
   415) 
   416)   implicit none
   417) 
   418)   PetscReal, intent(in) :: T        ! temperature [C]
   419)   PetscReal, intent(in) :: P_comp   ! air pressure [Pa]
   420)   PetscReal, intent(in) :: P_gas    ! gas pressure [Pa]
   421)   PetscReal, intent(in) :: Rho_comp ! air density [C]
   422)   PetscReal, intent(out) :: V_mix   ! mixture viscosity
   423)   PetscErrorCode, intent(out) :: ierr
   424)  
   425)   ! not yet supported
   426)   print *, 'EOSGasViscosityDerive() not yet supported.'
   427)   stop
   428)   
   429) end subroutine EOSGasViscosityDerive
   430) #endif
   431) 
   432) ! ************************************************************************** !
   433) 
   434) subroutine EOSGasViscosity1(T, P_comp, P_gas, Rho_comp, V_mix, ierr)
   435) 
   436)   implicit none
   437) 
   438)   PetscReal, intent(in) :: T        ! temperature [C]
   439)   PetscReal, intent(in) :: P_comp   ! air pressure [Pa]
   440)   PetscReal, intent(in) :: P_gas    ! gas pressure [Pa]
   441)   PetscReal, intent(in) :: Rho_comp ! air density [C]
   442)   PetscReal, intent(out) :: V_mix   ! mixture viscosity
   443)   PetscErrorCode, intent(out) :: ierr
   444)   
   445)   !geh: copied from gas_eos_mod.F90
   446)   !
   447)   ! REFERENCES
   448)   ! THIS ROUTINE IS LARGELY ADAPTED FROM THE TOUGH CODE.
   449)   ! this routine computes the viscosity of vapor-air mixtures.
   450)   ! it uses a modified version of a formulation based on kinetic
   451)   ! gas theory, as given by j.o. hirschfelder, c.f. curtiss, and
   452)   ! r.b. bird, molecular theory of gases and liquids, john wiley
   453)   ! & sons, 1954, pp. 528-530.
   454)   ! the modification made to the hirschfelder et al. expressions is
   455)   ! that for vapor viscosity accurate (empirical) values are used,
   456)   ! rather than the first order expression of kinetic theory.
   457)   ! the formulation matches experimental data on viscosities of
   458)   ! vapor-air mixtures in the temperature range from 100 to 150
   459)   ! deg. c, for all compositions, to better than 4%.
   460)   ! 
   461)   !PetscReal, intent(in) :: t     ! [C]
   462)   !PetscReal, intent(in) :: p_air ! [Pa]
   463)   !PetscReal, intent(in) :: p_gas ! [Pa]
   464)   !PetscReal, intent(in) :: d_air ! [kmol/m^3]
   465)   !PetscReal, intent(out) :: visg ! [Pa-s]
   466) 
   467)   PetscReal ::  fair,fwat,cair,cwat
   468)   PetscReal :: p_air, d_air, visg
   469) 
   470)   data  fair,   fwat,    cair,  cwat &
   471)         /97.d0, 363.d0, 3.617d0, 2.655d0/
   472)  
   473)   PetscReal fmix,cmix,d,xga,xg1,tk,trd1,trd3,ome1,ome3,ard,fmw3,vis1, &
   474)           v1,vs,vis2,vis3,z1,g,h,e,z2,z3
   475) 
   476) 
   477) !c======================================================================
   478) 
   479)   p_air = P_comp
   480)   d_air = Rho_comp
   481)           
   482)   fmix = sqrt (fair*fwat)
   483)   cmix = (cair+cwat)*0.5d0
   484) 
   485) !      do k = 1,nb
   486) !       if (iphas(k).eq.2 .or. iphas(k).eq.0) then
   487) 
   488)       d   = d_air *FMWAIR       
   489)       xga = p_air / p_gas ! for debug, set x constant
   490)       xg1 = 1.D0 - xga
   491)       tk  = t +273.15d0
   492) 
   493)       trd1 = tk/fair
   494)       trd3 = tk/fmix
   495)       ome1 = (1.188d0-0.051d0*trd1)/trd1
   496)       ome3 = (1.480d0-0.412d0*log(trd3))/trd3
   497)       ard  = 1.095d0/trd3
   498)       fmw3 = 2.d0*FMWAIR*FMWH2O/(FMWAIR+FMWH2O)
   499)       vis1 = 266.93d-7*sqrt(FMWAIR*trd1*fair)/(cair*cair*ome1*trd1)
   500)  
   501)       v1 = .407d0*t +80.4d0
   502)       if (t .le.350.d0) then
   503)         vs = 1.d-7*(v1-d*(1858.d0-5.9d0*t )*1.d-3)
   504)       else
   505) !             if (t .gt.350.d0) 
   506) !cpcl .      vs = 1.d-7*(v1 + 0.353d0*d + 676.5d-6*d**2 + 102.1d-9*d**3)
   507)         vs = 1.d-7*(v1 + (0.353d0 + (676.5d-6 + 102.1d-9*d)*d)*d)
   508)       endif
   509) 
   510)       vis2 = 10.d0*vs
   511)       vis3 = 266.93d-7*sqrt(fmw3*trd3*fmix)/(cmix*cmix*ome3*trd3)
   512)       z1   = xga*xga/vis1+2.d0*xg1*xga/vis3+xg1*xg1/vis2
   513)       g    = xga*xga*FMWAIR/FMWH2O
   514)       h    = xg1*xg1*FMWH2O/FMWAIR
   515)       e    = (2.d0*xga*xg1*FMWAIR*FMWH2O/fmw3**2)*vis3/(vis1*vis2)
   516)       z2   = 0.6d0*ard*(g/vis1+e+h/vis2)
   517)       z3   = 0.6d0*ard*(g+e*(vis1+vis2)-2.d0*xga*xg1+h)
   518)       visg  = (1.d0+z3)/(z1+z2)*.1d0 
   519)       
   520)   V_mix = visg
   521)   
   522) end subroutine EOSGasViscosity1
   523) 
   524) ! ************************************************************************** !
   525) 
   526) subroutine EOSGasViscosityConstant(T, P_comp, P_gas, Rho_comp, V_mix, ierr)
   527) 
   528)   implicit none
   529) 
   530)   PetscReal, intent(in) :: T        ! temperature [C]
   531)   PetscReal, intent(in) :: P_comp   ! air pressure [Pa]
   532)   PetscReal, intent(in) :: P_gas    ! gas pressure [Pa]
   533)   PetscReal, intent(in) :: Rho_comp ! air density [C]
   534)   PetscReal, intent(out) :: V_mix   ! mixture viscosity
   535)   PetscErrorCode, intent(out) :: ierr
   536) 
   537)   V_mix = constant_viscosity
   538)   
   539) end subroutine EOSGasViscosityConstant
   540) 
   541) ! ************************************************************************** !
   542) 
   543) subroutine EOSGasDensityNoDerive(T,P,Rho_gas,ierr)
   544) 
   545)   implicit none
   546) 
   547)   PetscReal, intent(in) :: T        ! temperature [C]
   548)   PetscReal, intent(in) :: P        ! pressure [Pa]
   549)   PetscReal, intent(out) :: Rho_gas ! gas density [kmol/m^3]
   550)   PetscErrorCode, intent(out) :: ierr
   551)   
   552)   PetscReal :: dum1, dum2
   553)   
   554)   ! derivatives are so cheap, just compute them
   555)   call EOSGasDensityPtr(T,P,Rho_gas,dum1,dum2,ierr)
   556)   
   557) end subroutine EOSGasDensityNoDerive
   558) 
   559) ! ************************************************************************** !
   560) 
   561) subroutine EOSGasDensityDerive(T,P,Rho_gas,dRho_dT,dRho_dP,ierr)
   562) 
   563)   implicit none
   564) 
   565)   PetscReal, intent(in) :: T        ! temperature [C]
   566)   PetscReal, intent(in) :: P        ! pressure [Pa]
   567)   PetscReal, intent(out) :: Rho_gas ! gas density [kmol/m^3]
   568)   PetscReal, intent(out) :: dRho_dT ! derivative gas density wrt temperature
   569)   PetscReal, intent(out) :: dRho_dP ! derivative gas density wrt pressure
   570)   PetscErrorCode, intent(out) :: ierr
   571)   
   572)   call EOSGasDensityPtr(T,P,Rho_gas,dRho_dT,dRho_dP,ierr)
   573)                           
   574) end subroutine EOSGasDensityDerive
   575) 
   576) ! ************************************************************************** !
   577) 
   578) subroutine EOSGasEnergyNoDerive(T,P,H,U,ierr)
   579) 
   580)   implicit none
   581)   
   582)   PetscReal, intent(in) :: T        ! temperature [C]
   583)   PetscReal, intent(in) :: P        ! pressure [Pa]
   584)   PetscReal, intent(out) :: H       ! enthalpy [J/kmol]
   585)   PetscReal, intent(out) :: U       ! internal energy [J/kmol]
   586)   PetscErrorCode, intent(out) :: ierr
   587)   
   588)   PetscReal :: dum1, dum2, dum3, dum4
   589)   
   590)   call EOSGasEnergyPtr(T,P,H,dum1,dum2,U,dum3,dum4,ierr)
   591)   
   592) end subroutine EOSGasEnergyNoDerive
   593) 
   594) ! ************************************************************************** !
   595) 
   596) subroutine EOSGasEnergyDerive(T,P,H,dH_dT,dH_dP,U,dU_dT,dU_dP,ierr)
   597)     
   598)   implicit none
   599) 
   600)   PetscReal, intent(in) :: T        ! temperature [C]
   601)   PetscReal, intent(in) :: P        ! pressure [Pa]
   602)   PetscReal, intent(out) :: H       ! enthalpy [J/kmol]
   603)   PetscReal, intent(out) :: dH_dT   ! derivative enthalpy wrt temperature
   604)   PetscReal, intent(out) :: dH_dP   ! derivative enthalpy wrt pressure
   605)   PetscReal, intent(out) :: U       ! internal energy [J/kmol]
   606)   PetscReal, intent(out) :: dU_dT   ! deriv. internal energy wrt temperature
   607)   PetscReal, intent(out) :: dU_dP   ! deriv. internal energy wrt pressure
   608)   PetscErrorCode, intent(out) :: ierr
   609)   
   610)   call EOSGasEnergyPtr(T,P,H,dH_dT,dH_dP,U,dU_dT,dU_dP,ierr)
   611)   
   612) end subroutine EOSGasEnergyDerive
   613) 
   614) ! ************************************************************************** !
   615) 
   616) subroutine EOSGasDenEnthNoDerive(T,P,Rho_gas,H,U,ierr)
   617) 
   618)   implicit none
   619) 
   620)   PetscReal, intent(in) :: T        ! temperature [C]
   621)   PetscReal, intent(in) :: P        ! pressure [Pa]
   622)   PetscReal, intent(out) :: Rho_gas ! gas density [kmol/m^3]
   623)   PetscReal, intent(out) :: H       ! enthalpy [J/kmol]
   624)   PetscReal, intent(out) :: U       ! internal energy [J/kmol]
   625)   PetscErrorCode, intent(out) :: ierr
   626)   
   627)   PetscReal :: dum1, dum2, dum3, dum4, dum5, dum6
   628)   
   629)   call EOSGasDensityEnergyPtr(T,P,Rho_gas,dum1,dum2, &
   630)                               H,dum3,dum4,U,dum5,dum6,ierr)
   631)   
   632) end subroutine EOSGasDenEnthNoDerive
   633) 
   634) ! ************************************************************************** !
   635) 
   636) subroutine EOSGasDenEnthDerive(T,P,Rho_gas,dRho_dT,dRho_dP, &
   637)                                H,dH_dT,dH_dP,U,dU_dT,dU_dP,ierr)
   638) 
   639)   implicit none
   640) 
   641)   PetscReal, intent(in) :: T        ! temperature [C]
   642)   PetscReal, intent(in) :: P        ! pressure [Pa]
   643)   PetscReal, intent(out) :: Rho_gas ! gas density [kmol/m^3]
   644)   PetscReal, intent(out) :: dRho_dT ! derivative gas density wrt temperature
   645)   PetscReal, intent(out) :: dRho_dP ! derivative gas density wrt pressuret
   646)   PetscReal, intent(out) :: H       ! enthalpy [J/kmol]
   647)   PetscReal, intent(out) :: dH_dT   ! derivative enthalpy wrt temperature
   648)   PetscReal, intent(out) :: dH_dP   ! derivative enthalpy wrt pressure
   649)   PetscReal, intent(out) :: U       ! internal energy [J/kmol]
   650)   PetscReal, intent(out) :: dU_dT   ! deriv. internal energy wrt temperature
   651)   PetscReal, intent(out) :: dU_dP   ! deriv. internal energy wrt pressure
   652)   PetscErrorCode, intent(out) :: ierr
   653)   
   654)   call EOSGasDensityEnergyPtr(T,P,Rho_gas,dRho_dT,dRho_dP, &
   655)                               H,dH_dT,dH_dP,U,dU_dT,dU_dP,ierr)
   656)   
   657) end subroutine EOSGasDenEnthDerive
   658) 
   659) ! ************************************************************************** !
   660) 
   661) subroutine EOSGasDensityEnergyGeneral(T,P,Rho_gas,dRho_dT,dRho_dP, &
   662)                                       H,dH_dT,dH_dP,U,dU_dT,dU_dP,ierr)
   663)                                       
   664)   implicit none
   665)   
   666)   PetscReal, intent(in) :: T        ! temperature [C]
   667)   PetscReal, intent(in) :: P        ! pressure [Pa]
   668)   PetscReal, intent(out) :: Rho_gas ! gas density [kmol/m^3]
   669)   PetscReal, intent(out) :: dRho_dT ! derivative gas density wrt temperature
   670)   PetscReal, intent(out) :: dRho_dP ! derivative gas density wrt pressuret
   671)   PetscReal, intent(out) :: H       ! enthalpy [J/kmol]
   672)   PetscReal, intent(out) :: dH_dT   ! derivative enthalpy wrt temperature
   673)   PetscReal, intent(out) :: dH_dP   ! derivative enthalpy wrt pressure
   674)   PetscReal, intent(out) :: U       ! internal energy [J/kmol]
   675)   PetscReal, intent(out) :: dU_dT   ! deriv. internal energy wrt temperature
   676)   PetscReal, intent(out) :: dU_dP   ! deriv. internal energy wrt pressure
   677)   PetscErrorCode, intent(out) :: ierr
   678)   
   679)   call EOSGasDensityPtr(T,P,Rho_gas,dRho_dT,dRho_dP,ierr)
   680)   call EOSGasEnergyPtr(T,P,H,dH_dT,dH_dP,U,dU_dT,dU_dP,ierr)  
   681)   
   682) end subroutine EOSGasDensityEnergyGeneral
   683) 
   684) ! ************************************************************************** !
   685) 
   686) subroutine EOSGasDensityIdeal(T,P,Rho_gas,dRho_dT,dRho_dP,ierr)
   687) 
   688)   implicit none
   689) 
   690)   PetscReal, intent(in) :: T        ! temperature [C]
   691)   PetscReal, intent(in) :: P        ! pressure [Pa]
   692)   PetscReal, intent(out) :: Rho_gas ! gas density [kmol/m^3]
   693)   PetscReal, intent(out) :: dRho_dT ! derivative gas density wrt temperature
   694)   PetscReal, intent(out) :: dRho_dP ! derivative gas density wrt pressure
   695)   PetscErrorCode, intent(out) :: ierr
   696) 
   697)   PetscReal  T_kelvin
   698) 
   699)   T_kelvin = T + 273.15d0
   700)   Rho_gas = P / T_kelvin / IDEAL_GAS_CONSTANT * 1.d-3 ! mol/m^3 -> kmol/m^3
   701) 
   702)   dRho_dP =  Rho_gas / P
   703)   dRho_dT = -Rho_gas / T_kelvin
   704) 
   705) end subroutine EOSGasDensityIdeal
   706) 
   707) ! ************************************************************************** !
   708) 
   709) subroutine EOSGasDensityRKS(T,P,Rho_gas,dRho_dT,dRho_dP,ierr)
   710) ! Redlich-Kwong-Soave (RKS) equation of state used in BRAGFLO.  See
   711) ! Soave, Giorgio, 1972, "Equilibrium constants from a modified Redlich-Kwong
   712) ! equation of state", Chem. Eng. Sci., V27, pp 1197-1203.
   713) ! current version is for hydrogen only.
   714) !
   715) ! Author: Heeho Park
   716) ! Date: 05/08/14
   717) !
   718)   use PFLOTRAN_Constants_module, only : UNINITIALIZED_DOUBLE
   719) 
   720)   implicit none
   721) 
   722)   PetscReal, intent(in) :: T        ! temperature [C]
   723)   PetscReal, intent(in) :: P        ! pressure [Pa]
   724)   PetscReal, intent(out) :: Rho_gas ! gas density [kmol/m^3]
   725)   PetscReal, intent(out) :: dRho_dT ! derivative gas density wrt temperature
   726)   PetscReal, intent(out) :: dRho_dP ! derivative gas density wrt pressure
   727)   PetscErrorCode, intent(out) :: ierr
   728)   
   729)   PetscReal :: T_kelvin, RT, alpha, a, B , a_RT, p_RT
   730)   PetscReal :: b2, V, f, dfdV, dVd
   731)   PetscInt :: i
   732)   PetscReal :: coeff_alpha
   733)   
   734)   !for hydrogen
   735)   ! American Petroleum Institute,
   736)   ! "Technical Data Book-Petroleum Refining" (1977)
   737)   
   738)   !solver
   739)   PetscReal :: coef(4)
   740)   PetscInt, parameter :: maxit = 50
   741)   dRho_dT = UNINITIALIZED_DOUBLE
   742)   dRho_dP = UNINITIALIZED_DOUBLE
   743)   
   744)   T_kelvin = T + 273.15d0
   745)   RT = IDEAL_GAS_CONSTANT * T_kelvin
   746)   
   747)   if (hydrogen) then
   748)     ! suggested by Peter Lichtner
   749)     ! this function honors alpha(Tc)=1 while closely fitting Graboski curve from
   750)     ! "A Modified Soave Equation of State for Phase Equilibrium
   751)     !  Calculations. 3. Systems Containing Hydrogen"
   752)     alpha = EXP(0.340d0*(1-T_kelvin/Tc))
   753)   else
   754)     coeff_alpha = 0.48508d0 + acentric*(1.55171d0 - 0.15613*acentric)
   755)     alpha = (1.d0 + coeff_alpha*(1.d0 - SQRT(T_Kelvin/Tc)))**2
   756)   end if
   757)   
   758)   a = coeff_a * alpha * (IDEAL_GAS_CONSTANT * Tc)**2 / Pc
   759)   b = coeff_b * IDEAL_GAS_CONSTANT * Tc / Pc
   760)   
   761)   a_RT = a / RT
   762)   P_RT = P / RT
   763)   coef(4) = P / RT
   764)   coef(3) = 1.0d0
   765)   coef(2) = a_RT - b - P_RT*b**2
   766)   coef(1) = a_RT*b
   767)   V = RT/P  ! initial guess
   768)   
   769)   !Newton iteration to find a Volume of gas
   770)   do i = 1, maxit
   771)     f = V*(V*(coef(4)*V - coef(3)) + coef(2)) - coef(1)
   772)     dfdV = V*(3.0d0*coef(4)*V - 2.0d0*coef(3)) + coef(2)
   773)     if (dfdV .ne. 0.d0) then
   774)       dVd = F/dfdV
   775)       V = V - dVd
   776)       if (V .ne. 0.d0) then
   777)         if (abs(dVd/V) .lt. 1.d-10) then
   778)           Rho_gas = 1/V * 1d-3 ! mol/m^3 -> kmol/m^3
   779)           exit
   780)         end if
   781)       else
   782)         print *, 'Error: RKS gas density cannot be solved'
   783)       end if 
   784)     else
   785)       print *, 'Error: Zero Slope in Equation of State'
   786)     end if
   787)   end do
   788)   
   789) end subroutine EOSGasDensityRKS
   790) 
   791) ! ************************************************************************** !
   792) 
   793) subroutine EOSGasDensityPRMethane(T,P,Rho_gas,dRho_dT,dRho_dP,ierr)
   794) ! Peng-Robinson (PR) equation of state. This is the uncorrected version 
   795) ! sufficient for methane. For other higher hydrocarbons one might need
   796) ! the corrected version published in 1978.
   797) ! Reference: Peng, D. Y., and Robinson, D. B. (1976).
   798) ! A New Two-Constant Equation of State Industrial and Engineering Chemistry: 
   799) ! Fundamentals 15: 59–64 DOI:10.1021/i160057a011
   800) ! current version is for methane only.
   801) ! if omega is greater than 0.49 then alpha needs to be modified below
   802) ! Satish Karra, LANL
   803) ! 09/30/2014
   804) 
   805)   implicit none
   806) 
   807)   PetscReal, intent(in) :: T        ! temperature [C]
   808)   PetscReal, intent(in) :: P        ! pressure [Pa]
   809)   PetscReal, intent(out) :: Rho_gas ! gas density [kmol/m^3]
   810)   PetscReal, intent(out) :: dRho_dT ! derivative gas density wrt temperature
   811)   PetscReal, intent(out) :: dRho_dP ! derivative gas density wrt pressure
   812)   PetscErrorCode, intent(out) :: ierr
   813)   
   814)   PetscReal :: T_kelvin, RT, alpha,  T_r, Z
   815)   PetscReal :: f, dfdZ, dZd
   816)   PetscReal :: a, b
   817)   PetscInt :: i
   818)   PetscReal, parameter :: coeff_a = 0.45724
   819)   PetscReal, parameter :: coeff_b = 0.0778
   820)   
   821)   ! for methane critical temp, pressure 
   822)   PetscReal, parameter :: Tc = 191.15    ! in K
   823)   PetscReal, parameter :: Pc = 4.641e6   ! in Pa
   824)   PetscReal, parameter :: omega = 0.0115 ! acentric factor 
   825)   
   826)   !solver
   827)   PetscReal :: coef(4)
   828)   PetscInt, parameter :: maxit = 50
   829)   
   830)   T_kelvin = T + 273.15d0
   831)   RT = IDEAL_GAS_CONSTANT*T_kelvin
   832)   T_r = T_kelvin/Tc
   833)   alpha = (1 + (0.3744 + 1.5422*omega - 0.26992*omega**2)*(1-T_r**(0.5)))**2
   834)   
   835)   a = coeff_a * alpha * (IDEAL_GAS_CONSTANT * Tc)**2 / Pc
   836)   b = coeff_b * IDEAL_GAS_CONSTANT * Tc / Pc
   837) 
   838)   A = alpha * a / (RT)**2
   839)   B = b * P / RT 
   840) 
   841)   coef(1) = 1.0d0
   842)   coef(2) = B - 1.0d0
   843)   coef(3) = A - 2 * B - 3 * B**2
   844)   coef(4) = B**3 +  B**2 - A * B 
   845)   Z = 1.0d0  ! initial guess for compressibility
   846)   
   847)   !Newton iteration to find a Volume of gas
   848)   do i = 1, maxit
   849)     f = coef(1) * Z**3 + coef(2) * Z**2 + coef(3) * Z + coef(4)
   850)     dfdZ = coef(1) * 3 * Z**2  + coef(2) * 2 * Z + coef(3)
   851)     if (dfdZ .ne. 0.d0) then
   852)       dZd = f/dfdZ
   853)       Z = Z - dZd
   854)       if (Z .ne. 0.d0) then
   855)         if (abs(dZd/Z) .lt. 1.d-10) then
   856)           Rho_gas = 1.d0/Z * P/RT * 1d-3 ! mol/m^3 -> kmol/m^3
   857)           exit
   858)         end if
   859)       else
   860)         print *, 'Error: PR76 gas density cannot be solved'
   861)       end if 
   862)     else
   863)       print *, 'Error: Zero Slope in PR76 Equation of State'
   864)     end if
   865)   end do
   866)   
   867) end subroutine EOSGasDensityPRMethane
   868) 
   869) ! ************************************************************************** !
   870) 
   871) subroutine EOSGasFugacity(T,P,Rho_gas,phi,ierr)
   872) ! current version is for hydrogen only. See
   873) ! Soave, Giorgio, 1972, "Equilibrium constants from a modified Redlich-Kwong
   874) ! equation of state", Chem. Eng. Sci., V27, pp 1197-1203.
   875) 
   876)   PetscReal, intent(in) :: T        ! temperature [C]
   877)   PetscReal, intent(in) :: P        ! pressure [Pa]
   878)   PetscReal, intent(in) :: Rho_gas  ! gas density [kmol/m^3]
   879)   PetscReal, intent(out) :: phi     ! fugacity coefficient
   880)   PetscErrorCode, intent(out) :: ierr
   881) 
   882)   !for hydrogen
   883)   ! American Petroleum Institute,
   884)   ! "Technical Data Book-Petroleum Refining" (1977)
   885)   PetscReal, parameter :: Tc = 41.67d0   ! critical temperature
   886)   PetscReal, parameter :: Pc = 2.1029d6  ! critical pressure
   887) 
   888)   PetscReal :: T_kelvin, Z, V, Tr, LHS
   889)   PetscReal :: A, B, alpha
   890) 
   891)   V = 1.d0 / Rho_gas * 1.d-3
   892)   T_kelvin = T + 273.15d0
   893)   Tr = T_kelvin/Tc  ! reduced temperature
   894)   alpha = EXP(0.340d0*(1.d0-Tr))  ! alpha(T)
   895) 
   896)   A = 0.42747 * alpha * (P/Pc) / (T/Tc)**2
   897)   B = 0.08664 * (P/Pc) / (T/Tc)
   898)   Z = P*V / (IDEAL_GAS_CONSTANT*T)
   899)   
   900)   ! Fugacity Coefficient
   901)   LHS = Z - 1.d0 - LOG(Z-B) - A/B * LOG((Z+B)/Z)
   902)   phi = EXP(LHS)  ! dimensionless (Pa/Pa)
   903)   
   904) end subroutine EOSGasFugacity
   905) 
   906) ! ************************************************************************** !
   907) 
   908) subroutine EOSGasEnergyIdealMethane(T,P,H,dH_dT,dH_dP,U,dU_dT,dU_dP,ierr)
   909)   
   910) ! Based on EOSGasEnergyIdeal. Modified for Methane
   911) ! Satish Karra, LANL
   912) ! 09/30/2014
   913)   
   914)   implicit none
   915) 
   916)   PetscReal, intent(in) :: T        ! temperature [C]
   917)   PetscReal, intent(in) :: P        ! pressure [Pa]
   918)   PetscReal, intent(out) :: H       ! enthalpy [J/kmol]
   919)   PetscReal, intent(out) :: dH_dT   ! derivative enthalpy wrt temperature
   920)   PetscReal, intent(out) :: dH_dP   ! derivative enthalpy wrt pressure
   921)   PetscReal, intent(out) :: U       ! internal energy [J/kmol]
   922)   PetscReal, intent(out) :: dU_dT   ! deriv. internal energy wrt temperature
   923)   PetscReal, intent(out) :: dU_dP   ! deriv. internal energy wrt pressure
   924)   PetscErrorCode, intent(out) :: ierr
   925) 
   926)   ! Cpg units: J/mol-K
   927)   PetscReal, parameter :: Cp_methane = 35.69 ! at 298.15 K and 1 bar http://webbook.nist.gov/cgi/cbook.cgi?ID=C74828&Units=SI&Mask=1
   928)   PetscReal :: T_energy
   929)   PetscReal :: T_k
   930) 
   931)   ierr = 0
   932)   ! T_energy is either T or T + 273.15
   933)   ! do not change below
   934)   T_energy = T + T_energy_offset
   935)   T_k = T + 273.15d0
   936)   H = Cp_methane * T_energy * 1.d3  ! J/mol -> J/kmol
   937)   U = H - IDEAL_GAS_CONSTANT * T_k * 1.d3 ! J/mol -> J/kmol
   938) 
   939)   dH_dP = 0.d0
   940)   dH_dT = Cp_methane * 1.d3
   941)   dU_dP = 0.d0
   942)   dU_dT = (Cp_methane - IDEAL_GAS_CONSTANT) * 1.d3
   943)     
   944) end subroutine EOSGasEnergyIdealMethane
   945) 
   946) ! ************************************************************************** !
   947) 
   948) subroutine EOSGasEnergyIdeal(T,P,H,dH_dT,dH_dP,U,dU_dT,dU_dP,ierr)
   949)     
   950)   implicit none
   951) 
   952)   PetscReal, intent(in) :: T        ! temperature [C]
   953)   PetscReal, intent(in) :: P        ! pressure [Pa]
   954)   PetscReal, intent(out) :: H       ! enthalpy [J/kmol]
   955)   PetscReal, intent(out) :: dH_dT   ! derivative enthalpy wrt temperature
   956)   PetscReal, intent(out) :: dH_dP   ! derivative enthalpy wrt pressure
   957)   PetscReal, intent(out) :: U       ! internal energy [J/kmol]
   958)   PetscReal, intent(out) :: dU_dT   ! deriv. internal energy wrt temperature
   959)   PetscReal, intent(out) :: dU_dP   ! deriv. internal energy wrt pressure
   960)   PetscErrorCode, intent(out) :: ierr
   961) 
   962)   ! Cv_air units: J/mol-K
   963)   PetscReal, parameter :: Cv_air = 20.85 ! heat capacity wiki [J/mol-K]
   964)   PetscReal :: T_energy
   965)   PetscReal :: T_k
   966) 
   967)   ! T_energy is either T or T + 273.15
   968)   ! do not change below
   969)   T_energy = T + T_energy_offset
   970)   T_k = T + 273.15d0
   971)   U = Cv_air * T_energy * 1.d3  ! J/mol -> J/kmol
   972)   H = U + IDEAL_GAS_CONSTANT * T_k * 1.d3 ! J/mol -> J/kmol
   973) 
   974)   dU_dP = 0.d0
   975)   dU_dT = Cv_air * 1.d3
   976)   dH_dP = 0.d0
   977)   dH_dT = dU_dT + IDEAL_GAS_CONSTANT * 1.d3
   978)     
   979) end subroutine EOSGasEnergyIdeal
   980) 
   981) ! ************************************************************************** !
   982) 
   983) subroutine EOSGasDensityConstant(T,P,Rho_gas,dRho_dT,dRho_dP,ierr)
   984) 
   985)   implicit none
   986)   
   987)   PetscReal, intent(in) :: T        ! temperature [C]
   988)   PetscReal, intent(in) :: P        ! pressure [Pa]
   989)   PetscReal, intent(out) :: Rho_gas ! gas density [kmol/m^3]
   990)   PetscReal, intent(out) :: dRho_dT ! derivative gas density wrt temperature
   991)   PetscReal, intent(out) :: dRho_dP ! derivative gas density wrt pressure
   992)   PetscErrorCode, intent(out) :: ierr
   993)   
   994)   ierr = 0
   995)   Rho_gas = constant_density ! kmol/m^3
   996) 
   997)   dRho_dT = 0.d0
   998)   dRho_dP = 0.d0
   999) 
  1000) end subroutine EOSGasDensityConstant
  1001) 
  1002) ! ************************************************************************** !
  1003) 
  1004) subroutine EOSGasEnergyConstant(T,P,H,dH_dT,dH_dP,U,dU_dT,dU_dP,ierr)
  1005)     
  1006)   implicit none
  1007) 
  1008)   PetscReal, intent(in) :: T        ! temperature [C]
  1009)   PetscReal, intent(in) :: P        ! pressure [Pa]
  1010)   PetscReal, intent(out) :: H       ! enthalpy [J/kmol]
  1011)   PetscReal, intent(out) :: dH_dT   ! derivative enthalpy wrt temperature
  1012)   PetscReal, intent(out) :: dH_dP   ! derivative enthalpy wrt pressure
  1013)   PetscReal, intent(out) :: U       ! internal energy [J/kmol]
  1014)   PetscReal, intent(out) :: dU_dT   ! deriv. internal energy wrt temperature
  1015)   PetscReal, intent(out) :: dU_dP   ! deriv. internal energy wrt pressure
  1016)   PetscErrorCode, intent(out) :: ierr
  1017)   
  1018)   PetscReal :: T_energy
  1019) 
  1020)   ierr = 0
  1021)   H = constant_enthalpy ! J/kmol
  1022)   ! T_energy is either T or T + 273.15
  1023)   ! do not change below
  1024)   T_energy = T + T_energy_offset
  1025)   U = H - IDEAL_GAS_CONSTANT * T_energy * 1.d3 ! J/mol -> J/kmol
  1026)   
  1027)   dH_dP = 0.d0
  1028)   dH_dT = 0.d0
  1029)   dU_dP = 0.d0
  1030)   dU_dT = -1.d0 * IDEAL_GAS_CONSTANT * 1.d3
  1031)   
  1032)   print *, 'Calculation of internal gas energy not set up properly in ' // &
  1033)     'EOSGasEnergyConstant.'
  1034)   stop  
  1035)   
  1036) end subroutine EOSGasEnergyConstant
  1037) 
  1038) 
  1039) ! ************************************************************************** !
  1040) 
  1041) subroutine EOSGasHenryNoDerive(T,Psat,Hc)
  1042) 
  1043)   implicit none
  1044) 
  1045)   PetscReal, intent(in) :: T        ! temperature [C]
  1046)   PetscReal, intent(in) :: Psat     ! saturation pressure
  1047)   PetscReal, intent(out) :: Hc      ! Henry's constant
  1048)   
  1049)   call EOSGasHenryPtr(T,Psat,Hc)
  1050)                           
  1051) end subroutine EOSGasHenryNoDerive
  1052) 
  1053) ! ************************************************************************** !
  1054) 
  1055) subroutine EOSGasHenry_air_noderiv(tc,ps,Henry)
  1056) ! 
  1057) !   Calculates Henry's constant as a function of temperature [C], 
  1058) !   and saturation pressure [Pa].  
  1059) !
  1060) !   Fernandez-Prini, F., J. Alvarez and A. Harvey (2003) Henry's Constants and
  1061) !   Vapor-Liquid Distribution Constants for Gaseous Solutes in H2O and D2O at
  1062) !   High Temperatures, J. Phys. Chem. Ref. Data, Vol. 32, No. 2, Equation 15
  1063) !   with coefficients A,B,C from Table 3 for N2(g)
  1064) 
  1065)     implicit none
  1066)     
  1067)     PetscReal, intent(in) :: tc
  1068)     PetscReal, intent(in) :: ps
  1069)     PetscReal, intent(out) :: Henry
  1070) 
  1071)     PetscReal  Tr,tao,tmp,t
  1072)     PetscReal, parameter :: a=-9.67578d0, b=4.72162d0, c=11.70585d0
  1073)     PetscReal, parameter :: Tcl=647.096d0 ! H2O critical temp(K) from IAPWS(1995b)
  1074) 
  1075)     t = tc+273.15D0
  1076)     Tr = t/Tcl
  1077)     tao = 1.D0-Tr
  1078)     tmp = a/Tr + b * tao**0.355d0/Tr + c * (Tr**(-0.41d0)) * exp(tao)
  1079)     Henry = exp(tmp)*ps
  1080) 
  1081) end subroutine EOSGasHenry_air_noderiv
  1082) 
  1083) ! ************************************************************************** !
  1084) 
  1085) subroutine EOSGasHenry_air(tc,ps,ps_p,ps_t,Henry,Henry_p,Henry_t)
  1086) ! 
  1087) !   Calculates Henry's constant as a function of temperature [C], 
  1088) !   and saturation pressure [Pa].  
  1089) !
  1090) !   Fernandez-Prini, F., J. Alvarez and A. Harvey (2003) Henry's Constants and
  1091) !   Vapor-Liquid Distribution Constants for Gaseous Solutes in H2O and D2O at
  1092) !   High Temperatures, J. Phys. Chem. Ref. Data, Vol. 32, No. 2, Equation 15
  1093) !   with coefficients A,B,C from Table 3 for N2(g)
  1094) 
  1095)     implicit none
  1096)     
  1097)     PetscReal, intent(in) :: tc       ! [C]
  1098)     PetscReal, intent(in) :: ps       ! [Pa]
  1099)     PetscReal, intent(in) :: ps_p,ps_t
  1100)     PetscReal,intent(out) :: Henry,Henry_p,Henry_t
  1101) 
  1102)     PetscReal  Tr,tao,tmp,t
  1103)     PetscReal, parameter :: a=-9.67578d0, b=4.72162d0, c=11.70585d0
  1104)     PetscReal, parameter :: Tcl=647.096d0 ! H2O critical temp from IAPWS(1995b)
  1105) 
  1106)     t = tc+273.15D0
  1107)     Tr = t/Tcl
  1108)     tao = 1.D0-Tr
  1109)     tmp = a/Tr + b * tao**0.355d0/Tr + c * (Tr**(-0.41d0)) * exp(tao)
  1110)     Henry = exp(tmp)*ps
  1111) 
  1112)     tmp = ((-a/Tr+b*(-0.355d0*tao**(-0.645d0)-tao**0.355d0/Tr))/Tr - &
  1113)          c*exp(tao)*(tao**(-0.41d0))*(0.41d0/Tr-1.d0))/Tcl
  1114)     Henry_t = Henry*(tmp+ps_t/ps)
  1115)     Henry_p = ps_p*Henry/ps
  1116) 
  1117) end subroutine EOSGasHenry_air
  1118) 
  1119) ! ************************************************************************** !
  1120) 
  1121) subroutine EOSGasHenryConstant(T,Psat,Hc)
  1122)    implicit none
  1123)     PetscReal, intent(in) :: T    ! temperature [C]
  1124)     PetscReal, intent(in) :: Psat ! saturation pressure [Pa]
  1125)     PetscReal, intent(out) :: Hc   ! Henry's constant [Pa]
  1126) 
  1127)     Hc = constant_henry
  1128)     
  1129) end subroutine EOSGasHenryConstant
  1130) 
  1131) ! **************************************************************************** !
  1132) 
  1133) subroutine EOSGasInputRecord()
  1134)   ! 
  1135)   ! Prints ingested equation of state information to the input record file.
  1136)   ! 
  1137)   ! Author: Jenn Frederick
  1138)   ! Date: 05/04/2016
  1139)   ! 
  1140)   
  1141)   implicit none
  1142)   
  1143)   character(len=MAXWORDLENGTH) :: word1, word2
  1144)   character(len=MAXSTRINGLENGTH) :: string
  1145)   PetscInt :: id = INPUT_RECORD_UNIT
  1146) 
  1147)   write(id,'(a29)',advance='no') '---------------------------: '
  1148)   write(id,'(a)') 'GAS'
  1149)   
  1150)   ! gas density [kg/m^3]
  1151)   if (associated(EOSGasDensityEnergyPtr,EOSGasDensityEnergyGeneral) .and. &
  1152)       associated(EOSGasDensityPtr,EOSGasDensityConstant)) then
  1153)     write(id,'(a29)',advance='no') 'gas density: '
  1154)     write(word1,*) constant_density
  1155)     write(id,'(a)') 'constant, ' // adjustl(trim(word1)) // ' kg/m^3'
  1156)   endif
  1157)   if (associated(EOSGasDensityEnergyPtr,EOSGasDensityEnergyGeneral) .and. &
  1158)       associated(EOSGasDensityPtr,EOSGasDensityRKS)) then
  1159)     write(id,'(a29)',advance='no') 'gas density: '
  1160)     write(id,'(a)') 'rsk'
  1161)     write(id,'(a29)',advance='no') 'critical temperature: '
  1162)     write(word1,*) Tc
  1163)     write(id,'(a)') adjustl(trim(word1)) // ' C'
  1164)     write(id,'(a29)',advance='no') 'critical pressure: '
  1165)     write(word1,*) Pc
  1166)     write(id,'(a)') adjustl(trim(word1)) // ' Pa'
  1167)     if (.not.hydrogen) then
  1168)       write(id,'(a29)',advance='no') 'acentric factor: '
  1169)       write(word1,*) acentric
  1170)       write(id,'(a)') adjustl(trim(word1)) 
  1171)     endif
  1172)     write(id,'(a29)',advance='no') 'omega A: '
  1173)     write(word1,*) coeff_a
  1174)     write(id,'(a)') adjustl(trim(word1))
  1175)     write(id,'(a29)',advance='no') 'omega B: '
  1176)     write(word1,*) coeff_b
  1177)     write(id,'(a)') adjustl(trim(word1))
  1178)   endif
  1179)   if (associated(EOSGasDensityEnergyPtr,EOSGasDensityEnergyGeneral) .and. &
  1180)       associated(EOSGasDensityPtr,EOSGasDensityPRMethane)) then
  1181)     write(id,'(a29)',advance='no') 'gas density: '
  1182)     write(id,'(a)') 'pr methane'
  1183)   endif
  1184)   if (associated(EOSGasDensityEnergyPtr,EOSGasDensityEnergyGeneral) .and. &
  1185)       associated(EOSGasDensityPtr,EOSGasDensityIdeal)) then
  1186)     write(id,'(a29)',advance='no') 'gas density: '
  1187)     write(id,'(a)') 'default, ideal'
  1188)   endif
  1189)   
  1190)   ! gas viscosity [Pa-s]
  1191)   if (associated(EOSGasViscosityPtr,EOSGasViscosityConstant)) then
  1192)     write(id,'(a29)',advance='no') 'gas viscosity: '
  1193)     write(word1,*) constant_viscosity
  1194)     write(id,'(a)') 'constant, ' // trim(word1) // ' Pa-sec'
  1195)   endif
  1196)   if (associated(EOSGasViscosityPtr,EOSGasViscosity1)) then
  1197)     write(id,'(a29)',advance='no') 'gas viscosity: '
  1198)     write(id,'(a)') 'default'
  1199)   endif
  1200)   
  1201)   ! gas enthalpy [J/kmol]
  1202)   if (associated(EOSGasDensityEnergyPtr,EOSGasDensityEnergyGeneral) .and. &
  1203)       associated(EOSGasEnergyPtr,EOSGasEnergyConstant)) then
  1204)     write(id,'(a29)',advance='no') 'gas enthalpy: '
  1205)     write(word1,*) constant_enthalpy
  1206)     write(id,'(a)') 'constant, ' // trim(word1) // 'J/kmol'
  1207)   endif
  1208)   if (associated(EOSGasDensityEnergyPtr,EOSGasDensityEnergyGeneral) .and. &
  1209)       associated(EOSGasEnergyPtr,EOSGasEnergyIdeal)) then
  1210)     write(id,'(a29)',advance='no') 'gas enthalpy: '
  1211)     write(id,'(a)') 'default, ideal'
  1212)   endif
  1213)   if (associated(EOSGasDensityEnergyPtr,EOSGasDensityEnergyGeneral) .and. &
  1214)       associated(EOSGasEnergyPtr,EOSGasEnergyIdealMethane)) then
  1215)     write(id,'(a29)',advance='no') 'gas enthalpy: '
  1216)     write(id,'(a)') 'ideal methane'
  1217)   endif
  1218)   
  1219)   ! henry's constant
  1220)   if (associated(EOSGasHenryPtr,EOSGasHenryConstant)) then
  1221)     write(id,'(a29)',advance='no') "henry's constant: "
  1222)     write(word1,*) constant_henry
  1223)     write(id,'(a)') 'constant, ' // trim(word1) 
  1224)   endif
  1225)   if (associated(EOSGasHenryPtr,EOSGasHenry_air_noderiv)) then
  1226)     write(id,'(a29)',advance='no') "henry's constant: "
  1227)     write(id,'(a)') 'default, air'
  1228)   endif
  1229)   
  1230)   write(id,'(a)') '---------------------------------------------------------&
  1231)                   &-----------------------'
  1232)   
  1233) end subroutine EOSGasInputRecord
  1234) 
  1235) ! ************************************************************************** !
  1236) 
  1237) subroutine EOSGasTest(temp_low,temp_high,pres_low,pres_high, &
  1238)                         ntemp,npres,uniform_temp,uniform_pres,filename)
  1239) 
  1240)   use EOS_Water_module, only : EOSWaterSaturationPressure
  1241) 
  1242)   implicit none
  1243) 
  1244)   PetscReal :: temp_low
  1245)   PetscReal :: temp_high
  1246)   PetscReal :: pres_low
  1247)   PetscReal :: pres_high
  1248)   PetscInt :: npres
  1249)   PetscInt :: ntemp
  1250)   PetscBool :: uniform_temp
  1251)   PetscBool :: uniform_pres
  1252)   character(len=MAXWORDLENGTH) :: filename
  1253) 
  1254)   PetscReal, allocatable :: temp(:)
  1255)   PetscReal, allocatable :: pres(:)
  1256)   PetscReal, allocatable :: density_kg(:,:)
  1257)   PetscReal, allocatable :: enthalpy(:,:)
  1258)   PetscReal, allocatable :: internal_energy(:,:)
  1259)   PetscReal, allocatable :: viscosity(:,:)
  1260)   PetscReal, allocatable :: saturation_pressure_array(:)
  1261)   PetscReal, allocatable :: henry(:)
  1262)   PetscReal :: dum1, dum2, dum3, dum4
  1263)   PetscInt :: itemp, ipres
  1264)   PetscReal :: ln_low, ln_high
  1265)   PetscReal :: saturation_pressure
  1266)   PetscReal :: air_pressure
  1267)   PetscReal :: NaN
  1268)   character(len=MAXWORDLENGTH) :: eos_density_name
  1269)   character(len=MAXWORDLENGTH) :: eos_energy_name
  1270)   character(len=MAXWORDLENGTH) :: eos_viscosity_name
  1271)   character(len=MAXWORDLENGTH) :: eos_saturation_pressure_name
  1272)   character(len=MAXWORDLENGTH) :: eos_henry_name
  1273)   character(len=MAXSTRINGLENGTH) :: header
  1274) 
  1275)   PetscErrorCode :: ierr
  1276) 
  1277)   NaN = 0.d0
  1278)   NaN = 1.d0/NaN
  1279)   NaN = 0.d0*NaN
  1280) 
  1281)   allocate(temp(ntemp))
  1282)   temp = UNINITIALIZED_DOUBLE
  1283)   allocate(pres(ntemp))
  1284)   pres = UNINITIALIZED_DOUBLE
  1285)   allocate(density_kg(npres,ntemp))
  1286)   density_kg = UNINITIALIZED_DOUBLE
  1287)   allocate(viscosity(npres,ntemp))
  1288)   viscosity = UNINITIALIZED_DOUBLE
  1289)   allocate(enthalpy(npres,ntemp))
  1290)   enthalpy = UNINITIALIZED_DOUBLE
  1291)   allocate(internal_energy(npres,ntemp))
  1292)   internal_energy = UNINITIALIZED_DOUBLE
  1293)   allocate(saturation_pressure_array(ntemp))
  1294)   saturation_pressure_array = UNINITIALIZED_DOUBLE
  1295)   allocate(henry(ntemp))
  1296)   henry = UNINITIALIZED_DOUBLE
  1297) 
  1298)   if (uniform_pres) then
  1299)     do ipres = 1, npres
  1300)       pres(ipres) = (pres_high-pres_low)/dble(npres-1) * (ipres-1) + pres_low
  1301)     enddo
  1302)   else
  1303)     ln_high = log(pres_high)
  1304)     ln_low = log(pres_low)
  1305)     do ipres = 1, npres
  1306)       pres(ipres) = exp((ln_high-ln_low)/dble(npres-1) * (ipres-1) + ln_low)
  1307)     enddo
  1308)   endif
  1309) 
  1310)   if (uniform_temp) then
  1311)     do itemp = 1, ntemp
  1312)       temp(itemp) = (temp_high-temp_low)/dble(ntemp-1) * (itemp-1) + temp_low
  1313)     enddo
  1314)   else
  1315)     ln_high = log(temp_high)
  1316)     ln_low = log(temp_low)
  1317)     do itemp = 1, ntemp
  1318)       temp(itemp) = exp((ln_high-ln_low)/dble(ntemp-1) * (itemp-1) + ln_low)
  1319)     enddo
  1320)   endif
  1321) 
  1322)   ! density
  1323)   if (associated(EOSGasDensityPtr,EOSGasDensityConstant)) then
  1324)     eos_density_name = 'Constant'
  1325)   else if (associated(EOSGasDensityPtr,EOSGasDensityIdeal)) then
  1326)     eos_density_name = 'Ideal Gas Law'
  1327)   else if (associated(EOSGasDensityPtr,EOSGasDensityRKS)) then
  1328)     eos_density_name = 'Redlich-Kwong-Soave'
  1329)   else if (associated(EOSGasDensityPtr,EOSGasDensityPRMethane)) then
  1330)     eos_density_name = 'Peng-Robinson Methane'
  1331)   else 
  1332)     eos_density_name = 'Unknown'
  1333)   endif
  1334) 
  1335)   ! energy
  1336)   if (associated(EOSGasEnergyPtr,EOSGasEnergyConstant)) then
  1337)     eos_energy_name = 'Constant'
  1338)   else if (associated(EOSGasEnergyPtr,EOSGasEnergyIdeal)) then
  1339)     eos_energy_name = 'Ideal Gas Law'
  1340)   else if (associated(EOSGasEnergyPtr,EOSGasEnergyIdealMethane)) then
  1341)     eos_energy_name = 'Ideal Gas Law - Methane'
  1342)   else
  1343)     eos_energy_name = 'Unknown'
  1344)   endif
  1345) 
  1346)   ! viscosity
  1347)   if (associated(EOSGasViscosityPtr,EOSGasViscosityConstant)) then
  1348)     eos_viscosity_name = 'Constant'
  1349)   else if (associated(EOSGasViscosityPtr,EOSGasViscosity1)) then
  1350)     eos_viscosity_name = 'Default'
  1351)   else
  1352)     eos_viscosity_name = 'Unknown'
  1353)   endif
  1354) 
  1355)   ! Henry's constant
  1356)   if (associated(EOSGasHenryPtr,EOSGasHenryConstant)) then
  1357)     eos_henry_name = 'Constant'
  1358)   else if (associated(EOSGasHenryPtr,EOSGasHenry_air_noderiv)) then
  1359)     eos_henry_name = 'Default'
  1360)   else
  1361)     eos_henry_name = 'Unknown'
  1362)   endif
  1363) 
  1364)   ! saturation pressure
  1365)   eos_saturation_pressure_name = 'Unknown'
  1366) 
  1367)   do itemp = 1, ntemp
  1368)     ! Need saturation pressure to calculate air partial pressure
  1369)     call EOSWaterSaturationPressure(temp(itemp),saturation_pressure,ierr)
  1370)     saturation_pressure_array(itemp) = saturation_pressure
  1371)     call EOSGasHenryPtr(temp(itemp),saturation_pressure,henry(itemp))
  1372)     do ipres = 1, npres
  1373)       call EOSGasDensityPtr(temp(itemp),pres(ipres), &
  1374)                             density_kg(ipres,itemp), &
  1375)                             dum1,dum2,ierr)
  1376)       call EOSGasEnergyPtr(temp(itemp),pres(ipres),&
  1377)                            enthalpy(ipres,itemp),dum1,dum2, &
  1378)                            internal_energy(ipres,itemp),dum3,dum4,ierr)
  1379)       air_pressure = pres(ipres) - saturation_pressure
  1380)       if (air_pressure > 0.d0) then
  1381)         call EOSGasViscosityPtr(temp(itemp),air_pressure,pres(ipres), &
  1382)                                 density_kg(ipres,itemp), &
  1383)                                 viscosity(ipres,itemp),ierr)
  1384)       else
  1385)         viscosity(ipres,itemp) = NaN
  1386)       endif
  1387)     enddo
  1388)   enddo
  1389) 
  1390) 100 format(100es16.8)
  1391)   if (len_trim(filename) == 0) filename = 'eos_gas_test.txt'
  1392)   open(unit=IUNIT_TEMP,file=filename)
  1393)   header = 'T[C], P[Pa], &
  1394)     &Density (' // trim(eos_density_name) // ') [kg/m^3], &
  1395)     &Enthalpy (' // trim(eos_energy_name) // ') [J/kmol], &
  1396)     &Internal Energy (' // trim(eos_energy_name) // ') [J/kmol], &
  1397)     &Viscosity (' // trim(eos_viscosity_name) // ') [Pa-s], &
  1398)     &Saturation Pressure (' // trim(eos_saturation_pressure_name) // ") [Pa], &
  1399)     &Henry's Constant (" // trim(eos_henry_name) // ') [-]'
  1400)   write(IUNIT_TEMP,'(a)') trim(header)
  1401)   write(IUNIT_TEMP,'(100i9)') ntemp, npres
  1402)   do itemp = 1, ntemp
  1403)     do ipres = 1, npres
  1404)       write(IUNIT_TEMP,100) temp(itemp), pres(ipres), &
  1405)             density_kg(ipres,itemp), enthalpy(ipres,itemp), &
  1406)             internal_energy(ipres,itemp), viscosity(ipres,itemp), &
  1407)             saturation_pressure_array(itemp), henry(itemp)
  1408)     enddo
  1409)   enddo
  1410)   close(IUNIT_TEMP)
  1411) 
  1412)   deallocate(temp)
  1413)   deallocate(pres)
  1414)   deallocate(density_kg)
  1415)   deallocate(enthalpy)
  1416)   deallocate(internal_energy)
  1417)   deallocate(viscosity)
  1418)   deallocate(saturation_pressure_array)
  1419)   deallocate(henry)
  1420) 
  1421) end subroutine EOSGasTest
  1422) 
  1423) ! ************************************************************************** !
  1424) 
  1425) end module EOS_Gas_module

generated by
Intel(R) C++/Fortran Compiler code-coverage tool
Web-Page Owner: Nobody