LCOV - code coverage report
Current view: top level - src/materials - PorousFlowFluidState.C (source / functions) Hit Total Coverage
Test: idaholab/moose porous_flow: #31405 (292dce) with base fef103 Lines: 167 170 98.2 %
Date: 2025-09-04 07:55:56 Functions: 10 10 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 "PorousFlowFluidState.h"
      11             : 
      12             : registerMooseObject("PorousFlowApp", PorousFlowFluidState);
      13             : registerMooseObject("PorousFlowApp", ADPorousFlowFluidState);
      14             : 
      15             : template <bool is_ad>
      16             : InputParameters
      17        4922 : PorousFlowFluidStateTempl<is_ad>::validParams()
      18             : {
      19        4922 :   InputParameters params = PorousFlowFluidStateBaseMaterialTempl<is_ad>::validParams();
      20        9844 :   params.addRequiredCoupledVar("gas_porepressure",
      21             :                                "Variable that is the porepressure of the gas phase");
      22        9844 :   params.addRequiredCoupledVar("z", "Total mass fraction of component i summed over all phases");
      23        9844 :   params.addCoupledVar(
      24             :       "temperature", 20, "The fluid temperature (C or K, depending on temperature_unit)");
      25        9844 :   params.addCoupledVar("xnacl", 0, "The salt mass fraction in the brine (kg/kg)");
      26        9844 :   params.addRequiredParam<UserObjectName>("fluid_state", "Name of the FluidState UserObject");
      27        4922 :   params.addClassDescription("Class for fluid state calculations using persistent primary "
      28             :                              "variables and a vapor-liquid flash");
      29        4922 :   return params;
      30           0 : }
      31             : 
      32             : template <bool is_ad>
      33        3846 : PorousFlowFluidStateTempl<is_ad>::PorousFlowFluidStateTempl(const InputParameters & parameters)
      34             :   : PorousFlowFluidStateBaseMaterialTempl<is_ad>(parameters),
      35        7692 :     _gas_porepressure(_nodal_material
      36        1461 :                           ? this->template coupledGenericDofValue<is_ad>("gas_porepressure")
      37        6231 :                           : this->template coupledGenericValue<is_ad>("gas_porepressure")),
      38        3846 :     _gas_gradp_qp(this->template coupledGenericGradient<is_ad>("gas_porepressure")),
      39        3846 :     _gas_porepressure_varnum(coupled("gas_porepressure")),
      40        7692 :     _pvar(_dictator.isPorousFlowVariable(_gas_porepressure_varnum)
      41        3846 :               ? _dictator.porousFlowVariableNum(_gas_porepressure_varnum)
      42             :               : 0),
      43        3846 :     _num_Z_vars(coupledComponents("z")),
      44        5988 :     _is_Xnacl_nodal(isCoupled("xnacl") ? getFieldVar("xnacl", 0)->isNodal() : false),
      45        1461 :     _Xnacl(_nodal_material && _is_Xnacl_nodal
      46        4389 :                ? this->template coupledGenericDofValue<is_ad>("xnacl")
      47        7149 :                : this->template coupledGenericValue<is_ad>("xnacl")),
      48        3846 :     _grad_Xnacl_qp(this->template coupledGenericGradient<is_ad>("xnacl")),
      49        3846 :     _Xnacl_varnum(coupled("xnacl")),
      50        3846 :     _Xvar(_dictator.isPorousFlowVariable(_Xnacl_varnum)
      51        3846 :               ? _dictator.porousFlowVariableNum(_Xnacl_varnum)
      52             :               : 0),
      53        3846 :     _fs(this->template getUserObject<PorousFlowFluidStateMultiComponentBase>("fluid_state")),
      54        3846 :     _aqueous_phase_number(_fs.aqueousPhaseIndex()),
      55        3846 :     _gas_phase_number(_fs.gasPhaseIndex()),
      56        3846 :     _aqueous_fluid_component(_fs.aqueousComponentIndex()),
      57        3846 :     _gas_fluid_component(_fs.gasComponentIndex()),
      58        3846 :     _salt_component(_fs.saltComponentIndex()),
      59        3846 :     _temperature(
      60        3846 :         this->template getGenericMaterialProperty<Real, is_ad>("PorousFlow_temperature" + _sfx)),
      61        3846 :     _gradT_qp(_nodal_material ? nullptr
      62        3846 :                               : &this->template getGenericMaterialProperty<RealGradient, is_ad>(
      63             :                                     "PorousFlow_grad_temperature" + _sfx)),
      64        3846 :     _dtemperature_dvar(is_ad ? nullptr
      65        3186 :                              : &this->template getMaterialProperty<std::vector<Real>>(
      66             :                                    "dPorousFlow_temperature" + _sfx + "_dvar")),
      67        3846 :     _temperature_varnum(coupled("temperature")),
      68        3846 :     _Tvar(_dictator.isPorousFlowVariable(_temperature_varnum)
      69        3846 :               ? _dictator.porousFlowVariableNum(_temperature_varnum)
      70             :               : 0),
      71        3846 :     _pidx(_fs.getPressureIndex()),
      72        3846 :     _Tidx(_fs.getTemperatureIndex()),
      73        3846 :     _Zidx(_fs.getZIndex()),
      74        7692 :     _Xidx(_fs.getXIndex())
      75             : {
      76             :   // Check that the number of phases in the fluidstate class is also provided in the Dictator
      77        3846 :   if (_fs.numPhases() != _num_phases)
      78           0 :     mooseError(name(),
      79             :                ": only ",
      80           0 :                _fs.numPhases(),
      81             :                " phases are allowed. Please check the number of phases entered in the dictator is "
      82             :                "correct");
      83             : 
      84             :   // Store all total mass fractions and associated variable numbers
      85        3846 :   _Z.resize(_num_Z_vars);
      86        3846 :   _gradZ_qp.resize(_num_Z_vars);
      87        3846 :   _Z_varnum.resize(_num_Z_vars);
      88        3846 :   _Zvar.resize(_num_Z_vars);
      89             : 
      90        7692 :   for (unsigned int i = 0; i < _num_Z_vars; ++i)
      91             :   {
      92        6231 :     _Z[i] = (_nodal_material ? &this->template coupledGenericDofValue<is_ad>("z", i)
      93        6231 :                              : &this->template coupledGenericValue<is_ad>("z", i));
      94        3846 :     _gradZ_qp[i] = &this->template coupledGenericGradient<is_ad>("z", i);
      95        3846 :     _Z_varnum[i] = coupled("z", i);
      96        7692 :     _Zvar[i] = (_dictator.isPorousFlowVariable(_Z_varnum[i])
      97        3846 :                     ? _dictator.porousFlowVariableNum(_Z_varnum[i])
      98             :                     : 0);
      99             :   }
     100        3846 : }
     101             : 
     102             : template <bool is_ad>
     103             : void
     104     1548562 : PorousFlowFluidStateTempl<is_ad>::thermophysicalProperties()
     105             : {
     106             :   // The FluidProperty objects use temperature in K
     107     1548562 :   const GenericReal<is_ad> Tk = _temperature[_qp] + _T_c2k;
     108             : 
     109     1548562 :   _fs.clearFluidStateProperties(_fsp);
     110     1548562 :   _fs.thermophysicalProperties(_gas_porepressure[_qp], Tk, _Xnacl[_qp], (*_Z[0])[_qp], _qp, _fsp);
     111     1548428 : }
     112             : 
     113             : template <bool is_ad>
     114             : void
     115       42541 : PorousFlowFluidStateTempl<is_ad>::initQpStatefulProperties()
     116             : {
     117       42541 :   PorousFlowFluidStateBaseMaterialTempl<is_ad>::initQpStatefulProperties();
     118       42541 : }
     119             : 
     120             : template <bool is_ad>
     121             : void
     122     1506021 : PorousFlowFluidStateTempl<is_ad>::computeQpProperties()
     123             : {
     124     1506021 :   PorousFlowFluidStateBaseMaterialTempl<is_ad>::computeQpProperties();
     125             : 
     126             :   // If the material isn't AD, we need to compute the derivatives
     127             :   if (!is_ad)
     128             :   {
     129             :     // Derivative of properties wrt variables (calculated in fluid state class)
     130     3791811 :     for (unsigned int ph = 0; ph < _num_phases; ++ph)
     131             :     {
     132             :       // If porepressure is a PorousFlow variable (it usually is), add derivatives wrt
     133             :       // porepressure
     134     2527874 :       if (_dictator.isPorousFlowVariable(_gas_porepressure_varnum))
     135             :       {
     136     5041672 :         (*_dporepressure_dvar)[_qp][ph][_pvar] = _fsp[ph].pressure.derivatives()[_pidx];
     137     2645478 :         (*_dsaturation_dvar)[_qp][ph][_pvar] = _fsp[ph].saturation.derivatives()[_pidx];
     138     3843575 :         (*_dfluid_density_dvar)[_qp][ph][_pvar] = _fsp[ph].density.derivatives()[_pidx];
     139     3843575 :         (*_dfluid_viscosity_dvar)[_qp][ph][_pvar] = _fsp[ph].viscosity.derivatives()[_pidx];
     140     3843575 :         (*_dfluid_enthalpy_dvar)[_qp][ph][_pvar] = _fsp[ph].enthalpy.derivatives()[_pidx];
     141     2527874 :         (*_dfluid_internal_energy_dvar)[_qp][ph][_pvar] =
     142     2527874 :             _fsp[ph].internal_energy.derivatives()[_pidx];
     143             : 
     144     8275182 :         for (unsigned int comp = 0; comp < _num_components; ++comp)
     145     5747308 :           (*_dmass_frac_dvar)[_qp][ph][comp][_pvar] =
     146     5747308 :               _fsp[ph].mass_fraction[comp].derivatives()[_pidx];
     147             :       }
     148             : 
     149             :       // If Z is a PorousFlow variable (it usually is), add derivatives wrt Z
     150     2527874 :       if (_dictator.isPorousFlowVariable(_Z_varnum[0]))
     151             :       {
     152     2586676 :         (*_dporepressure_dvar)[_qp][ph][_Zvar[0]] = _fsp[ph].pressure.derivatives()[_Zidx];
     153     2645478 :         (*_dsaturation_dvar)[_qp][ph][_Zvar[0]] = _fsp[ph].saturation.derivatives()[_Zidx];
     154     2933569 :         (*_dfluid_density_dvar)[_qp][ph][_Zvar[0]] = _fsp[ph].density.derivatives()[_Zidx];
     155     2594436 :         (*_dfluid_viscosity_dvar)[_qp][ph][_Zvar[0]] = _fsp[ph].viscosity.derivatives()[_Zidx];
     156     3777113 :         (*_dfluid_enthalpy_dvar)[_qp][ph][_Zvar[0]] = _fsp[ph].enthalpy.derivatives()[_Zidx];
     157     2527874 :         (*_dfluid_internal_energy_dvar)[_qp][ph][_Zvar[0]] =
     158     2527874 :             _fsp[ph].internal_energy.derivatives()[_Zidx];
     159             : 
     160     8275182 :         for (unsigned int comp = 0; comp < _num_components; ++comp)
     161     5747308 :           (*_dmass_frac_dvar)[_qp][ph][comp][_Zvar[0]] =
     162     5747308 :               _fsp[ph].mass_fraction[comp].derivatives()[_Zidx];
     163             :       }
     164             : 
     165             :       // If temperature is a PorousFlow variable (nonisothermal case), add derivatives wrt
     166             :       // temperature
     167     2527874 :       if (_dictator.isPorousFlowVariable(_temperature_varnum))
     168             :       {
     169     1105552 :         (*_dporepressure_dvar)[_qp][ph][_Tvar] = _fsp[ph].pressure.derivatives()[_Tidx];
     170     1132866 :         (*_dsaturation_dvar)[_qp][ph][_Tvar] = _fsp[ph].saturation.derivatives()[_Tidx];
     171     1644599 :         (*_dfluid_density_dvar)[_qp][ph][_Tvar] = _fsp[ph].density.derivatives()[_Tidx];
     172     1644599 :         (*_dfluid_viscosity_dvar)[_qp][ph][_Tvar] = _fsp[ph].viscosity.derivatives()[_Tidx];
     173     1644599 :         (*_dfluid_enthalpy_dvar)[_qp][ph][_Tvar] = _fsp[ph].enthalpy.derivatives()[_Tidx];
     174     1078238 :         (*_dfluid_internal_energy_dvar)[_qp][ph][_Tvar] =
     175     1078238 :             _fsp[ph].internal_energy.derivatives()[_Tidx];
     176             : 
     177     3747160 :         for (unsigned int comp = 0; comp < _num_components; ++comp)
     178     2668922 :           (*_dmass_frac_dvar)[_qp][ph][comp][_Tvar] =
     179     2668922 :               _fsp[ph].mass_fraction[comp].derivatives()[_Tidx];
     180             :       }
     181             : 
     182             :       // If Xnacl is a PorousFlow variable, add derivatives wrt Xnacl
     183     2527874 :       if (_dictator.isPorousFlowVariable(_Xnacl_varnum))
     184             :       {
     185      706283 :         (*_dporepressure_dvar)[_qp][ph][_Xvar] = _fsp[ph].pressure.derivatives()[_Xidx];
     186      721006 :         (*_dsaturation_dvar)[_qp][ph][_Xvar] = _fsp[ph].saturation.derivatives()[_Xidx];
     187     1037304 :         (*_dfluid_density_dvar)[_qp][ph][_Xvar] += _fsp[ph].density.derivatives()[_Xidx];
     188     1037304 :         (*_dfluid_viscosity_dvar)[_qp][ph][_Xvar] += _fsp[ph].viscosity.derivatives()[_Xidx];
     189     1037304 :         (*_dfluid_enthalpy_dvar)[_qp][ph][_Xvar] = _fsp[ph].enthalpy.derivatives()[_Xidx];
     190      691560 :         (*_dfluid_internal_energy_dvar)[_qp][ph][_Xvar] =
     191      691560 :             _fsp[ph].internal_energy.derivatives()[_Xidx];
     192             : 
     193     2766240 :         for (unsigned int comp = 0; comp < _num_components; ++comp)
     194     2074680 :           (*_dmass_frac_dvar)[_qp][ph][comp][_Xvar] =
     195     2074680 :               _fsp[ph].mass_fraction[comp].derivatives()[_Xidx];
     196             :       }
     197             :     }
     198             :   }
     199             : 
     200             :   // If the material properties are being evaluated at the qps, calculate the gradients as well
     201             :   // Note: only nodal properties are evaluated in initQpStatefulProperties(), so no need to check
     202             :   // _is_initqp flag for qp properties
     203     1263937 :   if (!_nodal_material)
     204             :     if constexpr (!is_ad)
     205             :     {
     206             :       // Derivatives of capillary pressure
     207      629815 :       const Real dpc = _pc.dCapillaryPressure(_fsp[_aqueous_phase_number].saturation.value(), _qp);
     208             :       const Real d2pc =
     209      629815 :           _pc.d2CapillaryPressure(_fsp[_aqueous_phase_number].saturation.value(), _qp);
     210             : 
     211             :       // Gradients of saturation and porepressure in all phases
     212      629815 :       (*_grads_qp)[_qp][_gas_phase_number] =
     213      629815 :           (*_dsaturation_dvar)[_qp][_gas_phase_number][_pvar] * _gas_gradp_qp[_qp] +
     214      629815 :           (*_dsaturation_dvar)[_qp][_gas_phase_number][_Zvar[0]] * (*_gradZ_qp[0])[_qp] +
     215      629815 :           (*_dsaturation_dvar)[_qp][_gas_phase_number][_Tvar] * (*_gradT_qp)[_qp];
     216      629815 :       (*_grads_qp)[_qp][_aqueous_phase_number] = -(*_grads_qp)[_qp][_gas_phase_number];
     217             : 
     218      629815 :       (*_gradp_qp)[_qp][_gas_phase_number] = _gas_gradp_qp[_qp];
     219      629815 :       (*_gradp_qp)[_qp][_aqueous_phase_number] =
     220             :           _gas_gradp_qp[_qp] - dpc * (*_grads_qp)[_qp][_aqueous_phase_number];
     221             : 
     222             :       // Gradients of mass fractions for each component in each phase
     223      629815 :       (*_grad_mass_frac_qp)[_qp][_aqueous_phase_number][_aqueous_fluid_component] =
     224      629815 :           _fsp[_aqueous_phase_number].mass_fraction[_aqueous_fluid_component].derivatives()[_pidx] *
     225             :               _gas_gradp_qp[_qp] +
     226      629815 :           _fsp[_aqueous_phase_number].mass_fraction[_aqueous_fluid_component].derivatives()[_Zidx] *
     227             :               (*_gradZ_qp[0])[_qp] +
     228      629815 :           _fsp[_aqueous_phase_number].mass_fraction[_aqueous_fluid_component].derivatives()[_Tidx] *
     229             :               (*_gradT_qp)[_qp];
     230      629815 :       (*_grad_mass_frac_qp)[_qp][_aqueous_phase_number][_gas_fluid_component] =
     231             :           -(*_grad_mass_frac_qp)[_qp][_aqueous_phase_number][_aqueous_fluid_component];
     232             : 
     233      629815 :       (*_grad_mass_frac_qp)[_qp][_gas_phase_number][_aqueous_fluid_component] =
     234             :           _fsp[_gas_phase_number].mass_fraction[_aqueous_fluid_component].derivatives()[_pidx] *
     235             :               _gas_gradp_qp[_qp] +
     236             :           _fsp[_gas_phase_number].mass_fraction[_aqueous_fluid_component].derivatives()[_Zidx] *
     237             :               (*_gradZ_qp[0])[_qp] +
     238      629815 :           _fsp[_gas_phase_number].mass_fraction[_aqueous_fluid_component].derivatives()[_Tidx] *
     239             :               (*_gradT_qp)[_qp];
     240      629815 :       (*_grad_mass_frac_qp)[_qp][_gas_phase_number][_gas_fluid_component] =
     241             :           -(*_grad_mass_frac_qp)[_qp][_gas_phase_number][_aqueous_fluid_component];
     242             : 
     243             :       // Derivatives of gradients wrt variables
     244      629815 :       if (_dictator.isPorousFlowVariable(_gas_porepressure_varnum))
     245             :       {
     246     1889445 :         for (unsigned int ph = 0; ph < _num_phases; ++ph)
     247     1259630 :           (*_dgradp_qp_dgradv)[_qp][ph][_pvar] = 1.0;
     248             : 
     249      629815 :         (*_dgradp_qp_dgradv)[_qp][_aqueous_phase_number][_pvar] +=
     250      629815 :             -dpc * (*_dsaturation_dvar)[_qp][_aqueous_phase_number][_pvar];
     251             : 
     252      629815 :         (*_dgradp_qp_dv)[_qp][_aqueous_phase_number][_pvar] =
     253      629815 :             -d2pc * (*_grads_qp)[_qp][_aqueous_phase_number] *
     254             :             (*_dsaturation_dvar)[_qp][_aqueous_phase_number][_pvar];
     255             :       }
     256             : 
     257      629815 :       if (_dictator.isPorousFlowVariable(_Z_varnum[0]))
     258             :       {
     259      629815 :         (*_dgradp_qp_dgradv)[_qp][_aqueous_phase_number][_Zvar[0]] =
     260      629815 :             -dpc * (*_dsaturation_dvar)[_qp][_aqueous_phase_number][_Zvar[0]];
     261             : 
     262      629815 :         (*_dgradp_qp_dv)[_qp][_aqueous_phase_number][_Zvar[0]] =
     263      629815 :             -d2pc * (*_grads_qp)[_qp][_aqueous_phase_number] *
     264             :             (*_dsaturation_dvar)[_qp][_aqueous_phase_number][_Zvar[0]];
     265             :       }
     266             : 
     267      629815 :       if (_dictator.isPorousFlowVariable(_temperature_varnum))
     268             :       {
     269      268347 :         (*_dgradp_qp_dgradv)[_qp][_aqueous_phase_number][_Tvar] =
     270      268347 :             -dpc * (*_dsaturation_dvar)[_qp][_aqueous_phase_number][_Tvar];
     271             : 
     272      268347 :         (*_dgradp_qp_dv)[_qp][_aqueous_phase_number][_Tvar] =
     273      268347 :             -d2pc * (*_grads_qp)[_qp][_aqueous_phase_number] *
     274             :             (*_dsaturation_dvar)[_qp][_aqueous_phase_number][_Tvar];
     275             :       }
     276             : 
     277             :       // If Xnacl is a PorousFlow variable, add gradients and derivatives wrt Xnacl
     278      629815 :       if (_dictator.isPorousFlowVariable(_Xnacl_varnum))
     279             :       {
     280      172422 :         (*_dgradp_qp_dgradv)[_qp][_aqueous_phase_number][_Xvar] =
     281      172422 :             -dpc * (*_dsaturation_dvar)[_qp][_aqueous_phase_number][_Xvar];
     282             : 
     283      172422 :         (*_grads_qp)[_qp][_aqueous_phase_number] +=
     284      172422 :             (*_dsaturation_dvar)[_qp][_aqueous_phase_number][_Xvar] * _grad_Xnacl_qp[_qp];
     285             : 
     286      172422 :         (*_grads_qp)[_qp][_gas_phase_number] -=
     287      172422 :             (*_dsaturation_dvar)[_qp][_aqueous_phase_number][_Xvar] * _grad_Xnacl_qp[_qp];
     288             : 
     289      172422 :         (*_gradp_qp)[_qp][_aqueous_phase_number] -=
     290      172422 :             dpc * (*_dsaturation_dvar)[_qp][_aqueous_phase_number][_Xvar] * _grad_Xnacl_qp[_qp];
     291             : 
     292      172422 :         (*_dgradp_qp_dv)[_qp][_aqueous_phase_number][_Xvar] =
     293      172422 :             -d2pc * (*_grads_qp)[_qp][_aqueous_phase_number] *
     294             :             (*_dsaturation_dvar)[_qp][_aqueous_phase_number][_Xvar];
     295             : 
     296      172422 :         (*_grad_mass_frac_qp)[_qp][_aqueous_phase_number][_salt_component] = _grad_Xnacl_qp[_qp];
     297             :         (*_grad_mass_frac_qp)[_qp][_aqueous_phase_number][_aqueous_fluid_component] +=
     298             :             _fsp[_aqueous_phase_number]
     299      172422 :                 .mass_fraction[_aqueous_fluid_component]
     300      172422 :                 .derivatives()[_Xidx] *
     301             :             _grad_Xnacl_qp[_qp];
     302      172422 :         (*_grad_mass_frac_qp)[_qp][_aqueous_phase_number][_gas_fluid_component] -=
     303             :             _fsp[_aqueous_phase_number]
     304             :                 .mass_fraction[_aqueous_fluid_component]
     305      172422 :                 .derivatives()[_Xidx] *
     306             :             _grad_Xnacl_qp[_qp];
     307             :         (*_grad_mass_frac_qp)[_qp][_gas_phase_number][_aqueous_fluid_component] +=
     308      172422 :             _fsp[_gas_phase_number].mass_fraction[_aqueous_fluid_component].derivatives()[_Xidx] *
     309             :             _grad_Xnacl_qp[_qp];
     310             :         (*_grad_mass_frac_qp)[_qp][_gas_phase_number][_gas_fluid_component] -=
     311      172422 :             _fsp[_gas_phase_number].mass_fraction[_aqueous_fluid_component].derivatives()[_Xidx] *
     312             :             _grad_Xnacl_qp[_qp];
     313             :       }
     314             :     }
     315     1505887 : }
     316             : 
     317             : template class PorousFlowFluidStateTempl<false>;
     318             : template class PorousFlowFluidStateTempl<true>;

Generated by: LCOV version 1.14