www.mooseframework.org
PorousFlowHeatEnergy.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 
17 
20 {
22  params.addRequiredParam<UserObjectName>(
23  "PorousFlowDictator", "The UserObject that holds the list of PorousFlow variable names.");
24  params.addParam<bool>(
25  "include_porous_skeleton", true, "Include the heat energy of the porous skeleton");
26  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  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  params.set<bool>("use_displaced_mesh") = false;
39  params.suppressParameter<bool>("use_displaced_mesh");
40  params.addParam<unsigned int>("kernel_variable_number",
41  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  params.addClassDescription("Calculates the sum of heat energy of fluid phase(s) and/or the "
47  "porous skeleton in a region");
48  return params;
49 }
50 
52  : ElementIntegralPostprocessor(parameters),
53  _dictator(getUserObject<PorousFlowDictator>("PorousFlowDictator")),
54  _num_phases(_dictator.numPhases()),
55  _base_name(isParamValid("base_name") ? getParam<std::string>("base_name") + "_" : ""),
56  _has_total_strain(hasMaterialProperty<RankTwoTensor>(_base_name + "total_strain")),
57  _total_strain(_has_total_strain
58  ? &getMaterialProperty<RankTwoTensor>(_base_name + "total_strain")
59  : nullptr),
60  _fluid_present(_num_phases > 0),
61  _include_porous_skeleton(getParam<bool>("include_porous_skeleton")),
62  _phase_index(getParam<std::vector<unsigned int>>("phase")),
63  _porosity(getMaterialProperty<Real>("PorousFlow_porosity_nodal")),
64  _rock_energy_nodal(getMaterialProperty<Real>("PorousFlow_matrix_internal_energy_nodal")),
65  _fluid_density(_fluid_present ? &getMaterialProperty<std::vector<Real>>(
66  "PorousFlow_fluid_phase_density_nodal")
67  : nullptr),
68  _fluid_saturation_nodal(
69  _fluid_present ? &getMaterialProperty<std::vector<Real>>("PorousFlow_saturation_nodal")
70  : nullptr),
71  _energy_nodal(_fluid_present ? &getMaterialProperty<std::vector<Real>>(
72  "PorousFlow_fluid_phase_internal_energy_nodal")
73  : nullptr),
74  _var(getParam<unsigned>("kernel_variable_number") < _dictator.numVariables()
75  ? &_fe_problem.getStandardVariable(
76  _tid,
77  _dictator
78  .getCoupledStandardMooseVars()[getParam<unsigned>("kernel_variable_number")]
79  ->name())
80  : nullptr)
81 {
82  if (!_phase_index.empty())
83  {
84  // Check that the phase indices entered are not greater than the number of phases
85  const unsigned int max_phase_num = *std::max_element(_phase_index.begin(), _phase_index.end());
86  if (max_phase_num > _num_phases - 1)
87  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  if (getParam<unsigned>("kernel_variable_number") >= _dictator.numVariables())
96  paramError("kernel_variable_number",
97  "The Dictator pronounces that the number of PorousFlow variables is ",
99  ", however you have used ",
100  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:
106 }
107 
108 Real
110 {
111  Real sum = 0;
112 
113  // The use of _test in the loops below mean that the
114  // integral is exactly the same as the one computed
115  // by the PorousFlowMassTimeDerivative Kernel. Because that
116  // Kernel is lumped, this Postprocessor also needs to
117  // be lumped. Hence the use of the "nodal" Material
118  // Properties
119  const VariableTestValue & test = _var->phi();
120 
121  for (unsigned node = 0; node < test.size(); ++node)
122  {
123  Real nodal_volume = 0.0;
124  for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
125  {
126  const Real n_v = _JxW[_qp] * _coord[_qp] * test[node][_qp];
127  if (_has_total_strain)
128  nodal_volume += n_v * (1.0 + (*_total_strain)[_qp].trace());
129  else
130  nodal_volume += n_v;
131  }
132 
133  Real energy = 0.0;
135  energy += (1.0 - _porosity[node]) * _rock_energy_nodal[node];
136 
137  for (auto ph : _phase_index)
138  energy += (*_fluid_density)[node][ph] * (*_fluid_saturation_nodal)[node][ph] *
139  (*_energy_nodal)[node][ph] * _porosity[node];
140 
141  sum += nodal_volume * energy;
142  }
143 
144  return sum;
145 }
146 
147 Real
149 {
150  return 0.0;
151 }
const MooseArray< Real > & _coord
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
virtual Real computeQpIntegral() override
T & set(const std::string &name, bool quiet_mode=false)
void addRequiredParam(const std::string &name, const std::string &doc_string)
void suppressParameter(const std::string &name)
const MaterialProperty< Real > & _porosity
Porosity.
const MaterialProperty< Real > & _rock_energy_nodal
Nodal rock energy density.
Postprocessor produces the sum of heat energy of the porous skeleton and/or fluid components in a reg...
static InputParameters validParams()
const PorousFlowDictator & _dictator
PorousFlowDictator UserObject.
const unsigned int _num_phases
Number of fluid phases.
OutputTools< Real >::VariableTestValue VariableTestValue
const FieldVariablePhiValue & phi() const override
const std::string name
Definition: Setup.h:20
void paramError(const std::string &param, Args... args) const
unsigned int numVariables() const
The number of PorousFlow variables.
void addMooseVariableDependency(MooseVariableFieldBase *var)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
MooseVariable *const _var
The variable for the corresponding PorousFlowEnergyTimeDerivative Kernel: this provides test function...
const QBase *const & _qrule
This holds maps between the nonlinear variables used in a PorousFlow simulation and the variable numb...
std::vector< unsigned int > _phase_index
The phase indices that this Postprocessor is restricted to.
const MooseArray< Real > & _JxW
registerMooseObject("PorousFlowApp", PorousFlowHeatEnergy)
const bool _include_porous_skeleton
Whether to include the heat energy of the porous skeleton in the calculations.
void addClassDescription(const std::string &doc_string)
virtual Real computeIntegral() override
PorousFlowHeatEnergy(const InputParameters &parameters)
void ErrorVector unsigned int
const bool _has_total_strain
Whether there is a Material called _base_name_total_strain.
static InputParameters validParams()