LCOV - code coverage report
Current view: top level - include/userobjects - PorousFlowBrineCO2.h (source / functions) Hit Total Coverage
Test: idaholab/moose porous_flow: #31405 (292dce) with base fef103 Lines: 1 1 100.0 %
Date: 2025-09-04 07:55:56 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #pragma once
      11             : 
      12             : #include "PorousFlowFluidStateMultiComponentBase.h"
      13             : 
      14             : class BrineFluidProperties;
      15             : class SinglePhaseFluidProperties;
      16             : class Water97FluidProperties;
      17             : 
      18             : /**
      19             :  * Specialized class for brine and CO2 including calculation of mutual
      20             :  * solubility of the two fluids using a high-accuracy fugacity-based formulation.
      21             :  *
      22             :  * For temperatures 12C <= T <= 99C, the formulation is based on
      23             :  * Spycher, Pruess and Ennis-King, CO2-H2O mixtures in the geological
      24             :  * sequestration of CO2. I. Assessment and calculation of mutual solubilities
      25             :  * from 12 to 100C and up to 600 bar, Geochimica et Cosmochimica Acta, 67, 3015-3031 (2003),
      26             :  * and Spycher and Pruess, CO2-H2O mixtures in the geological sequestration of CO2. II.
      27             :  * Partitioning in chloride brine at 12-100C and up to 600 bar, Geochimica et
      28             :  * Cosmochimica Acta, 69, 3309-3320 (2005).
      29             :  *
      30             :  * For temperatures 109C <= T <= 300C, the formulation is based on
      31             :  * Spycher and Pruess, A Phase-Partitioning Model for CO2-Brine Mixtures at Elevated
      32             :  * Temperatures and Pressures: Application to CO2-Enhanced Geothermal Systems,
      33             :  * Transport in Porous Media, 82, 173-196 (2010)
      34             :  *
      35             :  * As the two formulations do not coincide at temperatures near 100C, a cubic
      36             :  * polynomial is used in the intermediate temperature range 99C < T < 109C to
      37             :  * provide a smooth transition from the two formulations in this region.
      38             :  *
      39             :  * Notation convention
      40             :  * Throughout this class, both mole fractions and mass fractions will be used.
      41             :  * The following notation will be used:
      42             :  * yk: mole fraction of component k in the gas phase
      43             :  * xk: mole fraction of component k in the liquid phase
      44             :  * Yk: mass fraction of component k in the gas phase
      45             :  * Xk: mass fraction of component k in the liquid phase
      46             :  */
      47             : class PorousFlowBrineCO2 : public PorousFlowFluidStateMultiComponentBase
      48             : {
      49             : public:
      50             :   static InputParameters validParams();
      51             : 
      52             :   PorousFlowBrineCO2(const InputParameters & parameters);
      53             : 
      54             :   virtual std::string fluidStateName() const override;
      55             : 
      56             :   void thermophysicalProperties(Real pressure,
      57             :                                 Real temperature,
      58             :                                 Real Xnacl,
      59             :                                 Real Z,
      60             :                                 unsigned int qp,
      61             :                                 std::vector<FluidStateProperties> & fsp) const override;
      62             : 
      63             :   void thermophysicalProperties(const ADReal & pressure,
      64             :                                 const ADReal & temperature,
      65             :                                 const ADReal & Xnacl,
      66             :                                 const ADReal & Z,
      67             :                                 unsigned int qp,
      68             :                                 std::vector<FluidStateProperties> & fsp) const override;
      69             : 
      70             :   /**
      71             :    * Mole fractions of CO2 in brine and water vapor in CO2 at equilibrium
      72             :    *
      73             :    * In the low temperature regime (T <= 99C), the mole fractions are calculated directly,
      74             :    * while in the elevated temperature regime (T >= 109C), they are calculated iteratively.
      75             :    * In the intermediate regime (99C < T < 109C), a cubic polynomial is used to smoothly
      76             :    * connect the low and elevated temperature regimes.
      77             :    *
      78             :    * @param pressure phase pressure (Pa)
      79             :    * @param temperature phase temperature (K)
      80             :    * @param Xnacl NaCl mass fraction (kg/kg)
      81             :    * @param[out] xco2 mole fraction of CO2 in liquid
      82             :    * @param[out] yh2o mole fraction of H2O in gas
      83             :    */
      84             :   void equilibriumMoleFractions(const ADReal & pressure,
      85             :                                 const ADReal & temperature,
      86             :                                 const ADReal & Xnacl,
      87             :                                 ADReal & xco2,
      88             :                                 ADReal & yh2o) const;
      89             : 
      90             :   /**
      91             :    * Mass fractions of CO2 in brine and water vapor in CO2 at equilibrium
      92             :    *
      93             :    * @param pressure phase pressure (Pa)
      94             :    * @param temperature phase temperature (K)
      95             :    * @param Xnacl NaCl mass fraction (kg/kg)
      96             :    * @param[out] Xco2 mass fraction of CO2 in liquid (kg/kg)
      97             :    * @param[out] Yh2o mass fraction of H2O in gas (kg/kg)
      98             :    */
      99             :   void equilibriumMassFractions(const ADReal & pressure,
     100             :                                 const ADReal & temperature,
     101             :                                 const ADReal & Xnacl,
     102             :                                 ADReal & Xco2,
     103             :                                 ADReal & Yh2o) const;
     104             : 
     105             :   /**
     106             :    * Mass fractions of CO2 and H2O in both phases, as well as derivatives wrt
     107             :    * PorousFlow variables. Values depend on the phase state (liquid, gas or two phase)
     108             :    *
     109             :    * @param pressure phase pressure (Pa)
     110             :    * @param temperature phase temperature (K)
     111             :    * @param Xnacl NaCl mass fraction (kg/kg)
     112             :    * @param Z total mass fraction of CO2 component
     113             :    * @param[out] PhaseStateEnum current phase state
     114             :    * @param[out] FluidStateProperties data structure
     115             :    */
     116             :   void massFractions(const ADReal & pressure,
     117             :                      const ADReal & temperature,
     118             :                      const ADReal & Xnacl,
     119             :                      const ADReal & Z,
     120             :                      FluidStatePhaseEnum & phase_state,
     121             :                      std::vector<FluidStateProperties> & fsp) const;
     122             : 
     123             :   /**
     124             :    * Thermophysical properties of the gaseous state
     125             :    *
     126             :    * @param pressure gas pressure (Pa)
     127             :    * @param temperature temperature (K)
     128             :    * @param[out] FluidStateProperties data structure
     129             :    */
     130             :   void gasProperties(const ADReal & pressure,
     131             :                      const ADReal & temperature,
     132             :                      std::vector<FluidStateProperties> & fsp) const;
     133             : 
     134             :   /**
     135             :    * Thermophysical properties of the liquid state
     136             :    *
     137             :    * @param pressure liquid pressure (Pa)
     138             :    * @param temperature temperature (K)
     139             :    * @param Xnacl NaCl mass fraction (kg/kg)
     140             :    * @param[out] FluidStateProperties data structure
     141             :    */
     142             :   void liquidProperties(const ADReal & pressure,
     143             :                         const ADReal & temperature,
     144             :                         const ADReal & Xnacl,
     145             :                         std::vector<FluidStateProperties> & fsp) const;
     146             : 
     147             :   /**
     148             :    * Gas saturation in the two-phase region
     149             :    *
     150             :    * @param pressure gas pressure (Pa)
     151             :    * @param temperature phase temperature (K)
     152             :    * @param Xnacl NaCl mass fraction (kg/kg)
     153             :    * @param Z total mass fraction of CO2 component
     154             :    * @param FluidStateProperties data structure
     155             :    * @return gas saturation (-)
     156             :    */
     157             :   ADReal saturation(const ADReal & pressure,
     158             :                     const ADReal & temperature,
     159             :                     const ADReal & Xnacl,
     160             :                     const ADReal & Z,
     161             :                     std::vector<FluidStateProperties> & fsp) const;
     162             : 
     163             :   /**
     164             :    * Gas and liquid properties in the two-phase region
     165             :    *
     166             :    * @param pressure gas pressure (Pa)
     167             :    * @param temperature phase temperature (K)
     168             :    * @param Xnacl NaCl mass fraction (kg/kg)
     169             :    * @param Z total mass fraction of NCG component
     170             :    * @param qp quadpoint for capillary presssure
     171             :    * @param[out] FluidStateProperties data structure
     172             :    */
     173             :   void twoPhaseProperties(const ADReal & pressure,
     174             :                           const ADReal & temperature,
     175             :                           const ADReal & Xnacl,
     176             :                           const ADReal & Z,
     177             :                           unsigned int qp,
     178             :                           std::vector<FluidStateProperties> & fsp) const;
     179             : 
     180             :   /**
     181             :    * Fugacity coefficients for H2O and CO2 for T <= 100C
     182             :    * Eq. (B7) from Spycher, Pruess and Ennis-King (2003)
     183             :    *
     184             :    * @param pressure gas pressure (Pa)
     185             :    * @param temperature temperature (K)
     186             :    * @param co2_density CO2 density (kg/m^3)
     187             :    * @param[out] fco2 fugacity coefficient for CO2
     188             :    * @param[out] fh2o fugacity coefficient for H2O
     189             :    */
     190             :   void fugacityCoefficientsLowTemp(const ADReal & pressure,
     191             :                                    const ADReal & temperature,
     192             :                                    const ADReal & co2_density,
     193             :                                    ADReal & fco2,
     194             :                                    ADReal & fh2o) const;
     195             : 
     196             :   ///@{
     197             :   /**
     198             :    * Fugacity coefficients for H2O and CO2 at elevated temperatures (100C < T <= 300C).
     199             :    * Eq. (A8) from Spycher & Pruess (2010)
     200             :    *
     201             :    * @param pressure gas pressure (Pa)
     202             :    * @param temperature temperature (K)
     203             :    * @param co2_density CO2 density (kg/m^3)
     204             :    * @param xco2 mole fraction of CO2 in liquid phase (-)
     205             :    * @param yh2o mole fraction of H2O in gas phase (-)
     206             :    * @param[out] fco2 fugacity coefficient for CO2
     207             :    * @param[out] fh2o fugacity coefficient for H2O
     208             :    */
     209             :   void fugacityCoefficientsHighTemp(const ADReal & pressure,
     210             :                                     const ADReal & temperature,
     211             :                                     const ADReal & co2_density,
     212             :                                     const ADReal & xco2,
     213             :                                     const ADReal & yh2o,
     214             :                                     ADReal & fco2,
     215             :                                     ADReal & fh2o) const;
     216             : 
     217             :   ADReal fugacityCoefficientH2OHighTemp(const ADReal & pressure,
     218             :                                         const ADReal & temperature,
     219             :                                         const ADReal & co2_density,
     220             :                                         const ADReal & xco2,
     221             :                                         const ADReal & yh2o) const;
     222             : 
     223             :   ADReal fugacityCoefficientCO2HighTemp(const ADReal & pressure,
     224             :                                         const ADReal & temperature,
     225             :                                         const ADReal & co2_density,
     226             :                                         const ADReal & xco2,
     227             :                                         const ADReal & yh2o) const;
     228             :   ///@}
     229             : 
     230             :   /**
     231             :    * Activity coefficient of H2O
     232             :    * Eq. (12) from Spycher & Pruess (2010)
     233             :    *
     234             :    * @param temperature temperature (K)
     235             :    * @param xco2 mole fraction of CO2 in liquid phase (-)
     236             :    * @return activity coefficient
     237             :    */
     238             :   ADReal activityCoefficientH2O(const ADReal & temperature, const ADReal & xco2) const;
     239             : 
     240             :   /**
     241             :    * Activity coefficient of CO2
     242             :    * Eq. (13) from Spycher & Pruess (2010)
     243             :    *
     244             :    * @param temperature temperature (K)
     245             :    * @param xco2 mole fraction of CO2 in liquid phase (-)
     246             :    * @return activity coefficient
     247             :    */
     248             :   ADReal activityCoefficientCO2(const ADReal & temperature, const ADReal & xco2) const;
     249             : 
     250             :   /**
     251             :    * Activity coefficient for CO2 in brine. From Duan and Sun, An improved model calculating
     252             :    * CO2 solubility in pure water and aqueous NaCl solutions from 257 to 533 K and from 0 to
     253             :    * 2000 bar, Chem. Geol., 193, 257-271 (2003)
     254             :    *
     255             :    * Note: this is not a 'true' activity coefficient, and is instead related to the molality
     256             :    * of CO2 in water and brine. Nevertheless, Spycher and Pruess (2005) refer to it as an
     257             :    * activity coefficient, so this notation is followed here.
     258             :    *
     259             :    * @param pressure phase pressure (Pa)
     260             :    * @param temperature phase temperature (K)
     261             :    * @param Xnacl salt mass fraction (kg/kg)
     262             :    * @return activity coefficient for CO2 in brine
     263             :    */
     264             :   ADReal activityCoefficient(const ADReal & pressure,
     265             :                              const ADReal & temperature,
     266             :                              const ADReal & Xnacl) const;
     267             : 
     268             :   /**
     269             :    * Activity coefficient for CO2 in brine used in the elevated temperature formulation.
     270             :    * Eq. (18) from Spycher and Pruess (2010).
     271             :    *
     272             :    * Note: unlike activityCoefficient(), no pressure dependence is included in
     273             :    * this formulation
     274             :    *
     275             :    * @param temperature phase temperature (K)
     276             :    * @param Xnacl salt mass fraction (kg/kg)
     277             :    * @return activity coefficient for CO2 in brine
     278             :    */
     279             :   ADReal activityCoefficientHighTemp(const ADReal & temperature, const ADReal & Xnacl) const;
     280             : 
     281             :   /**
     282             :    * Equilibrium constant for H2O
     283             :    * For temperatures 12C <= T <= 99C, uses Spycher, Pruess and Ennis-King (2003)
     284             :    * For temperatures 109C <= T <= 300C, uses Spycher and Pruess (2010)
     285             :    * For temperatures 99C < T < 109C, the value is calculated by smoothly interpolating
     286             :    * the two formulations
     287             :    *
     288             :    * @param temperature temperature (K)
     289             :    * @return equilibrium constant for H2O
     290             :    */
     291             :   ADReal equilibriumConstantH2O(const ADReal & temperature) const;
     292             : 
     293             :   /**
     294             :    * Equilibrium constant for CO2
     295             :    * For temperatures 12C <= T <= 99C, uses Spycher, Pruess and Ennis-King (2003)
     296             :    * For temperatures 109C <= T <= 300C, uses Spycher and Pruess (2010)
     297             :    * For temperatures 99C < T < 109C, the value is calculated by smoothly interpolating
     298             :    * the two formulations
     299             :    *
     300             :    * @param temperature temperature (K)
     301             :    * @return equilibrium constant for CO2
     302             :    */
     303             :   ADReal equilibriumConstantCO2(const ADReal & temperature) const;
     304             : 
     305             :   /**
     306             :    * Partial density of dissolved CO2
     307             :    * From Garcia, Density of aqueous solutions of CO2, LBNL-49023 (2001)
     308             :    *
     309             :    * @param temperature fluid temperature (K)
     310             :    * @return partial molar density (kg/m^3)
     311             :    */
     312             :   ADReal partialDensityCO2(const ADReal & temperature) const;
     313             : 
     314             :   virtual Real totalMassFraction(
     315             :       Real pressure, Real temperature, Real Xnacl, Real saturation, unsigned int qp) const override;
     316             : 
     317             :   /**
     318             :    * The index of the salt component
     319             :    * @return salt component number
     320             :    */
     321           1 :   unsigned int saltComponentIndex() const { return _salt_component; };
     322             : 
     323             :   /**
     324             :    * Henry's constant of dissolution of gas phase CO2 in brine. From
     325             :    * Battistelli et al, A fluid property module for the TOUGH2 simulator for saline brines
     326             :    * with non-condensible gas, Proc. Eighteenth Workshop on Geothermal Reservoir Engineering (1993)
     327             :    *
     328             :    * @param temperature fluid temperature (K)
     329             :    * @param Xnacl NaCl mass fraction (kg/kg)
     330             :    * @return Henry's constant (Pa)
     331             :    */
     332             :   ADReal henryConstant(const ADReal & temperature, const ADReal & Xnacl) const;
     333             : 
     334             :   /**
     335             :    * Enthalpy of dissolution of gas phase CO2 in brine calculated using Henry's constant
     336             :    * From Himmelblau, Partial molal heats and entropies of solution for gases dissolved
     337             :    * in water from the freezing to the near critical point, J. Phys. Chem. 63 (1959).
     338             :    * Correction due to salinity from Battistelli et al, A fluid property module for the
     339             :    * TOUGH2 simulator for saline brines with non-condensible gas, Proc. Eighteenth Workshop
     340             :    * on Geothermal Reservoir Engineering (1993).
     341             :    *
     342             :    * @param temperature fluid temperature (K)
     343             :    * @param Xnacl NaCl mass fraction (kg/kg)
     344             :    * @return enthalpy of dissolution (J/kg)
     345             :    */
     346             :   ADReal enthalpyOfDissolutionGas(const ADReal & temperature, const ADReal & Xnacl) const;
     347             : 
     348             :   /**
     349             :    * Enthalpy of dissolution of CO2 in brine calculated using linear fit to model of
     350             :    * Duan and Sun, An improved model calculating CO2 solubility in pure water and aqueous NaCl
     351             :    * solutions from 273 to 533 K and from 0 to 2000 bar, Chemical geology, 193, 257--271 (2003).
     352             :    *
     353             :    * In the region of interest, the more complicated model given in Eq. (8) of Duan and Sun
     354             :    * is well approximated by a simple linear fit (R^2 = 0.9997).
     355             :    *
     356             :    * Note: as the effect of salt mass fraction is small, it is not included in this function.
     357             :    *
     358             :    * @param temperature fluid temperature (K)
     359             :    * @return enthalpy of dissolution (J/kg)
     360             :    */
     361             :   ADReal enthalpyOfDissolution(const ADReal & temperature) const;
     362             : 
     363             :   /**
     364             :    * Mole fractions of CO2 in brine and water vapor in CO2 at equilibrium in the low
     365             :    * temperature regime (T <= 99C).
     366             :    *
     367             :    * @param pressure phase pressure (Pa)
     368             :    * @param temperature phase temperature (K)
     369             :    * @param Xnacl NaCl mass fraction (kg/kg)
     370             :    * @param[out] xco2 mole fraction of CO2 in liquid
     371             :    * @param[out] yh2o mass fraction of mole in gas
     372             :    */
     373             :   void equilibriumMoleFractionsLowTemp(const ADReal & pressure,
     374             :                                        const ADReal & temperature,
     375             :                                        const ADReal & Xnacl,
     376             :                                        ADReal & xco2,
     377             :                                        ADReal & yh2o) const;
     378             : 
     379             :   /**
     380             :    * Function to solve for yh2o and xco2 iteratively in the elevated temperature regime (T > 100C)
     381             :    *
     382             :    * @param pressure gas pressure (Pa)
     383             :    * @param temperature fluid temperature (K)
     384             :    * @param Xnacl NaCl mass fraction (kg/kg)
     385             :    * @param co2_density CO2 density (kg/m^3)
     386             :    * @param[out] xco2 mole fraction of CO2 in liquid phase (-)
     387             :    * @param[out] yh2o mole fraction of H2O in gas phase (-)
     388             :    */
     389             :   void solveEquilibriumMoleFractionHighTemp(Real pressure,
     390             :                                             Real temperature,
     391             :                                             Real Xnacl,
     392             :                                             Real co2_density,
     393             :                                             Real & xco2,
     394             :                                             Real & yh2o) const;
     395             : 
     396             : protected:
     397             :   /// Check the input variables
     398             :   virtual void checkVariables(Real pressure, Real temperature) const;
     399             : 
     400             :   /**
     401             :    * Cubic function to smoothly interpolate between the low temperature and elevated
     402             :    * temperature models for 99C < T < 109C
     403             :    *
     404             :    * @param temperature temperature (K)
     405             :    * @param f0 function value at T = 372K (99C)
     406             :    * @param df0 derivative of function at T = 372K (99C)
     407             :    * @param f1 function value at T = 382K (109C)
     408             :    * @param df1 derivative of function at T = 382K (109C)
     409             :    * @param[out] value value at the given temperature
     410             :    * @param[out] deriv derivative at the given temperature
     411             :    */
     412             :   void smoothCubicInterpolation(
     413             :       Real temperature, Real f0, Real df0, Real f1, Real df1, Real & value, Real & deriv) const;
     414             : 
     415             :   ///@{
     416             :   /**
     417             :    * The function A (Eq. (11) of Spycher, Pruess and Ennis-King (2003) for T <= 100C,
     418             :    * and Eqs. (10) and (17) of Spycher and Pruess (2010) for T > 100C)
     419             :    *
     420             :    * @param pressure gas pressure (Pa)
     421             :    * @param temperature fluid temperature (K)
     422             :    * @param Xnacl NaCl mass fraction (kg/kg)
     423             :    * @param co2_density CO2 density (kg/m^3)
     424             :    * @param xco2 mole fraction of CO2 in liquid phase (-)
     425             :    * @param yh2o mole fraction of H2O in gas phase (-)
     426             :    * @param[out] A the function A
     427             :    * @param[out] B the function B
     428             :    */
     429             :   void funcABHighTemp(Real pressure,
     430             :                       Real temperature,
     431             :                       Real Xnacl,
     432             :                       Real co2_density,
     433             :                       Real xco2,
     434             :                       Real yh2o,
     435             :                       Real & A,
     436             :                       Real & B) const;
     437             : 
     438             :   void funcABHighTemp(Real pressure,
     439             :                       Real temperature,
     440             :                       Real Xnacl,
     441             :                       Real co2_density,
     442             :                       Real xco2,
     443             :                       Real yh2o,
     444             :                       Real & A,
     445             :                       Real & dA_dp,
     446             :                       Real & dA_dT,
     447             :                       Real & B,
     448             :                       Real & dB_dp,
     449             :                       Real & dB_dT,
     450             :                       Real & dB_dX) const;
     451             : 
     452             :   void funcABLowTemp(const ADReal & pressure,
     453             :                      const ADReal & temperature,
     454             :                      const ADReal & co2_density,
     455             :                      ADReal & A,
     456             :                      ADReal & B) const;
     457             :   ///@}
     458             : 
     459             :   /// Salt component index
     460             :   const unsigned int _salt_component;
     461             :   /// Fluid properties UserObject for water
     462             :   const BrineFluidProperties & _brine_fp;
     463             :   /// Fluid properties UserObject for the CO2
     464             :   const SinglePhaseFluidProperties & _co2_fp;
     465             :   /// Molar mass of water (kg/mol)
     466             :   const Real _Mh2o;
     467             :   /// Inverse of molar mass of H2O (mol/kg)
     468             :   const Real _invMh2o;
     469             :   /// Molar mass of CO2 (kg/mol)
     470             :   const Real _Mco2;
     471             :   /// Molar mass of NaCL
     472             :   const Real _Mnacl;
     473             :   /// Molar gas constant in bar cm^3 /(K mol)
     474             :   const Real _Rbar;
     475             :   /// Temperature below which the Spycher, Pruess & Ennis-King (2003) model is used (K)
     476             :   const Real _Tlower;
     477             :   /// Temperature above which the Spycher & Pruess (2010) model is used (K)
     478             :   const Real _Tupper;
     479             :   /// Minimum Z - below this value all CO2 will be dissolved. This reduces the
     480             :   /// computational burden when small values of Z are present
     481             :   const Real _Zmin;
     482             :   /// Henry's coefficeients for CO2
     483             :   const std::vector<Real> _co2_henry;
     484             : };

Generated by: LCOV version 1.14