www.mooseframework.org
PorousFlowMassTimeDerivative.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 
11 
12 #include "MooseVariable.h"
13 
14 #include "libmesh/quadrature.h"
15 
16 #include <limits>
17 
19 
20 template <>
21 InputParameters
23 {
24  InputParameters params = validParams<TimeKernel>();
25  params.addParam<bool>("strain_at_nearest_qp",
26  false,
27  "When calculating nodal porosity that depends on strain, use the strain at "
28  "the nearest quadpoint. This adds a small extra computational burden, and "
29  "is not necessary for simulations involving only linear lagrange elements. "
30  " If you set this to true, you will also want to set the same parameter to "
31  "true for related Kernels and Materials");
32  params.addParam<unsigned int>(
33  "fluid_component", 0, "The index corresponding to the component for this kernel");
34  params.addRequiredParam<UserObjectName>(
35  "PorousFlowDictator", "The UserObject that holds the list of PorousFlow variable names.");
36  params.addClassDescription(
37  "Component mass derivative wrt time for component given by fluid_component");
38  return params;
39 }
40 
42  : TimeKernel(parameters),
43  _fluid_component(getParam<unsigned int>("fluid_component")),
44  _dictator(getUserObject<PorousFlowDictator>("PorousFlowDictator")),
45  _var_is_porflow_var(_dictator.isPorousFlowVariable(_var.number())),
46  _num_phases(_dictator.numPhases()),
47  _strain_at_nearest_qp(getParam<bool>("strain_at_nearest_qp")),
48  _porosity(getMaterialProperty<Real>("PorousFlow_porosity_nodal")),
49  _porosity_old(getMaterialPropertyOld<Real>("PorousFlow_porosity_nodal")),
50  _dporosity_dvar(getMaterialProperty<std::vector<Real>>("dPorousFlow_porosity_nodal_dvar")),
51  _dporosity_dgradvar(
52  getMaterialProperty<std::vector<RealGradient>>("dPorousFlow_porosity_nodal_dgradvar")),
53  _nearest_qp(_strain_at_nearest_qp
54  ? &getMaterialProperty<unsigned int>("PorousFlow_nearestqp_nodal")
55  : nullptr),
56  _fluid_density(getMaterialProperty<std::vector<Real>>("PorousFlow_fluid_phase_density_nodal")),
57  _fluid_density_old(
58  getMaterialPropertyOld<std::vector<Real>>("PorousFlow_fluid_phase_density_nodal")),
59  _dfluid_density_dvar(getMaterialProperty<std::vector<std::vector<Real>>>(
60  "dPorousFlow_fluid_phase_density_nodal_dvar")),
61  _fluid_saturation_nodal(getMaterialProperty<std::vector<Real>>("PorousFlow_saturation_nodal")),
62  _fluid_saturation_nodal_old(
63  getMaterialPropertyOld<std::vector<Real>>("PorousFlow_saturation_nodal")),
64  _dfluid_saturation_nodal_dvar(
65  getMaterialProperty<std::vector<std::vector<Real>>>("dPorousFlow_saturation_nodal_dvar")),
66  _mass_frac(getMaterialProperty<std::vector<std::vector<Real>>>("PorousFlow_mass_frac_nodal")),
67  _mass_frac_old(
68  getMaterialPropertyOld<std::vector<std::vector<Real>>>("PorousFlow_mass_frac_nodal")),
69  _dmass_frac_dvar(getMaterialProperty<std::vector<std::vector<std::vector<Real>>>>(
70  "dPorousFlow_mass_frac_nodal_dvar"))
71 {
73  paramError(
74  "fluid_component",
75  "The Dictator proclaims that the maximum fluid component index in this simulation is ",
77  " whereas you have used ",
79  ". Remember that indexing starts at 0. The Dictator does not take such mistakes lightly.");
80 }
81 
82 Real
84 {
85  Real mass = 0.0;
86  Real mass_old = 0.0;
87  for (unsigned ph = 0; ph < _num_phases; ++ph)
88  {
89  mass += _fluid_density[_i][ph] * _fluid_saturation_nodal[_i][ph] *
91  mass_old += _fluid_density_old[_i][ph] * _fluid_saturation_nodal_old[_i][ph] *
93  }
94 
95  return _test[_i][_qp] * (_porosity[_i] * mass - _porosity_old[_i] * mass_old) / _dt;
96 }
97 
98 Real
100 {
101  // If the variable is not a PorousFlow variable (very unusual), the diag Jacobian terms are 0
102  if (!_var_is_porflow_var)
103  return 0.0;
104  return computeQpJac(_dictator.porousFlowVariableNum(_var.number()));
105 }
106 
107 Real
109 {
110  // If the variable is not a PorousFlow variable, the OffDiag Jacobian terms are 0
112  return 0.0;
114 }
115 
116 Real
118 {
119  const unsigned nearest_qp = (_strain_at_nearest_qp ? (*_nearest_qp)[_i] : _i);
120 
121  // porosity is dependent on variables that are lumped to the nodes,
122  // but it can depend on the gradient
123  // of variables, which are NOT lumped to the nodes, hence:
124  Real dmass = 0.0;
125  for (unsigned ph = 0; ph < _num_phases; ++ph)
126  dmass += _fluid_density[_i][ph] * _fluid_saturation_nodal[_i][ph] *
127  _mass_frac[_i][ph][_fluid_component] * _dporosity_dgradvar[_i][pvar] *
128  _grad_phi[_j][nearest_qp];
129 
130  if (_i != _j)
131  return _test[_i][_qp] * dmass / _dt;
132 
133  // As the fluid mass is lumped to the nodes, only non-zero terms are for _i==_j
134  for (unsigned ph = 0; ph < _num_phases; ++ph)
135  {
136  dmass += _dfluid_density_dvar[_i][ph][pvar] * _fluid_saturation_nodal[_i][ph] *
137  _mass_frac[_i][ph][_fluid_component] * _porosity[_i];
138  dmass += _fluid_density[_i][ph] * _dfluid_saturation_nodal_dvar[_i][ph][pvar] *
139  _mass_frac[_i][ph][_fluid_component] * _porosity[_i];
140  dmass += _fluid_density[_i][ph] * _fluid_saturation_nodal[_i][ph] *
141  _dmass_frac_dvar[_i][ph][_fluid_component][pvar] * _porosity[_i];
142  dmass += _fluid_density[_i][ph] * _fluid_saturation_nodal[_i][ph] *
143  _mass_frac[_i][ph][_fluid_component] * _dporosity_dvar[_i][pvar];
144  }
145  return _test[_i][_qp] * dmass / _dt;
146 }
PorousFlowMassTimeDerivative::_dictator
const PorousFlowDictator & _dictator
PorousFlowDictator UserObject.
Definition: PorousFlowMassTimeDerivative.h:40
PorousFlowMassTimeDerivative::_dporosity_dvar
const MaterialProperty< std::vector< Real > > & _dporosity_dvar
d(porosity)/d(PorousFlow variable) - these derivatives will be wrt variables at the nodes
Definition: PorousFlowMassTimeDerivative.h:58
PorousFlowMassTimeDerivative::_porosity
const MaterialProperty< Real > & _porosity
Porosity at the nodes, but it can depend on grad(variables) which are actually evaluated at the qps.
Definition: PorousFlowMassTimeDerivative.h:52
PorousFlowMassTimeDerivative
Kernel = (mass_component - mass_component_old)/dt where mass_component = porosity*sum_phases(density_...
Definition: PorousFlowMassTimeDerivative.h:26
PorousFlowMassTimeDerivative::computeQpResidual
virtual Real computeQpResidual() override
Definition: PorousFlowMassTimeDerivative.C:83
PorousFlowMassTimeDerivative::computeQpJac
Real computeQpJac(unsigned int pvar)
Derivative of residual with respect to PorousFlow variable number pvar This is used by both computeQp...
Definition: PorousFlowMassTimeDerivative.C:117
registerMooseObject
registerMooseObject("PorousFlowApp", PorousFlowMassTimeDerivative)
PorousFlowMassTimeDerivative::_fluid_component
const unsigned int _fluid_component
The fluid component index.
Definition: PorousFlowMassTimeDerivative.h:37
PorousFlowMassTimeDerivative::_mass_frac
const MaterialProperty< std::vector< std::vector< Real > > > & _mass_frac
Nodal mass fraction.
Definition: PorousFlowMassTimeDerivative.h:85
libMesh::RealGradient
VectorValue< Real > RealGradient
Definition: GrainForceAndTorqueInterface.h:17
PorousFlowDictator::notPorousFlowVariable
bool notPorousFlowVariable(unsigned int moose_var_num) const
Returns true if moose_var_num is not a porous flow variabe.
Definition: PorousFlowDictator.C:161
PorousFlowMassTimeDerivative::_fluid_density_old
const MaterialProperty< std::vector< Real > > & _fluid_density_old
Old value of nodal fluid density.
Definition: PorousFlowMassTimeDerivative.h:70
PorousFlowMassTimeDerivative::_fluid_saturation_nodal
const MaterialProperty< std::vector< Real > > & _fluid_saturation_nodal
Nodal fluid saturation.
Definition: PorousFlowMassTimeDerivative.h:76
PorousFlowMassTimeDerivative::_porosity_old
const MaterialProperty< Real > & _porosity_old
Old value of porosity.
Definition: PorousFlowMassTimeDerivative.h:55
PorousFlowMassTimeDerivative::_dfluid_saturation_nodal_dvar
const MaterialProperty< std::vector< std::vector< Real > > > & _dfluid_saturation_nodal_dvar
d(nodal fluid saturation)/d(PorousFlow variable)
Definition: PorousFlowMassTimeDerivative.h:82
PorousFlowDictator::porousFlowVariableNum
unsigned int porousFlowVariableNum(unsigned int moose_var_num) const
The PorousFlow variable number.
Definition: PorousFlowDictator.C:135
PorousFlowMassTimeDerivative::_fluid_density
const MaterialProperty< std::vector< Real > > & _fluid_density
Nodal fluid density.
Definition: PorousFlowMassTimeDerivative.h:67
PorousFlowDictator
This holds maps between the nonlinear variables used in a PorousFlow simulation and the variable numb...
Definition: PorousFlowDictator.h:71
PorousFlowMassTimeDerivative.h
validParams< PorousFlowMassTimeDerivative >
InputParameters validParams< PorousFlowMassTimeDerivative >()
Definition: PorousFlowMassTimeDerivative.C:22
PorousFlowMassTimeDerivative::_num_phases
const unsigned int _num_phases
Number of fluid phases.
Definition: PorousFlowMassTimeDerivative.h:46
PorousFlowMassTimeDerivative::_dfluid_density_dvar
const MaterialProperty< std::vector< std::vector< Real > > > & _dfluid_density_dvar
d(nodal fluid density)/d(PorousFlow variable)
Definition: PorousFlowMassTimeDerivative.h:73
PorousFlowMassTimeDerivative::PorousFlowMassTimeDerivative
PorousFlowMassTimeDerivative(const InputParameters &parameters)
Definition: PorousFlowMassTimeDerivative.C:41
PorousFlowMassTimeDerivative::_fluid_saturation_nodal_old
const MaterialProperty< std::vector< Real > > & _fluid_saturation_nodal_old
Old value of fluid saturation.
Definition: PorousFlowMassTimeDerivative.h:79
PorousFlowDictator::numComponents
unsigned int numComponents() const
The number of fluid components.
Definition: PorousFlowDictator.C:111
PorousFlowMassTimeDerivative::_dporosity_dgradvar
const MaterialProperty< std::vector< RealGradient > > & _dporosity_dgradvar
d(porosity)/d(grad PorousFlow variable) - remember these derivatives will be wrt grad(vars) at qps
Definition: PorousFlowMassTimeDerivative.h:61
PorousFlowMassTimeDerivative::_var_is_porflow_var
const bool _var_is_porflow_var
Whether the Variable for this Kernel is a PorousFlow variable according to the Dictator.
Definition: PorousFlowMassTimeDerivative.h:43
PorousFlowMassTimeDerivative::_dmass_frac_dvar
const MaterialProperty< std::vector< std::vector< std::vector< Real > > > > & _dmass_frac_dvar
d(nodal mass fraction)/d(PorousFlow variable)
Definition: PorousFlowMassTimeDerivative.h:91
PorousFlowMassTimeDerivative::_strain_at_nearest_qp
const bool _strain_at_nearest_qp
Whether the porosity uses the volumetric strain at the closest quadpoint.
Definition: PorousFlowMassTimeDerivative.h:49
PorousFlowMassTimeDerivative::computeQpJacobian
virtual Real computeQpJacobian() override
Definition: PorousFlowMassTimeDerivative.C:99
PorousFlowMassTimeDerivative::computeQpOffDiagJacobian
virtual Real computeQpOffDiagJacobian(unsigned int jvar) override
Definition: PorousFlowMassTimeDerivative.C:108
PorousFlowMassTimeDerivative::_mass_frac_old
const MaterialProperty< std::vector< std::vector< Real > > > & _mass_frac_old
Old value of nodal mass fraction.
Definition: PorousFlowMassTimeDerivative.h:88