LCOV - code coverage report
Current view: top level - src/kernels - PorousFlowEnergyTimeDerivative.C (source / functions) Hit Total Coverage
Test: idaholab/moose porous_flow: #31405 (292dce) with base fef103 Lines: 83 84 98.8 %
Date: 2025-09-04 07:55:56 Functions: 6 6 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 "PorousFlowEnergyTimeDerivative.h"
      11             : 
      12             : #include "MooseVariable.h"
      13             : 
      14             : registerMooseObject("PorousFlowApp", PorousFlowEnergyTimeDerivative);
      15             : 
      16             : InputParameters
      17        2046 : PorousFlowEnergyTimeDerivative::validParams()
      18             : {
      19        2046 :   InputParameters params = TimeKernel::validParams();
      20        4092 :   params.addParam<bool>("strain_at_nearest_qp",
      21        4092 :                         false,
      22             :                         "When calculating nodal porosity that depends on strain, use the strain at "
      23             :                         "the nearest quadpoint.  This adds a small extra computational burden, and "
      24             :                         "is not necessary for simulations involving only linear lagrange elements. "
      25             :                         " If you set this to true, you will also want to set the same parameter to "
      26             :                         "true for related Kernels and Materials");
      27        4092 :   params.addParam<std::string>(
      28             :       "base_name",
      29             :       "For mechanically-coupled systems, this Kernel will depend on the volumetric strain.  "
      30             :       "base_name should almost always be the same base_name as given to the TensorMechanics object "
      31             :       "that computes strain.  Supplying a base_name to this Kernel but not defining an associated "
      32             :       "TensorMechanics strain calculator means that this Kernel will not depend on volumetric "
      33             :       "strain.  That could be useful when models contain solid mechanics that is not coupled to "
      34             :       "porous flow, for example");
      35        4092 :   params.addRequiredParam<UserObjectName>(
      36             :       "PorousFlowDictator", "The UserObject that holds the list of PorousFlow variable names.");
      37        2046 :   params.set<bool>("use_displaced_mesh") = false;
      38        2046 :   params.suppressParameter<bool>("use_displaced_mesh");
      39        2046 :   params.addClassDescription("Derivative of heat-energy-density wrt time");
      40        2046 :   return params;
      41           0 : }
      42             : 
      43        1120 : PorousFlowEnergyTimeDerivative::PorousFlowEnergyTimeDerivative(const InputParameters & parameters)
      44             :   : TimeKernel(parameters),
      45        1120 :     _dictator(getUserObject<PorousFlowDictator>("PorousFlowDictator")),
      46        1120 :     _var_is_porflow_var(_dictator.isPorousFlowVariable(_var.number())),
      47        1120 :     _num_phases(_dictator.numPhases()),
      48        1120 :     _fluid_present(_num_phases > 0),
      49        2240 :     _strain_at_nearest_qp(getParam<bool>("strain_at_nearest_qp")),
      50        2372 :     _base_name(isParamValid("base_name") ? getParam<std::string>("base_name") + "_" : ""),
      51        1120 :     _has_total_strain(hasMaterialProperty<RankTwoTensor>(_base_name + "total_strain")),
      52        2240 :     _total_strain_old(_has_total_strain
      53        1385 :                           ? &getMaterialPropertyOld<RankTwoTensor>(_base_name + "total_strain")
      54             :                           : nullptr),
      55        2240 :     _porosity(getMaterialProperty<Real>("PorousFlow_porosity_nodal")),
      56        2240 :     _porosity_old(getMaterialPropertyOld<Real>("PorousFlow_porosity_nodal")),
      57        2240 :     _dporosity_dvar(getMaterialProperty<std::vector<Real>>("dPorousFlow_porosity_nodal_dvar")),
      58        1120 :     _dporosity_dgradvar(
      59        1120 :         getMaterialProperty<std::vector<RealGradient>>("dPorousFlow_porosity_nodal_dgradvar")),
      60        2240 :     _nearest_qp(_strain_at_nearest_qp
      61        1131 :                     ? &getMaterialProperty<unsigned int>("PorousFlow_nearestqp_nodal")
      62             :                     : nullptr),
      63        2240 :     _rock_energy_nodal(getMaterialProperty<Real>("PorousFlow_matrix_internal_energy_nodal")),
      64        2240 :     _rock_energy_nodal_old(getMaterialPropertyOld<Real>("PorousFlow_matrix_internal_energy_nodal")),
      65        1120 :     _drock_energy_nodal_dvar(
      66        1120 :         getMaterialProperty<std::vector<Real>>("dPorousFlow_matrix_internal_energy_nodal_dvar")),
      67        2141 :     _fluid_density(_fluid_present ? &getMaterialProperty<std::vector<Real>>(
      68             :                                         "PorousFlow_fluid_phase_density_nodal")
      69             :                                   : nullptr),
      70        2141 :     _fluid_density_old(_fluid_present ? &getMaterialPropertyOld<std::vector<Real>>(
      71             :                                             "PorousFlow_fluid_phase_density_nodal")
      72             :                                       : nullptr),
      73        2141 :     _dfluid_density_dvar(_fluid_present ? &getMaterialProperty<std::vector<std::vector<Real>>>(
      74             :                                               "dPorousFlow_fluid_phase_density_nodal_dvar")
      75             :                                         : nullptr),
      76        1120 :     _fluid_saturation_nodal(
      77        2141 :         _fluid_present ? &getMaterialProperty<std::vector<Real>>("PorousFlow_saturation_nodal")
      78             :                        : nullptr),
      79        1120 :     _fluid_saturation_nodal_old(
      80        2141 :         _fluid_present ? &getMaterialPropertyOld<std::vector<Real>>("PorousFlow_saturation_nodal")
      81             :                        : nullptr),
      82        2240 :     _dfluid_saturation_nodal_dvar(_fluid_present
      83        2141 :                                       ? &getMaterialProperty<std::vector<std::vector<Real>>>(
      84             :                                             "dPorousFlow_saturation_nodal_dvar")
      85             :                                       : nullptr),
      86        2141 :     _energy_nodal(_fluid_present ? &getMaterialProperty<std::vector<Real>>(
      87             :                                        "PorousFlow_fluid_phase_internal_energy_nodal")
      88             :                                  : nullptr),
      89        2141 :     _energy_nodal_old(_fluid_present ? &getMaterialPropertyOld<std::vector<Real>>(
      90             :                                            "PorousFlow_fluid_phase_internal_energy_nodal")
      91             :                                      : nullptr),
      92        2141 :     _denergy_nodal_dvar(_fluid_present ? &getMaterialProperty<std::vector<std::vector<Real>>>(
      93             :                                              "dPorousFlow_fluid_phase_internal_energy_nodal_dvar")
      94        1120 :                                        : nullptr)
      95             : {
      96        1120 : }
      97             : 
      98             : Real
      99     8380204 : PorousFlowEnergyTimeDerivative::computeQpResidual()
     100             : {
     101             :   /// Porous matrix heat energy
     102     8380204 :   Real energy = (1.0 - _porosity[_i]) * _rock_energy_nodal[_i];
     103     8380204 :   Real energy_old = (1.0 - _porosity_old[_i]) * _rock_energy_nodal_old[_i];
     104             : 
     105             :   /// Add the fluid heat energy
     106     8380204 :   if (_fluid_present)
     107    17212004 :     for (unsigned ph = 0; ph < _num_phases; ++ph)
     108             :     {
     109     8872168 :       energy += (*_fluid_density)[_i][ph] * (*_fluid_saturation_nodal)[_i][ph] *
     110     8872168 :                 (*_energy_nodal)[_i][ph] * _porosity[_i];
     111     8872168 :       energy_old += (*_fluid_density_old)[_i][ph] * (*_fluid_saturation_nodal_old)[_i][ph] *
     112     8872168 :                     (*_energy_nodal_old)[_i][ph] * _porosity_old[_i];
     113             :     }
     114     8380204 :   const Real strain = (_has_total_strain ? (*_total_strain_old)[_qp].trace() : 0.0);
     115             : 
     116     8380204 :   return _test[_i][_qp] * (1.0 + strain) * (energy - energy_old) / _dt;
     117             : }
     118             : 
     119             : Real
     120    27083880 : PorousFlowEnergyTimeDerivative::computeQpJacobian()
     121             : {
     122             :   // If the variable is not a PorousFlow variable (very unusual), the diag Jacobian terms are 0
     123    27083880 :   if (!_var_is_porflow_var)
     124             :     return 0.0;
     125    27083880 :   return computeQpJac(_dictator.porousFlowVariableNum(_var.number()));
     126             : }
     127             : 
     128             : Real
     129    29953960 : PorousFlowEnergyTimeDerivative::computeQpOffDiagJacobian(unsigned int jvar)
     130             : {
     131             :   // If the variable is not a PorousFlow variable, the OffDiag Jacobian terms are 0
     132    29953960 :   if (_dictator.notPorousFlowVariable(jvar))
     133             :     return 0.0;
     134    29953960 :   return computeQpJac(_dictator.porousFlowVariableNum(jvar));
     135             : }
     136             : 
     137             : Real
     138    57037840 : PorousFlowEnergyTimeDerivative::computeQpJac(unsigned int pvar) const
     139             : {
     140    57037840 :   const unsigned nearest_qp = (_strain_at_nearest_qp ? (*_nearest_qp)[_i] : _i);
     141             : 
     142    57037840 :   const Real strain = (_has_total_strain ? (*_total_strain_old)[_qp].trace() : 0.0);
     143             : 
     144             :   // porosity is dependent on variables that are lumped to the nodes,
     145             :   // but it can depend on the gradient
     146             :   // of variables, which are NOT lumped to the nodes, hence:
     147    57037840 :   Real denergy = -_dporosity_dgradvar[_i][pvar] * _grad_phi[_j][_i] * _rock_energy_nodal[_i];
     148   115767392 :   for (unsigned ph = 0; ph < _num_phases; ++ph)
     149    58729552 :     denergy += (*_fluid_density)[_i][ph] * (*_fluid_saturation_nodal)[_i][ph] *
     150    58729552 :                (*_energy_nodal)[_i][ph] * _dporosity_dgradvar[_i][pvar] * _grad_phi[_j][nearest_qp];
     151             : 
     152    57037840 :   if (_i != _j)
     153    45189840 :     return _test[_i][_qp] * (1.0 + strain) * denergy / _dt;
     154             : 
     155             :   // As the fluid energy is lumped to the nodes, only non-zero terms are for _i==_j
     156    11848000 :   denergy += -_dporosity_dvar[_i][pvar] * _rock_energy_nodal[_i];
     157    11848000 :   denergy += (1.0 - _porosity[_i]) * _drock_energy_nodal_dvar[_i][pvar];
     158    24418624 :   for (unsigned ph = 0; ph < _num_phases; ++ph)
     159             :   {
     160    12570624 :     denergy += (*_dfluid_density_dvar)[_i][ph][pvar] * (*_fluid_saturation_nodal)[_i][ph] *
     161    12570624 :                (*_energy_nodal)[_i][ph] * _porosity[_i];
     162    12570624 :     denergy += (*_fluid_density)[_i][ph] * (*_dfluid_saturation_nodal_dvar)[_i][ph][pvar] *
     163    12570624 :                (*_energy_nodal)[_i][ph] * _porosity[_i];
     164    12570624 :     denergy += (*_fluid_density)[_i][ph] * (*_fluid_saturation_nodal)[_i][ph] *
     165    12570624 :                (*_denergy_nodal_dvar)[_i][ph][pvar] * _porosity[_i];
     166    12570624 :     denergy += (*_fluid_density)[_i][ph] * (*_fluid_saturation_nodal)[_i][ph] *
     167    12570624 :                (*_energy_nodal)[_i][ph] * _dporosity_dvar[_i][pvar];
     168             :   }
     169    11848000 :   return _test[_i][_qp] * (1.0 + strain) * denergy / _dt;
     170             : }

Generated by: LCOV version 1.14