LCOV - code coverage report
Current view: top level - src/fluidproperties - CO2FluidProperties.C (source / functions) Hit Total Coverage
Test: idaholab/moose fluid_properties: #31405 (292dce) with base fef103 Lines: 347 365 95.1 %
Date: 2025-09-04 07:53:14 Functions: 37 38 97.4 %
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             : #include "CO2FluidProperties.h"
      11             : #include "BrentsMethod.h"
      12             : #include "Conversion.h"
      13             : #include "MathUtils.h"
      14             : #include "libmesh/utility.h"
      15             : 
      16             : registerMooseObject("FluidPropertiesApp", CO2FluidProperties);
      17             : 
      18             : InputParameters
      19         268 : CO2FluidProperties::validParams()
      20             : {
      21         268 :   InputParameters params = HelmholtzFluidProperties::validParams();
      22         268 :   params.addClassDescription(
      23             :       "Fluid properties for carbon dioxide (CO2) using the Span & Wagner EOS");
      24         268 :   return params;
      25           0 : }
      26             : 
      27         146 : CO2FluidProperties::CO2FluidProperties(const InputParameters & parameters)
      28         146 :   : HelmholtzFluidProperties(parameters)
      29             : {
      30         146 : }
      31             : 
      32         256 : CO2FluidProperties::~CO2FluidProperties() {}
      33             : 
      34             : std::string
      35          10 : CO2FluidProperties::fluidName() const
      36             : {
      37          10 :   return "co2";
      38             : }
      39             : 
      40             : Real
      41    95275501 : CO2FluidProperties::molarMass() const
      42             : {
      43    95275501 :   return _Mco2;
      44             : }
      45             : 
      46             : Real
      47           3 : CO2FluidProperties::criticalPressure() const
      48             : {
      49           3 :   return _critical_pressure;
      50             : }
      51             : 
      52             : Real
      53    95275502 : CO2FluidProperties::criticalTemperature() const
      54             : {
      55    95275502 :   return _critical_temperature;
      56             : }
      57             : 
      58             : Real
      59    95275502 : CO2FluidProperties::criticalDensity() const
      60             : {
      61    95275502 :   return _critical_density;
      62             : }
      63             : 
      64             : Real
      65           3 : CO2FluidProperties::triplePointPressure() const
      66             : {
      67           3 :   return _triple_point_pressure;
      68             : }
      69             : 
      70             : Real
      71           3 : CO2FluidProperties::triplePointTemperature() const
      72             : {
      73           3 :   return _triple_point_temperature;
      74             : }
      75             : 
      76             : Real
      77     8142410 : CO2FluidProperties::meltingPressure(Real temperature) const
      78             : {
      79     8142410 :   if (temperature < _triple_point_temperature)
      80           0 :     throw MooseException("Temperature is below the triple point temperature in " + name() +
      81           0 :                          ": meltingPressure()");
      82             : 
      83     8142410 :   Real Tstar = temperature / _triple_point_temperature;
      84             : 
      85     8142410 :   return _triple_point_pressure *
      86     8142410 :          (1.0 + 1955.539 * (Tstar - 1.0) + 2055.4593 * Utility::pow<2>(Tstar - 1.0));
      87             : }
      88             : 
      89             : Real
      90           1 : CO2FluidProperties::sublimationPressure(Real temperature) const
      91             : {
      92           1 :   if (temperature > _triple_point_temperature)
      93           0 :     throw MooseException("Temperature is above the triple point temperature in " + name() +
      94           0 :                          ": sublimationPressure()");
      95             : 
      96           1 :   Real Tstar = temperature / _triple_point_temperature;
      97             : 
      98           1 :   Real pressure = _triple_point_pressure *
      99           1 :                   std::exp((-14.740846 * (1.0 - Tstar) + 2.4327015 * std::pow(1.0 - Tstar, 1.9) -
     100           1 :                             5.3061778 * std::pow(1.0 - Tstar, 2.9)) /
     101           1 :                            Tstar);
     102             : 
     103           1 :   return pressure;
     104             : }
     105             : 
     106             : Real
     107       11061 : CO2FluidProperties::vaporPressure(Real temperature) const
     108             : {
     109       11061 :   if (temperature < _triple_point_temperature || temperature > _critical_temperature)
     110           0 :     throw MooseException("Temperature is out of range in " + name() + ": vaporPressure()");
     111             : 
     112       11061 :   Real Tstar = temperature / _critical_temperature;
     113             : 
     114             :   Real logpressure =
     115       11061 :       (-7.0602087 * (1.0 - Tstar) + 1.9391218 * std::pow(1.0 - Tstar, 1.5) -
     116       11061 :        1.6463597 * Utility::pow<2>(1.0 - Tstar) - 3.2995634 * Utility::pow<4>(1.0 - Tstar)) /
     117       11061 :       Tstar;
     118             : 
     119       11061 :   return _critical_pressure * std::exp(logpressure);
     120             : }
     121             : 
     122             : void
     123           0 : CO2FluidProperties::vaporPressure(Real, Real &, Real &) const
     124             : {
     125           0 :   mooseError("vaporPressure() is not implemented");
     126             : }
     127             : 
     128             : Real
     129     7491478 : CO2FluidProperties::saturatedLiquidDensity(Real temperature) const
     130             : {
     131     7491478 :   if (temperature < _triple_point_temperature || temperature > _critical_temperature)
     132           0 :     throw MooseException("Temperature is out of range in " + name() + ": saturatedLiquiDensity()");
     133             : 
     134     7491478 :   Real Tstar = temperature / _critical_temperature;
     135             : 
     136     7491478 :   Real logdensity = 1.9245108 * std::pow(1.0 - Tstar, 0.34) -
     137     7491478 :                     0.62385555 * std::pow(1.0 - Tstar, 0.5) -
     138     7491478 :                     0.32731127 * std::pow(1.0 - Tstar, 10.0 / 6.0) +
     139     7491478 :                     0.39245142 * std::pow(1.0 - Tstar, 11.0 / 6.0);
     140             : 
     141     7491478 :   return _critical_density * std::exp(logdensity);
     142             : }
     143             : 
     144             : Real
     145     7491478 : CO2FluidProperties::saturatedVaporDensity(Real temperature) const
     146             : {
     147     7491478 :   if (temperature < _triple_point_temperature || temperature > _critical_temperature)
     148           0 :     throw MooseException("Temperature is out of range in " + name() + ": saturatedVaporDensity()");
     149             : 
     150     7491478 :   Real Tstar = temperature / _critical_temperature;
     151             : 
     152             :   Real logdensity =
     153     7491478 :       (-1.7074879 * std::pow(1.0 - Tstar, 0.34) - 0.82274670 * std::pow(1.0 - Tstar, 0.5) -
     154     7491478 :        4.6008549 * (1.0 - Tstar) - 10.111178 * std::pow(1.0 - Tstar, 7.0 / 3.0) -
     155     7491478 :        29.742252 * std::pow(1.0 - Tstar, 14.0 / 3.0));
     156             : 
     157     7491478 :   return _critical_density * std::exp(logdensity);
     158             : }
     159             : 
     160             : Real
     161      900264 : CO2FluidProperties::alpha(Real delta, Real tau) const
     162             : {
     163             :   // Ideal gas component of the Helmholtz free energy
     164             :   Real sum0 = 0.0;
     165     5401584 :   for (std::size_t i = 0; i < _a0.size(); ++i)
     166     4501320 :     sum0 += _a0[i] * std::log(1.0 - std::exp(-_theta0[i] * tau));
     167             : 
     168      900264 :   Real phi0 = std::log(delta) + 8.37304456 - 3.70454304 * tau + 2.5 * std::log(tau) + sum0;
     169             : 
     170             :   // Residual component of the Helmholtz free energy
     171             :   Real theta, Delta, Psi;
     172             :   Real phir = 0.0;
     173     7202112 :   for (std::size_t i = 0; i < _n1.size(); ++i)
     174     6301848 :     phir += _n1[i] * MathUtils::pow(delta, _d1[i]) * std::pow(tau, _t1[i]);
     175             : 
     176    25207392 :   for (std::size_t i = 0; i < _n2.size(); ++i)
     177    24307128 :     phir += _n2[i] * MathUtils::pow(delta, _d2[i]) * std::pow(tau, _t2[i]) *
     178    24307128 :             std::exp(-MathUtils::pow(delta, _c2[i]));
     179             : 
     180     5401584 :   for (std::size_t i = 0; i < _n3.size(); ++i)
     181     4501320 :     phir += _n3[i] * MathUtils::pow(delta, _d3[i]) * MathUtils::pow(tau, _t3[i]) *
     182     4501320 :             std::exp(-_alpha3[i] * Utility::pow<2>(delta - _eps3[i]) -
     183     4501320 :                      _beta3[i] * Utility::pow<2>(tau - _gamma3[i]));
     184             : 
     185     3601056 :   for (std::size_t i = 0; i < _n4.size(); ++i)
     186             :   {
     187     2700792 :     theta = 1.0 - tau + _A4[i] * std::pow(Utility::pow<2>(delta - 1.0), 1.0 / (2.0 * _beta4[i]));
     188     2700792 :     Delta = Utility::pow<2>(theta) + _B4[i] * std::pow(Utility::pow<2>(delta - 1.0), _a4[i]);
     189     2700792 :     Psi = std::exp(-_C4[i] * Utility::pow<2>(delta - 1.0) - _D4[i] * Utility::pow<2>(tau - 1.0));
     190     2700792 :     phir += _n4[i] * std::pow(Delta, _b4[i]) * delta * Psi;
     191             :   }
     192             : 
     193             :   // The Helmholtz free energy is the sum of these components
     194      900264 :   return phi0 + phir;
     195             : }
     196             : 
     197             : Real
     198    92564697 : CO2FluidProperties::dalpha_ddelta(Real delta, Real tau) const
     199             : {
     200             :   // Derivative of the ideal gas component wrt gamma
     201    92564697 :   Real dphi0dd = 1.0 / delta;
     202             : 
     203             :   // Derivative of the residual component wrt gamma
     204             :   Real theta, Delta, Psi, dDelta_dd, dPsi_dd;
     205             :   Real dphirdd = 0.0;
     206             : 
     207   740517576 :   for (std::size_t i = 0; i < _n1.size(); ++i)
     208   647952879 :     dphirdd += _n1[i] * _d1[i] * MathUtils::pow(delta, _d1[i] - 1.0) * std::pow(tau, _t1[i]);
     209             : 
     210  2591811516 :   for (std::size_t i = 0; i < _n2.size(); ++i)
     211  2499246819 :     dphirdd += _n2[i] * std::exp(-MathUtils::pow(delta, _c2[i])) *
     212  2499246819 :                (MathUtils::pow(delta, _d2[i] - 1.0) * std::pow(tau, _t2[i]) *
     213  2499246819 :                 (_d2[i] - _c2[i] * MathUtils::pow(delta, _c2[i])));
     214             : 
     215   555388182 :   for (std::size_t i = 0; i < _n3.size(); ++i)
     216   462823485 :     dphirdd += _n3[i] * MathUtils::pow(delta, _d3[i]) * MathUtils::pow(tau, _t3[i]) *
     217   462823485 :                std::exp(-_alpha3[i] * Utility::pow<2>(delta - _eps3[i]) -
     218   462823485 :                         _beta3[i] * Utility::pow<2>(tau - _gamma3[i])) *
     219   462823485 :                (_d3[i] / delta - 2.0 * _alpha3[i] * (delta - _eps3[i]));
     220             : 
     221   370258788 :   for (std::size_t i = 0; i < _n4.size(); ++i)
     222             :   {
     223   277694091 :     theta = 1.0 - tau + _A4[i] * std::pow(Utility::pow<2>(delta - 1.0), 1.0 / (2.0 * _beta4[i]));
     224   277694091 :     Delta = Utility::pow<2>(theta) + _B4[i] * std::pow(Utility::pow<2>(delta - 1.0), _a4[i]);
     225   277694091 :     Psi = std::exp(-_C4[i] * Utility::pow<2>(delta - 1.0) - _D4[i] * Utility::pow<2>(tau - 1.0));
     226   277694091 :     dPsi_dd = -2.0 * _C4[i] * (delta - 1.0) * Psi;
     227   277694091 :     dDelta_dd = (delta - 1.0) *
     228   277694091 :                 (_A4[i] * theta * 2.0 / _beta4[i] *
     229   277694091 :                      std::pow(Utility::pow<2>(delta - 1.0), 1.0 / (2.0 * _beta4[i]) - 1.0) +
     230   277694091 :                  2.0 * _B4[i] * _a4[i] * std::pow(Utility::pow<2>(delta - 1.0), _a4[i] - 1.0));
     231             : 
     232   277694091 :     dphirdd += _n4[i] * (std::pow(Delta, _b4[i]) * (Psi + delta * dPsi_dd) +
     233   277694091 :                          _b4[i] * std::pow(Delta, _b4[i] - 1.0) * dDelta_dd * delta * Psi);
     234             :   }
     235             : 
     236             :   // The derivative of the free energy wrt delta is the sum of these components
     237    92564697 :   return dphi0dd + dphirdd;
     238             : }
     239             : 
     240             : Real
     241     2720813 : CO2FluidProperties::dalpha_dtau(Real delta, Real tau) const
     242             : {
     243             :   // Derivative of the ideal gas component wrt tau
     244             :   Real sum0 = 0.0;
     245    16324878 :   for (std::size_t i = 0; i < _a0.size(); ++i)
     246    13604065 :     sum0 += _a0[i] * _theta0[i] * (1.0 / (1.0 - std::exp(-_theta0[i] * tau)) - 1.0);
     247             : 
     248     2720813 :   Real dphi0dt = -3.70454304 + 2.5 / tau + sum0;
     249             : 
     250             :   // Derivative of the residual component wrt tau
     251             :   Real theta, Delta, Psi, dDelta_dt, dPsi_dt;
     252             :   Real dphirdt = 0.0;
     253    21766504 :   for (std::size_t i = 0; i < _n1.size(); ++i)
     254    19045691 :     dphirdt += _n1[i] * _t1[i] * MathUtils::pow(delta, _d1[i]) * std::pow(tau, _t1[i] - 1.0);
     255             : 
     256    76182764 :   for (std::size_t i = 0; i < _n2.size(); ++i)
     257    73461951 :     dphirdt += _n2[i] * _t2[i] * MathUtils::pow(delta, _d2[i]) * std::pow(tau, _t2[i] - 1.0) *
     258    73461951 :                std::exp(-MathUtils::pow(delta, _c2[i]));
     259             : 
     260    16324878 :   for (std::size_t i = 0; i < _n3.size(); ++i)
     261    13604065 :     dphirdt += _n3[i] * MathUtils::pow(delta, _d3[i]) * MathUtils::pow(tau, _t3[i]) *
     262    13604065 :                std::exp(-_alpha3[i] * Utility::pow<2>(delta - _eps3[i]) -
     263    13604065 :                         _beta3[i] * Utility::pow<2>(tau - _gamma3[i])) *
     264    13604065 :                (_t3[i] / tau - 2.0 * _beta3[i] * (tau - _gamma3[i]));
     265             : 
     266    10883252 :   for (std::size_t i = 0; i < _n4.size(); ++i)
     267             :   {
     268     8162439 :     theta = 1.0 - tau + _A4[i] * std::pow(Utility::pow<2>(delta - 1.0), 1.0 / (2.0 * _beta4[i]));
     269     8162439 :     Delta = Utility::pow<2>(theta) + _B4[i] * std::pow(Utility::pow<2>(delta - 1.0), _a4[i]);
     270     8162439 :     Psi = std::exp(-_C4[i] * Utility::pow<2>(delta - 1.0) - _D4[i] * Utility::pow<2>(tau - 1.0));
     271     8162439 :     dDelta_dt = -2.0 * theta * _b4[i] * std::pow(Delta, _b4[i] - 1.0);
     272     8162439 :     dPsi_dt = -2.0 * _D4[i] * (tau - 1.0) * Psi;
     273             : 
     274     8162439 :     dphirdt += _n4[i] * delta * (Psi * dDelta_dt + std::pow(Delta, _b4[i]) * dPsi_dt);
     275             :   }
     276             : 
     277             :   // The derivative of the free energy wrt tau is the sum of these components
     278     2720813 :   return dphi0dt + dphirdt;
     279             : }
     280             : 
     281             : Real
     282     1800512 : CO2FluidProperties::d2alpha_ddelta2(Real delta, Real tau) const
     283             : {
     284             :   // Second derivative of the ideal gas component wrt gamma
     285     1800512 :   Real d2phi0dd2 = -1.0 / delta / delta;
     286             : 
     287             :   // Second derivative of the residual component wrt gamma
     288             :   Real d2phirdd2 = 0.0;
     289             :   Real theta, Delta, Psi, dDelta_dd, dPsi_dd, d2Delta_dd2, d2Psi_dd2;
     290             : 
     291    14404096 :   for (std::size_t i = 0; i < _n1.size(); ++i)
     292    12603584 :     d2phirdd2 += _n1[i] * _d1[i] * (_d1[i] - 1.0) * MathUtils::pow(delta, _d1[i] - 2) *
     293    12603584 :                  std::pow(tau, _t1[i]);
     294             : 
     295    50414336 :   for (std::size_t i = 0; i < _n2.size(); ++i)
     296    48613824 :     d2phirdd2 += _n2[i] * std::exp(-MathUtils::pow(delta, _c2[i])) *
     297    48613824 :                  MathUtils::pow(delta, _d2[i] - 2) * std::pow(tau, _t2[i]) *
     298    48613824 :                  ((_d2[i] - _c2[i] * MathUtils::pow(delta, _c2[i])) *
     299    48613824 :                       (_d2[i] - 1.0 - _c2[i] * MathUtils::pow(delta, _c2[i])) -
     300    48613824 :                   _c2[i] * _c2[i] * MathUtils::pow(delta, _c2[i]));
     301             : 
     302    10803072 :   for (std::size_t i = 0; i < _n3.size(); ++i)
     303     9002560 :     d2phirdd2 +=
     304     9002560 :         _n3[i] * MathUtils::pow(tau, _t3[i]) *
     305     9002560 :         std::exp(-_alpha3[i] * Utility::pow<2>(delta - _eps3[i]) -
     306     9002560 :                  _beta3[i] * Utility::pow<2>(tau - _gamma3[i])) *
     307     9002560 :         (-2.0 * _alpha3[i] * MathUtils::pow(delta, _d3[i]) +
     308     9002560 :          4.0 * _alpha3[i] * _alpha3[i] * MathUtils::pow(delta, _d3[i]) *
     309     9002560 :              Utility::pow<2>(delta - _eps3[i]) -
     310     9002560 :          4.0 * _d3[i] * _alpha3[i] * MathUtils::pow(delta, _d3[i] - 1.0) * (delta - _eps3[i]) +
     311     9002560 :          _d3[i] * (_d3[i] - 1.0) * MathUtils::pow(delta, _d3[i] - 2.0));
     312             : 
     313     7202048 :   for (std::size_t i = 0; i < _n4.size(); ++i)
     314             :   {
     315     5401536 :     theta = 1.0 - tau + _A4[i] * std::pow(Utility::pow<2>(delta - 1.0), 1.0 / (2.0 * _beta4[i]));
     316     5401536 :     Delta = Utility::pow<2>(theta) + _B4[i] * std::pow(Utility::pow<2>(delta - 1.0), _a4[i]);
     317     5401536 :     Psi = std::exp(-_C4[i] * Utility::pow<2>(delta - 1.0) - _D4[i] * Utility::pow<2>(tau - 1.0));
     318     5401536 :     dPsi_dd = -2.0 * _C4[i] * (delta - 1.0) * Psi;
     319     5401536 :     dDelta_dd = (delta - 1.0) *
     320     5401536 :                 (_A4[i] * theta * 2.0 / _beta4[i] *
     321     5401536 :                      std::pow(Utility::pow<2>(delta - 1.0), 1.0 / (2.0 * _beta4[i]) - 1.0) +
     322     5401536 :                  2.0 * _B4[i] * _a4[i] * std::pow(Utility::pow<2>(delta - 1.0), _a4[i] - 1.0));
     323     5401536 :     d2Psi_dd2 = 3.0 * _D4[i] * Psi * (2.0 * _C4[i] * Utility::pow<2>(delta - 1.0) - 1.0);
     324     5401536 :     d2Delta_dd2 = 1.0 / (delta - 1.0) * dDelta_dd +
     325     5401536 :                   (delta - 1.0) * (delta - 1.0) *
     326     5401536 :                       (4.0 * _B4[i] * _a4[i] * (_a4[i] - 1.0) *
     327     5401536 :                            std::pow(Utility::pow<2>(delta - 1.0), _a4[i] - 2.0) +
     328     5401536 :                        2.0 * _A4[i] * _A4[i] *
     329     5401536 :                            Utility::pow<2>(std::pow(Utility::pow<2>(delta - 1.0),
     330     5401536 :                                                     1.0 / (2.0 * _beta4[i]) - 1.0)) /
     331     5401536 :                            _beta4[i] / _beta4[i] +
     332     5401536 :                        (4.0 / _beta4[i]) * _A4[i] * theta * (1.0 / (2.0 * _beta4[i]) - 1.0) *
     333     5401536 :                            std::pow(Utility::pow<2>(delta - 1.0), 1.0 / (2.0 * _beta4[i]) - 2.0));
     334     5401536 :     d2phirdd2 +=
     335     5401536 :         _n4[i] *
     336     5401536 :         (std::pow(Delta, _b4[i]) * (2.0 * dPsi_dd + delta * d2Psi_dd2) +
     337     5401536 :          2.0 * _b4[i] * std::pow(Delta, _b4[i] - 1.0) * dDelta_dd * (Psi + delta * dPsi_dd) +
     338     5401536 :          _b4[i] *
     339     5401536 :              (std::pow(Delta, _b4[i] - 1.0) * d2Delta_dd2 +
     340     5401536 :               (_b4[i] - 1.0) * std::pow(Delta, _b4[i] - 2.0) * Utility::pow<2>(dDelta_dd)) *
     341     5401536 :              delta * Psi);
     342             :   }
     343             :   // The second derivative of the free energy wrt delta is the sum of these components
     344     1800512 :   return d2phi0dd2 + d2phirdd2;
     345             : }
     346             : 
     347             : Real
     348     2700759 : CO2FluidProperties::d2alpha_dtau2(Real delta, Real tau) const
     349             : {
     350             :   // Second derivative of the ideal gas component wrt tau
     351             :   Real sum0 = 0.0;
     352    16204554 :   for (std::size_t i = 0; i < _a0.size(); ++i)
     353    13503795 :     sum0 += _a0[i] * _theta0[i] * _theta0[i] * std::exp(-_theta0[i] * tau) /
     354    13503795 :             Utility::pow<2>(1.0 - std::exp(-_theta0[i] * tau));
     355             : 
     356     2700759 :   Real d2phi0dt2 = -2.5 / tau / tau - sum0;
     357             : 
     358             :   // Second derivative of the residual component wrt tau
     359             :   Real d2phirdt2 = 0.0;
     360             :   Real theta, Delta, Psi, dPsi_dt, dDelta_dt, d2Delta_dt2, d2Psi_dt2;
     361             : 
     362    21606072 :   for (std::size_t i = 0; i < _n1.size(); ++i)
     363    18905313 :     d2phirdt2 += _n1[i] * _t1[i] * (_t1[i] - 1.0) * MathUtils::pow(delta, _d1[i]) *
     364    18905313 :                  std::pow(tau, _t1[i] - 2.0);
     365             : 
     366    75621252 :   for (std::size_t i = 0; i < _n2.size(); ++i)
     367    72920493 :     d2phirdt2 += _n2[i] * _t2[i] * (_t2[i] - 1.0) * MathUtils::pow(delta, _d2[i]) *
     368    72920493 :                  std::exp(-MathUtils::pow(delta, _c2[i])) * std::pow(tau, _t2[i] - 2.0);
     369             : 
     370    16204554 :   for (std::size_t i = 0; i < _n3.size(); ++i)
     371    13503795 :     d2phirdt2 += _n3[i] * MathUtils::pow(delta, _d3[i]) * MathUtils::pow(tau, _t3[i]) *
     372    13503795 :                  std::exp(-_alpha3[i] * Utility::pow<2>(delta - _eps3[i]) -
     373    13503795 :                           _beta3[i] * Utility::pow<2>(tau - _gamma3[i])) *
     374    13503795 :                  (Utility::pow<2>(_t3[i] / tau - 2.0 * _beta3[i] * (tau - _gamma3[i])) -
     375    13503795 :                   _t3[i] / tau / tau - 2.0 * _beta3[i]);
     376             : 
     377    10803036 :   for (std::size_t i = 0; i < _n4.size(); ++i)
     378             :   {
     379     8102277 :     theta = 1.0 - tau + _A4[i] * std::pow(Utility::pow<2>(delta - 1.0), 1.0 / (2.0 * _beta4[i]));
     380     8102277 :     Delta = Utility::pow<2>(theta) + _B4[i] * std::pow(Utility::pow<2>(delta - 1.0), _a4[i]);
     381     8102277 :     Psi = std::exp(-_C4[i] * Utility::pow<2>(delta - 1.0) - _D4[i] * Utility::pow<2>(tau - 1.0));
     382     8102277 :     dDelta_dt = -2.0 * theta * _b4[i] * std::pow(Delta, _b4[i] - 1.0);
     383     8102277 :     d2Delta_dt2 = 2.0 * _b4[i] * std::pow(Delta, _b4[i] - 1.0) +
     384     8102277 :                   4.0 * theta * theta * _b4[i] * (_b4[i] - 1.0) * std::pow(Delta, _b4[i] - 2.0);
     385     8102277 :     dPsi_dt = -2.0 * _D4[i] * (tau - 1.0) * Psi;
     386     8102277 :     d2Psi_dt2 = 2.0 * _D4[i] * (2.0 * _D4[i] * (tau - 1.0) * (tau - 1.0) - 1.0) * Psi;
     387     8102277 :     d2phirdt2 +=
     388     8102277 :         _n4[i] * delta *
     389     8102277 :         (Psi * d2Delta_dt2 + 2.0 * dDelta_dt * dPsi_dt + std::pow(Delta, _b4[i]) * d2Psi_dt2);
     390             :   }
     391             : 
     392             :   // The second derivative of the free energy wrt tau is the sum of these components
     393     2700759 :   return d2phi0dt2 + d2phirdt2;
     394             : }
     395             : 
     396             : Real
     397     1800512 : CO2FluidProperties::d2alpha_ddeltatau(Real delta, Real tau) const
     398             : {
     399             :   // Note: second derivative of the ideal gas component wrt delta and tau is 0
     400             :   // Derivative of the residual component wrt gamma
     401             :   Real theta, Delta, Psi, dDelta_dd, dPsi_dd, dDelta_dt, dPsi_dt, d2Delta_ddt, d2Psi_ddt;
     402             :   Real d2phirddt = 0.0;
     403    14404096 :   for (std::size_t i = 0; i < _n1.size(); ++i)
     404    12603584 :     d2phirddt += _n1[i] * _d1[i] * _t1[i] * MathUtils::pow(delta, _d1[i] - 1.0) *
     405    12603584 :                  std::pow(tau, _t1[i] - 1.0);
     406             : 
     407    50414336 :   for (std::size_t i = 0; i < _n2.size(); ++i)
     408    48613824 :     d2phirddt += _n2[i] * std::exp(-MathUtils::pow(delta, _c2[i])) *
     409    48613824 :                  (MathUtils::pow(delta, _d2[i] - 1.0) * _t2[i] * std::pow(tau, _t2[i] - 1.0) *
     410    48613824 :                   (_d2[i] - _c2[i] * MathUtils::pow(delta, _c2[i])));
     411             : 
     412    10803072 :   for (std::size_t i = 0; i < _n3.size(); ++i)
     413     9002560 :     d2phirddt += _n3[i] * MathUtils::pow(delta, _d3[i]) * MathUtils::pow(tau, _t3[i]) *
     414     9002560 :                  std::exp(-_alpha3[i] * Utility::pow<2>(delta - _eps3[i]) -
     415     9002560 :                           _beta3[i] * Utility::pow<2>(tau - _gamma3[i])) *
     416     9002560 :                  (_d3[i] / delta - 2.0 * _alpha3[i] * (delta - _eps3[i])) *
     417     9002560 :                  (_t3[i] / tau - 2.0 * _beta3[i] * (tau - _gamma3[i]));
     418             : 
     419     7202048 :   for (std::size_t i = 0; i < _n4.size(); ++i)
     420             :   {
     421     5401536 :     theta = 1.0 - tau + _A4[i] * std::pow(Utility::pow<2>(delta - 1.0), 1.0 / (2.0 * _beta4[i]));
     422     5401536 :     Delta = Utility::pow<2>(theta) + _B4[i] * std::pow(Utility::pow<2>(delta - 1.0), _a4[i]);
     423     5401536 :     Psi = std::exp(-_C4[i] * Utility::pow<2>(delta - 1.0) - _D4[i] * Utility::pow<2>(tau - 1.0));
     424     5401536 :     dPsi_dd = -2.0 * _C4[i] * (delta - 1.0) * Psi;
     425     5401536 :     dPsi_dt = -2.0 * _D4[i] * (tau - 1.0) * Psi;
     426     5401536 :     d2Psi_ddt = 4.0 * _C4[i] * _D4[i] * (delta - 1.0) * (tau - 1.0) * Psi;
     427     5401536 :     dDelta_dd = (delta - 1.0) *
     428     5401536 :                 (_A4[i] * theta * 2.0 / _beta4[i] *
     429     5401536 :                      std::pow(Utility::pow<2>(delta - 1.0), 1.0 / (2.0 * _beta4[i]) - 1.0) +
     430     5401536 :                  2.0 * _B4[i] * _a4[i] * std::pow(Utility::pow<2>(delta - 1.0), _a4[i] - 1.0));
     431     5401536 :     dDelta_dt = -2.0 * theta * _b4[i] * std::pow(Delta, _b4[i] - 1.0);
     432     5401536 :     d2Delta_ddt = -2.0 * _A4[i] * _b4[i] / _beta4[i] * std::pow(Delta, _b4[i] - 1.0) *
     433     5401536 :                       (delta - 1.0) *
     434     5401536 :                       std::pow(Utility::pow<2>(delta - 1.0), 1.0 / (2.0 * _beta4[i]) - 1.0) -
     435     5401536 :                   2.0 * theta * _b4[i] * (_b4[i] - 1.0) * std::pow(Delta, _b4[i] - 2.0) * dDelta_dd;
     436             : 
     437     5401536 :     d2phirddt += _n4[i] * (std::pow(Delta, _b4[i]) * (dPsi_dt + delta * d2Psi_ddt) +
     438     5401536 :                            delta * _b4[i] * std::pow(Delta, _b4[i] - 1.0) * dDelta_dd * dPsi_dt +
     439     5401536 :                            dDelta_dt * (Psi + delta * dPsi_dd) + d2Delta_ddt * delta * Psi);
     440             :   }
     441             : 
     442     1800512 :   return d2phirddt;
     443             : }
     444             : 
     445             : Real
     446    89864966 : CO2FluidProperties::p_from_rho_T(Real density, Real temperature) const
     447             : {
     448             :   // Check that the input parameters are within the region of validity
     449    89864966 :   if (temperature < 216.0 || temperature > 1100.0 || density <= 0.0)
     450           0 :     throw MooseException("Parameters out of range in " + name() + ": pressure()");
     451             : 
     452             :   Real pressure = 0.0;
     453             : 
     454    89864966 :   if (temperature > _triple_point_temperature && temperature < _critical_temperature)
     455             :   {
     456     7491475 :     Real gas_density = saturatedVaporDensity(temperature);
     457     7491475 :     Real liquid_density = saturatedLiquidDensity(temperature);
     458             : 
     459     7491475 :     if (density < gas_density || density > liquid_density)
     460     7480419 :       pressure = HelmholtzFluidProperties::p_from_rho_T(density, temperature);
     461             :     else
     462       11056 :       pressure = vaporPressure(temperature);
     463             :   }
     464             :   else
     465    82373491 :     pressure = HelmholtzFluidProperties::p_from_rho_T(density, temperature);
     466             : 
     467    89864966 :   return pressure;
     468             : }
     469             : 
     470             : Real
     471     8142407 : CO2FluidProperties::rho_from_p_T(Real pressure, Real temperature) const
     472             : {
     473             :   // Check that the input parameters are within the region of validity
     474     8142407 :   if (temperature < 216.0 || temperature > 1100.0 || pressure <= 0.0)
     475           0 :     throw MooseException("Parameters out of range in " + name() + ": rho_from_p_T()");
     476             : 
     477             :   // Also check that the pressure and temperature are not in the solid phase region
     478     8142407 :   if (((temperature > _triple_point_temperature) && (pressure > meltingPressure(temperature))) ||
     479     8142407 :       ((temperature < _triple_point_temperature) && (pressure > sublimationPressure(temperature))))
     480           0 :     throw MooseException("Input pressure and temperature in " + name() +
     481           0 :                          ": rho_from_p_T() correspond to solid CO2 phase");
     482             : 
     483             :   Real density;
     484             :   // Initial estimate of a bracketing interval for the density
     485     8142407 :   Real lower_density = 100.0;
     486     8142407 :   Real upper_density = 1000.0;
     487             : 
     488             :   // The density is found by finding the zero of the pressure calculated using the
     489             :   // Span and Wagner EOS minus the input pressure
     490    89864966 :   auto pressure_diff = [&pressure, &temperature, this](Real x)
     491    89864966 :   { return p_from_rho_T(x, temperature) - pressure; };
     492             : 
     493     8142407 :   BrentsMethod::bracket(pressure_diff, lower_density, upper_density);
     494     8142407 :   density = BrentsMethod::root(pressure_diff, lower_density, upper_density);
     495             : 
     496     8142407 :   return density;
     497             : }
     498             : 
     499             : void
     500          10 : CO2FluidProperties::rho_from_p_T(
     501             :     Real pressure, Real temperature, Real & rho, Real & drho_dp, Real & drho_dT) const
     502             : {
     503          10 :   HelmholtzFluidProperties::rho_from_p_T(pressure, temperature, rho, drho_dp, drho_dT);
     504          10 : }
     505             : 
     506             : Real
     507      910274 : CO2FluidProperties::mu_from_p_T(Real pressure, Real temperature) const
     508             : {
     509      910274 :   Real rho = rho_from_p_T(pressure, temperature);
     510      910274 :   return mu_from_rho_T(rho, temperature);
     511             : }
     512             : 
     513             : void
     514           7 : CO2FluidProperties::mu_from_p_T(
     515             :     Real pressure, Real temperature, Real & mu, Real & dmu_dp, Real & dmu_dT) const
     516             : {
     517             :   Real rho, drho_dp, drho_dT;
     518           7 :   HelmholtzFluidProperties::rho_from_p_T(pressure, temperature, rho, drho_dp, drho_dT);
     519             : 
     520             :   Real dmu_drho;
     521           7 :   mu_from_rho_T(rho, temperature, drho_dT, mu, dmu_drho, dmu_dT);
     522           7 :   dmu_dp = dmu_drho * drho_dp;
     523           7 : }
     524             : 
     525             : Real
     526      910283 : CO2FluidProperties::mu_from_rho_T(Real density, Real temperature) const
     527             : {
     528             :   // Check that the input parameters are within the region of validity
     529      910283 :   if (temperature < 216.0 || temperature > 1000.0 || density > 1400.0)
     530           0 :     throw MooseException("Parameters out of range in " + name() + ": mu_from_rho_T()");
     531             : 
     532      910283 :   Real Tstar = temperature / 251.196;
     533             : 
     534             :   // Viscosity in the zero-density limit
     535             :   Real sum = 0.0;
     536             : 
     537     5461698 :   for (std::size_t i = 0; i < _mu_a.size(); ++i)
     538     4551415 :     sum += _mu_a[i] * MathUtils::pow(std::log(Tstar), i);
     539             : 
     540      910283 :   Real mu0 = 1.00697 * std::sqrt(temperature) / std::exp(sum);
     541             : 
     542             :   // Excess viscosity due to finite density
     543      910283 :   Real mue = _mu_d[0] * density + _mu_d[1] * Utility::pow<2>(density) +
     544      910283 :              _mu_d[2] * Utility::pow<6>(density) / Utility::pow<3>(Tstar) +
     545      910283 :              _mu_d[3] * Utility::pow<8>(density) + _mu_d[4] * Utility::pow<8>(density) / Tstar;
     546             : 
     547      910283 :   return (mu0 + mue) * 1.0e-6; // convert to Pa.s
     548             : }
     549             : 
     550             : void
     551          10 : CO2FluidProperties::mu_from_rho_T(Real density,
     552             :                                   Real temperature,
     553             :                                   Real ddensity_dT,
     554             :                                   Real & mu,
     555             :                                   Real & dmu_drho,
     556             :                                   Real & dmu_dT) const
     557             : {
     558             :   // Check that the input parameters are within the region of validity
     559          10 :   if (temperature < 216.0 || temperature > 1000.0 || density > 1400.0)
     560           0 :     throw MooseException("Parameters out of range in " + name() + ": mu_drhoT()");
     561             : 
     562          10 :   Real Tstar = temperature / 251.196;
     563             :   Real dTstar_dT = 1.0 / 251.196;
     564             : 
     565             :   // Viscosity in the zero-density limit. Note this is only a function of T.
     566             :   // Start the sum at i = 1 so the derivative is defined
     567          10 :   Real sum0 = _mu_a[0], dsum0_dTstar = 0.0;
     568             : 
     569          50 :   for (std::size_t i = 1; i < _mu_a.size(); ++i)
     570             :   {
     571          40 :     sum0 += _mu_a[i] * MathUtils::pow(std::log(Tstar), i);
     572          40 :     dsum0_dTstar += i * _mu_a[i] * MathUtils::pow(std::log(Tstar), i - 1) / Tstar;
     573             :   }
     574             : 
     575          10 :   Real mu0 = 1.00697 * std::sqrt(temperature) / std::exp(sum0);
     576          10 :   Real dmu0_dT = (0.5 * 1.00697 / std::sqrt(temperature) -
     577          10 :                   1.00697 * std::sqrt(temperature) * dsum0_dTstar * dTstar_dT) /
     578          10 :                  std::exp(sum0);
     579             : 
     580             :   // Excess viscosity due to finite density
     581          10 :   Real mue = _mu_d[0] * density + _mu_d[1] * Utility::pow<2>(density) +
     582          10 :              _mu_d[2] * Utility::pow<6>(density) / Utility::pow<3>(Tstar) +
     583          10 :              _mu_d[3] * Utility::pow<8>(density) + _mu_d[4] * Utility::pow<8>(density) / Tstar;
     584             : 
     585          10 :   Real dmue_drho = _mu_d[0] + 2.0 * _mu_d[1] * density +
     586          10 :                    6.0 * _mu_d[2] * Utility::pow<5>(density) / Utility::pow<3>(Tstar) +
     587          10 :                    8.0 * _mu_d[3] * Utility::pow<7>(density) +
     588          10 :                    8.0 * _mu_d[4] * Utility::pow<7>(density) / Tstar;
     589             : 
     590          10 :   Real dmue_dT = (-3.0 * _mu_d[2] * Utility::pow<6>(density) / Utility::pow<4>(Tstar) -
     591          10 :                   _mu_d[4] * Utility::pow<8>(density) / Tstar / Tstar) *
     592          10 :                  dTstar_dT;
     593             : 
     594             :   // Viscosity in Pa.s is
     595          10 :   mu = (mu0 + mue) * 1.0e-6;
     596          10 :   dmu_drho = dmue_drho * 1.0e-6;
     597          10 :   dmu_dT = (dmu0_dT + dmue_dT) * 1.0e-6 + dmu_drho * ddensity_dT;
     598          10 : }
     599             : 
     600             : void
     601           1 : CO2FluidProperties::rho_mu_from_p_T(Real pressure, Real temperature, Real & rho, Real & mu) const
     602             : {
     603           1 :   rho = rho_from_p_T(pressure, temperature);
     604           1 :   mu = mu_from_rho_T(rho, temperature);
     605           1 : }
     606             : 
     607             : void
     608           1 : CO2FluidProperties::rho_mu_from_p_T(Real pressure,
     609             :                                     Real temperature,
     610             :                                     Real & rho,
     611             :                                     Real & drho_dp,
     612             :                                     Real & drho_dT,
     613             :                                     Real & mu,
     614             :                                     Real & dmu_dp,
     615             :                                     Real & dmu_dT) const
     616             : {
     617           1 :   rho_from_p_T(pressure, temperature, rho, drho_dp, drho_dT);
     618             :   Real dmu_drho;
     619           1 :   mu_from_rho_T(rho, temperature, drho_dT, mu, dmu_drho, dmu_dT);
     620           1 :   dmu_dp = dmu_drho * drho_dp;
     621           1 : }
     622             : 
     623             : Real
     624           3 : CO2FluidProperties::partialDensity(Real temperature) const
     625             : {
     626             :   // This correlation uses temperature in C
     627           3 :   Real Tc = temperature - _T_c2k;
     628             :   // The partial volume
     629           3 :   Real V = 37.51 - 9.585e-2 * Tc + 8.74e-4 * Tc * Tc - 5.044e-7 * Tc * Tc * Tc;
     630             : 
     631           3 :   return 1.0e6 * _Mco2 / V;
     632             : }
     633             : 
     634             : std::vector<Real>
     635           7 : CO2FluidProperties::henryCoefficients() const
     636             : {
     637           7 :   return {-8.55445, 4.01195, 9.52345};
     638             : }
     639             : 
     640             : Real
     641      900272 : CO2FluidProperties::k_from_p_T(Real pressure, Real temperature) const
     642             : {
     643             :   // Require density first
     644      900272 :   Real density = rho_from_p_T(pressure, temperature);
     645      900272 :   return k_from_rho_T(density, temperature);
     646             : }
     647             : 
     648             : void
     649           1 : CO2FluidProperties::k_from_p_T(
     650             :     Real pressure, Real temperature, Real & k, Real & dk_dp, Real & dk_dT) const
     651             : {
     652           1 :   k = this->k_from_p_T(pressure, temperature);
     653             :   // Calculate derivatives using finite differences. Note: this will be slow as
     654             :   // multiple calculations of density are required
     655             :   const Real eps = 1.0e-6;
     656           1 :   const Real peps = pressure * eps;
     657           1 :   const Real Teps = temperature * eps;
     658             : 
     659           1 :   dk_dp = (this->k_from_p_T(pressure + peps, temperature) - k) / peps;
     660           1 :   dk_dT = (this->k_from_p_T(pressure, temperature + Teps) - k) / Teps;
     661           1 : }
     662             : 
     663             : Real
     664      900275 : CO2FluidProperties::k_from_rho_T(Real density, Real temperature) const
     665             : {
     666             :   // Check the temperature is in the range of validity (216.592 K <= T <= 1000 K)
     667      900275 :   if (temperature <= _triple_point_temperature || temperature >= 1000.0)
     668           0 :     throw MooseException("Temperature " + Moose::stringify(temperature) +
     669           0 :                          "K out of range (200K, 1000K) in " + name() + ": k()");
     670             : 
     671             :   // Scaled variables
     672      900275 :   Real Tr = temperature / _critical_temperature;
     673      900275 :   Real rhor = density / _critical_density;
     674             : 
     675             :   Real sum1 = 0.0;
     676     3601100 :   for (std::size_t i = 0; i < _k_n1.size(); ++i)
     677     2700825 :     sum1 += _k_n1[i] * std::pow(Tr, _k_g1[i]) * MathUtils::pow(rhor, _k_h1[i]);
     678             : 
     679             :   Real sum2 = 0.0;
     680     7202200 :   for (std::size_t i = 0; i < _k_n2.size(); ++i)
     681     6301925 :     sum2 += _k_n2[i] * std::pow(Tr, _k_g2[i]) * MathUtils::pow(rhor, _k_h2[i]);
     682             : 
     683             :   // Near-critical enhancement
     684             :   Real alpha =
     685      900275 :       1.0 - _k_a[9] * std::acosh(1.0 + _k_a[10] * std::pow(Utility::pow<2>(1.0 - Tr), _k_a[11]));
     686             :   Real lambdac =
     687      900275 :       rhor *
     688      900275 :       std::exp(-std::pow(rhor, _k_a[0]) / _k_a[0] - Utility::pow<2>(_k_a[1] * (Tr - 1.0)) -
     689      900275 :                Utility::pow<2>(_k_a[2] * (rhor - 1.0))) /
     690      900275 :       std::pow(std::pow(Utility::pow<2>(
     691      900275 :                             1.0 - 1.0 / Tr +
     692      900275 :                             _k_a[3] * std::pow(Utility::pow<2>(rhor - 1.0), 1.0 / (2.0 * _k_a[4]))),
     693             :                         _k_a[5]) +
     694      900275 :                    std::pow(Utility::pow<2>(_k_a[6] * (rhor - alpha)), _k_a[7]),
     695      900275 :                _k_a[8]);
     696             : 
     697      900275 :   return 4.81384 * (sum1 + std::exp(-5.0 * rhor * rhor) * sum2 + 0.775547504 * lambdac) / 1000.0;
     698             : }

Generated by: LCOV version 1.14