LCOV - code coverage report
Current view: top level - src/postprocessors - PorousFlowHeatEnergy.C (source / functions) Hit Total Coverage
Test: idaholab/moose porous_flow: #31405 (292dce) with base fef103 Lines: 62 65 95.4 %
Date: 2025-09-04 07:55:56 Functions: 3 4 75.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 "PorousFlowHeatEnergy.h"
      11             : 
      12             : #include "MooseVariable.h"
      13             : 
      14             : #include "libmesh/quadrature.h"
      15             : 
      16             : registerMooseObject("PorousFlowApp", PorousFlowHeatEnergy);
      17             : 
      18             : InputParameters
      19         875 : PorousFlowHeatEnergy::validParams()
      20             : {
      21         875 :   InputParameters params = ElementIntegralPostprocessor::validParams();
      22        1750 :   params.addRequiredParam<UserObjectName>(
      23             :       "PorousFlowDictator", "The UserObject that holds the list of PorousFlow variable names.");
      24        1750 :   params.addParam<bool>(
      25        1750 :       "include_porous_skeleton", true, "Include the heat energy of the porous skeleton");
      26        1750 :   params.addParam<std::vector<unsigned int>>("phase",
      27             :                                              {},
      28             :                                              "The index(es) of the fluid phase that this "
      29             :                                              "Postprocessor is restricted to.  Multiple "
      30             :                                              "indices can be entered.");
      31        1750 :   params.addParam<std::string>(
      32             :       "base_name",
      33             :       "For non-mechanically-coupled systems with no TensorMechanics strain calculators, base_name "
      34             :       "need not be set.  For mechanically-coupled systems, base_name should be the same base_name "
      35             :       "as given to the TensorMechanics object that computes strain, so that this Postprocessor can "
      36             :       "correctly account for changes in mesh volume.  For non-mechanically-coupled systems, "
      37             :       "base_name should not be the base_name of any TensorMechanics strain calculators.");
      38         875 :   params.set<bool>("use_displaced_mesh") = false;
      39         875 :   params.suppressParameter<bool>("use_displaced_mesh");
      40        1750 :   params.addParam<unsigned int>("kernel_variable_number",
      41        1750 :                                 0,
      42             :                                 "The PorousFlow variable number (according to the dictatory) of "
      43             :                                 "the heat-energy kernel.  This is required only in the unusual "
      44             :                                 "situation where a variety of different finite-element "
      45             :                                 "interpolation schemes are employed in the simulation");
      46         875 :   params.addClassDescription("Calculates the sum of heat energy of fluid phase(s) and/or the "
      47             :                              "porous skeleton in a region");
      48         875 :   return params;
      49           0 : }
      50             : 
      51         468 : PorousFlowHeatEnergy::PorousFlowHeatEnergy(const InputParameters & parameters)
      52             :   : ElementIntegralPostprocessor(parameters),
      53         468 :     _dictator(getUserObject<PorousFlowDictator>("PorousFlowDictator")),
      54         468 :     _num_phases(_dictator.numPhases()),
      55         940 :     _base_name(isParamValid("base_name") ? getParam<std::string>("base_name") + "_" : ""),
      56         468 :     _has_total_strain(hasMaterialProperty<RankTwoTensor>(_base_name + "total_strain")),
      57         936 :     _total_strain(_has_total_strain
      58         754 :                       ? &getMaterialProperty<RankTwoTensor>(_base_name + "total_strain")
      59             :                       : nullptr),
      60         468 :     _fluid_present(_num_phases > 0),
      61         936 :     _include_porous_skeleton(getParam<bool>("include_porous_skeleton")),
      62         936 :     _phase_index(getParam<std::vector<unsigned int>>("phase")),
      63         936 :     _porosity(getMaterialProperty<Real>("PorousFlow_porosity_nodal")),
      64         936 :     _rock_energy_nodal(getMaterialProperty<Real>("PorousFlow_matrix_internal_energy_nodal")),
      65         914 :     _fluid_density(_fluid_present ? &getMaterialProperty<std::vector<Real>>(
      66             :                                         "PorousFlow_fluid_phase_density_nodal")
      67             :                                   : nullptr),
      68         468 :     _fluid_saturation_nodal(
      69         914 :         _fluid_present ? &getMaterialProperty<std::vector<Real>>("PorousFlow_saturation_nodal")
      70             :                        : nullptr),
      71         914 :     _energy_nodal(_fluid_present ? &getMaterialProperty<std::vector<Real>>(
      72             :                                        "PorousFlow_fluid_phase_internal_energy_nodal")
      73             :                                  : nullptr),
      74        1404 :     _var(getParam<unsigned>("kernel_variable_number") < _dictator.numVariables()
      75         934 :              ? &_fe_problem.getStandardVariable(
      76         466 :                    _tid,
      77         466 :                    _dictator
      78        1400 :                        .getCoupledStandardMooseVars()[getParam<unsigned>("kernel_variable_number")]
      79             :                        ->name())
      80         468 :              : nullptr)
      81             : {
      82         468 :   if (!_phase_index.empty())
      83             :   {
      84             :     // Check that the phase indices entered are not greater than the number of phases
      85         332 :     const unsigned int max_phase_num = *std::max_element(_phase_index.begin(), _phase_index.end());
      86         332 :     if (max_phase_num > _num_phases - 1)
      87           2 :       paramError("phase",
      88             :                  "The Dictator proclaims that the phase index ",
      89             :                  max_phase_num,
      90             :                  " is greater than the largest phase index possible, which is ",
      91             :                  _num_phases - 1);
      92             :   }
      93             : 
      94             :   // Check that kernel_variable_number is OK
      95        1398 :   if (getParam<unsigned>("kernel_variable_number") >= _dictator.numVariables())
      96           2 :     paramError("kernel_variable_number",
      97             :                "The Dictator pronounces that the number of PorousFlow variables is ",
      98           2 :                _dictator.numVariables(),
      99             :                ", however you have used ",
     100           2 :                getParam<unsigned>("kernel_variable_number"),
     101             :                ". This is an error");
     102             : 
     103             :   // Now that we know kernel_variable_number is OK, _var must be OK,
     104             :   // so ensure that reinit is called on _var:
     105         464 :   addMooseVariableDependency(_var);
     106             : 
     107             :   // Error if a strain base_name is provided but doesn't exist
     108         928 :   if (parameters.isParamSetByUser("base_name") && !_has_total_strain)
     109           2 :     paramError("base_name", "A strain base_name ", _base_name, " does not exist");
     110         462 : }
     111             : 
     112             : Real
     113        2726 : PorousFlowHeatEnergy::computeIntegral()
     114             : {
     115             :   Real sum = 0;
     116             : 
     117             :   // The use of _test in the loops below mean that the
     118             :   // integral is exactly the same as the one computed
     119             :   // by the PorousFlowMassTimeDerivative Kernel.  Because that
     120             :   // Kernel is lumped, this Postprocessor also needs to
     121             :   // be lumped.  Hence the use of the "nodal" Material
     122             :   // Properties
     123        2726 :   const VariableTestValue & test = _var->phi();
     124             : 
     125       15978 :   for (unsigned node = 0; node < test.size(); ++node)
     126             :   {
     127             :     Real nodal_volume = 0.0;
     128       86484 :     for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
     129             :     {
     130       73232 :       const Real n_v = _JxW[_qp] * _coord[_qp] * test[node][_qp];
     131       73232 :       if (_has_total_strain)
     132       27616 :         nodal_volume += n_v * (1.0 + (*_total_strain)[_qp].trace());
     133             :       else
     134       45616 :         nodal_volume += n_v;
     135             :     }
     136             : 
     137             :     Real energy = 0.0;
     138       13252 :     if (_include_porous_skeleton)
     139       12312 :       energy += (1.0 - _porosity[node]) * _rock_energy_nodal[node];
     140             : 
     141       18988 :     for (auto ph : _phase_index)
     142        5736 :       energy += (*_fluid_density)[node][ph] * (*_fluid_saturation_nodal)[node][ph] *
     143        5736 :                 (*_energy_nodal)[node][ph] * _porosity[node];
     144             : 
     145       13252 :     sum += nodal_volume * energy;
     146             :   }
     147             : 
     148        2726 :   return sum;
     149             : }
     150             : 
     151             : Real
     152           0 : PorousFlowHeatEnergy::computeQpIntegral()
     153             : {
     154           0 :   return 0.0;
     155             : }

Generated by: LCOV version 1.14