www.mooseframework.org
PorousFlowEnergyTimeDerivative.C
Go to the documentation of this file.
1 /****************************************************************/
2 /* MOOSE - Multiphysics Object Oriented Simulation Environment */
3 /* */
4 /* All contents are licensed under LGPL V2.1 */
5 /* See LICENSE for full restrictions */
6 /****************************************************************/
7 
9 
10 // MOOSE includes
11 #include "MooseVariable.h"
12 
13 template <>
14 InputParameters
16 {
17  InputParameters params = validParams<TimeKernel>();
18  params.addParam<bool>("strain_at_nearest_qp",
19  false,
20  "When calculating nodal porosity that depends on strain, use the strain at "
21  "the nearest quadpoint. This adds a small extra computational burden, and "
22  "is not necessary for simulations involving only linear lagrange elements. "
23  " If you set this to true, you will also want to set the same parameter to "
24  "true for related Kernels and Materials");
25  params.addRequiredParam<UserObjectName>(
26  "PorousFlowDictator", "The UserObject that holds the list of Porous-Flow variable names.");
27  params.addClassDescription("Derivative of heat-energy-density wrt time");
28  return params;
29 }
30 
32  : TimeKernel(parameters),
33  _dictator(getUserObject<PorousFlowDictator>("PorousFlowDictator")),
34  _var_is_porflow_var(_dictator.isPorousFlowVariable(_var.number())),
35  _num_phases(_dictator.numPhases()),
36  _fluid_present(_num_phases > 0),
37  _strain_at_nearest_qp(getParam<bool>("strain_at_nearest_qp")),
38  _porosity(getMaterialProperty<Real>("PorousFlow_porosity_nodal")),
39  _porosity_old(getMaterialPropertyOld<Real>("PorousFlow_porosity_nodal")),
40  _dporosity_dvar(getMaterialProperty<std::vector<Real>>("dPorousFlow_porosity_nodal_dvar")),
41  _dporosity_dgradvar(
42  getMaterialProperty<std::vector<RealGradient>>("dPorousFlow_porosity_nodal_dgradvar")),
43  _nearest_qp(_strain_at_nearest_qp
44  ? &getMaterialProperty<unsigned int>("PorousFlow_nearestqp_nodal")
45  : nullptr),
46  _rock_energy_nodal(getMaterialProperty<Real>("PorousFlow_matrix_internal_energy_nodal")),
47  _rock_energy_nodal_old(getMaterialPropertyOld<Real>("PorousFlow_matrix_internal_energy_nodal")),
48  _drock_energy_nodal_dvar(
49  getMaterialProperty<std::vector<Real>>("dPorousFlow_matrix_internal_energy_nodal_dvar")),
50  _fluid_density(
51  _fluid_present
52  ? &getMaterialProperty<std::vector<Real>>("PorousFlow_fluid_phase_density_nodal")
53  : nullptr),
54  _fluid_density_old(
55  _fluid_present
56  ? &getMaterialPropertyOld<std::vector<Real>>("PorousFlow_fluid_phase_density_nodal")
57  : nullptr),
58  _dfluid_density_dvar(_fluid_present
59  ? &getMaterialProperty<std::vector<std::vector<Real>>>(
60  "dPorousFlow_fluid_phase_density_nodal_dvar")
61  : nullptr),
62  _fluid_saturation_nodal(
63  _fluid_present ? &getMaterialProperty<std::vector<Real>>("PorousFlow_saturation_nodal")
64  : nullptr),
65  _fluid_saturation_nodal_old(
66  _fluid_present ? &getMaterialPropertyOld<std::vector<Real>>("PorousFlow_saturation_nodal")
67  : nullptr),
68  _dfluid_saturation_nodal_dvar(_fluid_present
69  ? &getMaterialProperty<std::vector<std::vector<Real>>>(
70  "dPorousFlow_saturation_nodal_dvar")
71  : nullptr),
72  _energy_nodal(_fluid_present
73  ? &getMaterialProperty<std::vector<Real>>(
74  "PorousFlow_fluid_phase_internal_energy_nodal")
75  : nullptr),
76  _energy_nodal_old(_fluid_present
77  ? &getMaterialPropertyOld<std::vector<Real>>(
78  "PorousFlow_fluid_phase_internal_energy_nodal")
79  : nullptr),
80  _denergy_nodal_dvar(_fluid_present
81  ? &getMaterialProperty<std::vector<std::vector<Real>>>(
82  "dPorousFlow_fluid_phase_internal_energy_nodal_dvar")
83  : nullptr)
84 {
85 }
86 
87 Real
89 {
90  Real energy = (1.0 - _porosity[_i]) * _rock_energy_nodal[_i];
91  Real energy_old = (1.0 - _porosity_old[_i]) * _rock_energy_nodal_old[_i];
92  for (unsigned ph = 0; ph < _num_phases; ++ph)
93  {
94  energy += (*_fluid_density)[_i][ph] * (*_fluid_saturation_nodal)[_i][ph] *
95  (*_energy_nodal)[_i][ph] * _porosity[_i];
96  energy_old += (*_fluid_density_old)[_i][ph] * (*_fluid_saturation_nodal_old)[_i][ph] *
97  (*_energy_nodal_old)[_i][ph] * _porosity_old[_i];
98  }
99 
100  return _test[_i][_qp] * (energy - energy_old) / _dt;
101 }
102 
103 Real
105 {
107  if (!_var_is_porflow_var)
108  return 0.0;
109  return computeQpJac(_dictator.porousFlowVariableNum(_var.number()));
110 }
111 
112 Real
114 {
117  return 0.0;
119 }
120 
121 Real
123 {
124  const unsigned nearest_qp = (_strain_at_nearest_qp ? (*_nearest_qp)[_i] : _i);
125 
126  // porosity is dependent on variables that are lumped to the nodes,
127  // but it can depend on the gradient
128  // of variables, which are NOT lumped to the nodes, hence:
129  Real denergy = -_dporosity_dgradvar[_i][pvar] * _grad_phi[_j][_i] * _rock_energy_nodal[_i];
130  for (unsigned ph = 0; ph < _num_phases; ++ph)
131  denergy += (*_fluid_density)[_i][ph] * (*_fluid_saturation_nodal)[_i][ph] *
132  (*_energy_nodal)[_i][ph] * _dporosity_dgradvar[_i][pvar] * _grad_phi[_j][nearest_qp];
133 
134  if (_i != _j)
135  return _test[_i][_qp] * denergy / _dt;
136 
138  denergy += -_dporosity_dvar[_i][pvar] * _rock_energy_nodal[_i];
139  denergy += (1.0 - _porosity[_i]) * _drock_energy_nodal_dvar[_i][pvar];
140  for (unsigned ph = 0; ph < _num_phases; ++ph)
141  {
142  denergy += (*_dfluid_density_dvar)[_i][ph][pvar] * (*_fluid_saturation_nodal)[_i][ph] *
143  (*_energy_nodal)[_i][ph] * _porosity[_i];
144  denergy += (*_fluid_density)[_i][ph] * (*_dfluid_saturation_nodal_dvar)[_i][ph][pvar] *
145  (*_energy_nodal)[_i][ph] * _porosity[_i];
146  denergy += (*_fluid_density)[_i][ph] * (*_fluid_saturation_nodal)[_i][ph] *
147  (*_denergy_nodal_dvar)[_i][ph][pvar] * _porosity[_i];
148  denergy += (*_fluid_density)[_i][ph] * (*_fluid_saturation_nodal)[_i][ph] *
149  (*_energy_nodal)[_i][ph] * _dporosity_dvar[_i][pvar];
150  }
151  return _test[_i][_qp] * denergy / _dt;
152 }
const MaterialProperty< std::vector< Real > > *const _fluid_density
nodal fluid density
const MaterialProperty< std::vector< Real > > & _drock_energy_nodal_dvar
d(nodal rock energy density)/d(PorousFlow variable)
InputParameters validParams< PorousFlowEnergyTimeDerivative >()
const PorousFlowDictator & _dictator
holds info on the PorousFlow variables
PorousFlowEnergyTimeDerivative(const InputParameters &parameters)
const MaterialProperty< Real > & _porosity
porosity at the nodes, but it can depend on grad(variables) which are actually evaluated at the qps ...
Real computeQpJac(unsigned int pvar) const
Derivative of residual with respect to PorousFlow variable number pvar This is used by both computeQp...
const MaterialProperty< std::vector< RealGradient > > & _dporosity_dgradvar
d(porosity)/d(grad porous-flow variable) - remember these derivatives will be wrt grad(vars) at qps ...
virtual Real computeQpOffDiagJacobian(unsigned int jvar) override
const MaterialProperty< Real > & _rock_energy_nodal
nodal rock energy density
const unsigned int _num_phases
number of fluid phases
const MaterialProperty< Real > & _porosity_old
old value of porosity
This holds maps between the nonlinear variables used in a PorousFlow simulation and the variable numb...
bool notPorousFlowVariable(unsigned int moose_var_num) const
returns true if moose_var_num is not a porous flow variabe
const MaterialProperty< Real > & _rock_energy_nodal_old
old value of nodal rock energy density
unsigned int porousFlowVariableNum(unsigned int moose_var_num) const
the PorousFlow variable number
const MaterialProperty< std::vector< Real > > & _dporosity_dvar
d(porosity)/d(porous-flow variable) - these derivatives will be wrt variables at the nodes ...
const bool _var_is_porflow_var
whether the Variable for this Kernel is a porous-flow variable according to the Dictator ...
const bool _strain_at_nearest_qp
whether the porosity uses the volumetric strain at the closest quadpoint