LCOV - code coverage report
Current view: top level - src/fluidproperties - NaKFluidProperties.C (source / functions) Hit Total Coverage
Test: idaholab/moose fluid_properties: #31405 (292dce) with base fef103 Lines: 118 122 96.7 %
Date: 2025-09-04 07:53:14 Functions: 22 22 100.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             : #include "NaKFluidProperties.h"
      11             : 
      12             : registerMooseObject("FluidPropertiesApp", NaKFluidProperties);
      13             : 
      14             : InputParameters
      15           8 : NaKFluidProperties::validParams()
      16             : {
      17           8 :   InputParameters params = SinglePhaseFluidProperties::validParams();
      18           8 :   params.addClassDescription("Fluid properties for NaK");
      19          16 :   params.addRequiredParam<Real>(
      20             :       "weight_fraction_K",
      21             :       "Weight fraction of potassium in NaK. Only eutectic is implemented (X_K = 0.778)");
      22           8 :   return params;
      23           0 : }
      24             : 
      25           4 : NaKFluidProperties::NaKFluidProperties(const InputParameters & parameters)
      26           4 :   : SinglePhaseFluidProperties(parameters), _MNaK((39.102 + 22.9898) / 1000)
      27             : {
      28             :   // We did not implement other weight fractions
      29           8 :   const Real Xk = getParam<Real>("weight_fraction_K");
      30           4 :   if (Xk != 0.778)
      31           0 :     paramError("weight_fraction_K",
      32             :                "Only 0.778 weight percent potassium (eutectic) is implemented");
      33             : 
      34             :   // Compute mole fractions from mass fractions
      35             :   const Real AwK = 39.102;
      36             :   const Real AwNa = 22.9898;
      37           4 :   _Nk = Xk / AwK / (Xk / AwK + (1 - Xk) / AwNa);
      38           4 : }
      39             : 
      40           8 : NaKFluidProperties::~NaKFluidProperties() {}
      41             : 
      42             : std::string
      43           1 : NaKFluidProperties::fluidName() const
      44             : {
      45           1 :   return "NaK";
      46             : }
      47             : 
      48             : Real
      49           1 : NaKFluidProperties::molarMass() const
      50             : {
      51           1 :   return _MNaK;
      52             : }
      53             : 
      54             : Real
      55           3 : NaKFluidProperties::T_from_p_h(Real /* pressure */, Real enthalpy) const
      56             : {
      57             :   // analytical inversion of h_from_p_T
      58           3 :   Real h2 = enthalpy * enthalpy;
      59             :   Real B1 =
      60           3 :       std::pow(183.357574154983 * std::sqrt(8405 * h2 - 8208700353 * enthalpy + 9265308922016000) +
      61           3 :                    16810 * enthalpy - 8208700353,
      62             :                1. / 3);
      63           3 :   return _T_c2k + 0.174216027874564 * (3.65930571002297 * B1 - 2.28699205892461e7 / B1 + 3087);
      64             : }
      65             : 
      66             : Real
      67           6 : NaKFluidProperties::T_from_p_rho(Real pressure, Real density) const
      68             : {
      69             :   // NOTE we could also invert analytically the third degree polynomial, see Cardan's method
      70             :   auto lambda = [&](Real p, Real current_T, Real & new_rho, Real & drho_dp, Real & drho_dT)
      71          24 :   { rho_from_p_T(p, current_T, new_rho, drho_dp, drho_dT); };
      72           6 :   Real T = FluidPropertiesUtils::NewtonSolve(pressure,
      73             :                                              density,
      74           6 :                                              _T_initial_guess,
      75           6 :                                              _tolerance,
      76             :                                              lambda,
      77           6 :                                              name() + "::T_from_p_rho",
      78           6 :                                              _max_newton_its)
      79           6 :                .first;
      80             :   // check for nans
      81           6 :   if (std::isnan(T))
      82           0 :     mooseError("Conversion from pressure (p = ",
      83             :                pressure,
      84             :                ") and density (rho = ",
      85             :                density,
      86             :                ") to temperature failed to converge.");
      87           6 :   return T;
      88             : }
      89             : 
      90             : Real
      91          75 : NaKFluidProperties::rho_from_p_T(Real /*pressure*/, Real temperature) const
      92             : {
      93          75 :   const Real Tc = temperature - _T_c2k;
      94             :   // Range from liquid Na and K density correlation ranges
      95          75 :   if (Tc < 210 || Tc > 1110)
      96          31 :     flagInvalidSolution(
      97             :         "NaK density evaluated outside of Na density temperature range [210, 1110] C");
      98          75 :   if (Tc < 63.2 || Tc > 1250)
      99           0 :     flagInvalidSolution(
     100             :         "NaK density evaluated outside of K density temperature range [63, 1250] C");
     101             : 
     102             :   // Eq. 1.8 page 18 of NaK handbook
     103          75 :   const Real v_k = 1. / (0.8415 - 2.172e-4 * Tc - 2.7e-8 * Tc * Tc + 4.77e-12 * Tc * Tc * Tc);
     104             :   // Eq. 1.5 page 15 of NaK handbook
     105          75 :   const Real v_Na = 1. / (0.9453 - 2.2473e-4 * Tc);
     106             :   // Eq. 1.9 page 15 of NaK handbook
     107          75 :   return 1000 / (_Nk * v_k + (1 - _Nk) * v_Na);
     108             : }
     109             : 
     110             : void
     111          32 : NaKFluidProperties::rho_from_p_T(
     112             :     Real pressure, Real temperature, Real & rho, Real & drho_dp, Real & drho_dT) const
     113             : {
     114          32 :   rho = this->rho_from_p_T(pressure, temperature);
     115          32 :   drho_dp = 0;
     116             : 
     117          32 :   const Real Tc = temperature - _T_c2k;
     118             :   // Eq. 1.8 page 18 of NaK handbook
     119          32 :   const Real v_k = 1. / (0.8415 - 2.172e-4 * Tc - 2.7e-8 * Tc * Tc + 4.77e-12 * Tc * Tc * Tc);
     120             :   // Eq. 1.5 page 15 of NaK handbook
     121          32 :   const Real v_Na = 1. / (0.9453 - 2.2473e-4 * Tc);
     122          32 :   drho_dT =
     123          32 :       1000 *
     124          32 :       -(_Nk * -(-2.172e-4 - 2 * 2.7e-8 * Tc + 3 * 4.77e-12 * Tc * Tc) * MathUtils::pow(v_k, 2) +
     125          32 :         (1 - _Nk) * 2.2473e-4 * MathUtils::pow(v_Na, 2)) /
     126          32 :       MathUtils::pow(_Nk * v_k + (1 - _Nk) * v_Na, 2);
     127          32 : }
     128             : 
     129             : Real
     130          11 : NaKFluidProperties::e_from_p_T(Real pressure, Real temperature) const
     131             : {
     132          11 :   return h_from_p_T(pressure, temperature) - pressure / rho_from_p_T(pressure, temperature);
     133             : }
     134             : 
     135             : Real
     136           3 : NaKFluidProperties::e_from_p_rho(Real pressure, Real density) const
     137             : {
     138           3 :   Real temperature = T_from_p_rho(pressure, density);
     139           3 :   return e_from_p_T(pressure, temperature);
     140             : }
     141             : 
     142             : void
     143           4 : NaKFluidProperties::e_from_p_T(
     144             :     Real pressure, Real temperature, Real & e, Real & de_dp, Real & de_dT) const
     145             : {
     146             :   Real h, dh_dp, dh_dT;
     147           4 :   h_from_p_T(pressure, temperature, h, dh_dp, dh_dT);
     148             :   Real rho, drho_dp, drho_dT;
     149           4 :   rho_from_p_T(pressure, temperature, rho, drho_dp, drho_dT);
     150             : 
     151           4 :   e = h - pressure / rho;
     152           4 :   de_dp = dh_dp + pressure * drho_dp / rho / rho - 1.0 / rho;
     153           4 :   de_dT = dh_dT + pressure * drho_dT / rho / rho;
     154           4 : }
     155             : 
     156             : Real
     157          14 : NaKFluidProperties::cp_from_p_T(Real /*pressure*/, Real temperature) const
     158             : {
     159          14 :   const Real Tc = temperature - _T_c2k;
     160             :   // Eq. 1.59 page 53 of the NaK handbook
     161             :   // converted from cal/g/C
     162          14 :   return (0.232 - 8.82e-5 * Tc + 8.2e-8 * Tc * Tc) * 4200;
     163             : }
     164             : 
     165             : void
     166           1 : NaKFluidProperties::cp_from_p_T(
     167             :     Real /*pressure*/, Real temperature, Real & cp, Real & dcp_dp, Real & dcp_dT) const
     168             : {
     169           1 :   const Real Tc = temperature - _T_c2k;
     170             :   // Eq. 1.59 page 53 of the NaK handbook
     171             :   // converted from cal/g/C
     172           1 :   cp = cp_from_p_T(-1, temperature);
     173           1 :   dcp_dp = 0;
     174           1 :   dcp_dT = (-8.82e-5 + 2 * 8.2e-8 * Tc) * 4200;
     175           1 : }
     176             : 
     177             : Real
     178           3 : NaKFluidProperties::cv_from_p_T(Real pressure, Real temperature) const
     179             : {
     180             :   Real e, de_dp, de_dT;
     181           3 :   e_from_p_T(pressure, temperature, e, de_dp, de_dT);
     182           3 :   return de_dT;
     183             : }
     184             : 
     185             : Real
     186          13 : NaKFluidProperties::mu_from_p_T(Real /*pressure*/, Real temperature) const
     187             : {
     188             :   /* eq. 1.18-19 page 24 of NaK handbook */
     189             :   // No range given
     190             :   // Converted from centipoise
     191          13 :   const Real rho = rho_from_p_T(-1, temperature) / 1000;
     192          13 :   if (temperature < _T_c2k + 400)
     193           6 :     return 0.001 * 0.116 * std::pow(rho, 1 / 3.) * exp(688 * rho / temperature);
     194             :   else
     195           7 :     return 0.001 * 0.082 * std::pow(rho, 1 / 3.) * exp(979 * rho / temperature);
     196             : }
     197             : 
     198             : void
     199           2 : NaKFluidProperties::mu_from_p_T(
     200             :     Real /*pressure*/, Real temperature, Real & mu, Real & dmu_dp, Real & dmu_dT) const
     201             : {
     202             :   /* eq. 1.18-19 page 24 of NaK handbook */
     203             :   // No range given
     204             :   // Converted from centipoise
     205             :   Real rho, drho_dp, drho_dT;
     206           2 :   rho_from_p_T(-1, temperature, rho, drho_dp, drho_dT);
     207           2 :   rho /= 1000;
     208           2 :   drho_dT /= 1000;
     209           2 :   if (temperature < _T_c2k + 400)
     210             :   {
     211           1 :     mu = 0.001 * 0.116 * std::pow(rho, 1 / 3.) * exp(688 * rho / temperature);
     212           1 :     dmu_dp = 0;
     213           1 :     dmu_dT =
     214           1 :         0.001 * 0.116 * exp(688 * rho / temperature) *
     215           1 :         (1 / 3. * drho_dT * std::pow(rho, -2 / 3.) +
     216           1 :          std::pow(rho, 1 / 3.) * 688 * (drho_dT * temperature - rho) / temperature / temperature);
     217             :   }
     218             :   else
     219             :   {
     220           1 :     mu = 0.001 * 0.082 * std::pow(rho, 1 / 3.) * exp(979 * rho / temperature);
     221           1 :     dmu_dp = 0;
     222           1 :     dmu_dT =
     223           1 :         0.001 * 0.082 * exp(979 * rho / temperature) *
     224           1 :         (1 / 3. * drho_dT * std::pow(rho, -2 / 3.) +
     225           1 :          std::pow(rho, 1 / 3.) * 979 * (drho_dT * temperature - rho) / temperature / temperature);
     226             :   }
     227           2 : }
     228             : 
     229             : Real
     230           9 : NaKFluidProperties::k_from_p_T(Real /*pressure*/, Real temperature) const
     231             : {
     232           9 :   const Real Tc = temperature - _T_c2k;
     233             :   /* eq. 1.53 page 46 handbook */
     234             :   // Note: reported as very sensitive to the composition
     235             :   // Range: 150 - 680 C
     236             :   // Converted from (W/cm-C)
     237           9 :   if (Tc < 150 || Tc > 680)
     238           8 :     flagInvalidSolution(
     239             :         "NaK thermal diffusivity evaluated outside of temperature range [150, 680] C");
     240           9 :   return 100 * (0.214 + 2.07e-4 * Tc - 2.2e-7 * Tc * Tc);
     241             : }
     242             : 
     243             : void
     244           1 : NaKFluidProperties::k_from_p_T(
     245             :     Real /*pressure*/, Real temperature, Real & k, Real & dk_dp, Real & dk_dT) const
     246             : {
     247           1 :   const Real Tc = temperature - _T_c2k;
     248           1 :   k = k_from_p_T(0, temperature);
     249           1 :   dk_dp = 0.0;
     250           1 :   dk_dT = 100 * (2.07e-4 - 2 * 2.2e-7 * Tc);
     251           1 : }
     252             : 
     253             : Real
     254          22 : NaKFluidProperties::h_from_p_T(Real /*pressure*/, Real temperature) const
     255             : {
     256             :   // Integration of cv
     257          22 :   const Real Tc = temperature - _T_c2k;
     258          22 :   return (0.232 * Tc - 8.82e-5 / 2 * Tc * Tc + 8.2e-8 / 3 * Tc * Tc * Tc) * 4200;
     259             : }
     260             : 
     261             : void
     262           5 : NaKFluidProperties::h_from_p_T(
     263             :     Real pressure, Real temperature, Real & h, Real & dh_dp, Real & dh_dT) const
     264             : {
     265           5 :   const Real Tc = temperature - _T_c2k;
     266           5 :   h = (0.232 * Tc - 8.82e-5 / 2 * Tc * Tc + 8.2e-8 / 3 * Tc * Tc * Tc) * 4200;
     267           5 :   dh_dp = 0;
     268           5 :   dh_dT = cp_from_p_T(pressure, temperature);
     269           5 : }

Generated by: LCOV version 1.14