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