www.mooseframework.org
PorousFlowMassVolumetricExpansion.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 
15 
18 {
20  params.addParam<bool>("strain_at_nearest_qp",
21  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  params.addParam<bool>(
28  "multiply_by_density",
29  true,
30  "If true, then this Kernel represents component_mass*rate_of_solid_volumetric_expansion. If "
31  "flase, then this Kernel represents component_volume*rate_of_solid_volumetric_expansion "
32  "(care must then be taken when using other PorousFlow objects, such as the "
33  "PorousFlowFluidMass postprocessor).");
34  params.addParam<unsigned int>(
35  "fluid_component", 0, "The index corresponding to the component for this kernel");
36  params.addRequiredParam<UserObjectName>(
37  "PorousFlowDictator", "The UserObject that holds the list of PorousFlow variable names.");
38  params.set<bool>("use_displaced_mesh") = false;
39  params.suppressParameter<bool>("use_displaced_mesh");
40  params.addClassDescription("Component_mass*rate_of_solid_volumetric_expansion. This Kernel "
41  "lumps the component mass to the nodes.");
42  return params;
43 }
44 
46  const InputParameters & parameters)
47  : TimeKernel(parameters),
48  _fluid_component(getParam<unsigned int>("fluid_component")),
49  _dictator(getUserObject<PorousFlowDictator>("PorousFlowDictator")),
50  _var_is_porflow_var(!_dictator.notPorousFlowVariable(_var.number())),
51  _num_phases(_dictator.numPhases()),
52  _strain_at_nearest_qp(getParam<bool>("strain_at_nearest_qp")),
53  _multiply_by_density(getParam<bool>("multiply_by_density")),
54  _porosity(getMaterialProperty<Real>("PorousFlow_porosity_nodal")),
55  _dporosity_dvar(getMaterialProperty<std::vector<Real>>("dPorousFlow_porosity_nodal_dvar")),
56  _dporosity_dgradvar(
57  getMaterialProperty<std::vector<RealGradient>>("dPorousFlow_porosity_nodal_dgradvar")),
58  _nearest_qp(_strain_at_nearest_qp
59  ? &getMaterialProperty<unsigned int>("PorousFlow_nearestqp_nodal")
60  : nullptr),
61  _fluid_density(_multiply_by_density ? &getMaterialProperty<std::vector<Real>>(
62  "PorousFlow_fluid_phase_density_nodal")
63  : nullptr),
64  _dfluid_density_dvar(_multiply_by_density
65  ? &getMaterialProperty<std::vector<std::vector<Real>>>(
66  "dPorousFlow_fluid_phase_density_nodal_dvar")
67  : nullptr),
68  _fluid_saturation(getMaterialProperty<std::vector<Real>>("PorousFlow_saturation_nodal")),
69  _dfluid_saturation_dvar(
70  getMaterialProperty<std::vector<std::vector<Real>>>("dPorousFlow_saturation_nodal_dvar")),
71  _mass_frac(getMaterialProperty<std::vector<std::vector<Real>>>("PorousFlow_mass_frac_nodal")),
72  _dmass_frac_dvar(getMaterialProperty<std::vector<std::vector<std::vector<Real>>>>(
73  "dPorousFlow_mass_frac_nodal_dvar")),
74  _strain_rate_qp(getMaterialProperty<Real>("PorousFlow_volumetric_strain_rate_qp")),
75  _dstrain_rate_qp_dvar(getMaterialProperty<std::vector<RealGradient>>(
76  "dPorousFlow_volumetric_strain_rate_qp_dvar"))
77 {
79  mooseError("The Dictator proclaims that the number of components in this simulation is ",
81  " whereas you have used the Kernel PorousFlowComponetMassVolumetricExpansion with "
82  "component = ",
84  ". The Dictator is watching you");
85 }
86 
87 Real
89 {
90  Real mass = 0.0;
91  for (unsigned ph = 0; ph < _num_phases; ++ph)
92  {
93  const Real dens = (_multiply_by_density ? (*_fluid_density)[_i][ph] : 1.0);
94  mass += dens * _fluid_saturation[_i][ph] * _mass_frac[_i][ph][_fluid_component];
95  }
96 
97  return _test[_i][_qp] * mass * _porosity[_i] * _strain_rate_qp[_qp];
98 }
99 
100 Real
102 {
104 }
105 
106 Real
108 {
109  return computedMassQpJac(jvar) + computedVolQpJac(jvar);
110 }
111 
112 Real
114 {
116  return 0.0;
117 
118  const unsigned int pvar = _dictator.porousFlowVariableNum(jvar);
119 
120  Real mass = 0.0;
121  for (unsigned ph = 0; ph < _num_phases; ++ph)
122  {
123  const Real dens = (_multiply_by_density ? (*_fluid_density)[_i][ph] : 1.0);
124  mass += dens * _fluid_saturation[_i][ph] * _mass_frac[_i][ph][_fluid_component];
125  }
126 
127  Real dvol = _dstrain_rate_qp_dvar[_qp][pvar] * _grad_phi[_j][_qp];
128 
129  return _test[_i][_qp] * mass * _porosity[_i] * dvol;
130 }
131 Real
133 {
135  return 0.0;
136 
137  const unsigned int pvar = _dictator.porousFlowVariableNum(jvar);
138  const unsigned nearest_qp = (_strain_at_nearest_qp ? (*_nearest_qp)[_i] : _i);
139 
140  Real dmass = 0.0;
141  for (unsigned ph = 0; ph < _num_phases; ++ph)
142  {
143  const Real dens = (_multiply_by_density ? (*_fluid_density)[_i][ph] : 1.0);
144  dmass += dens * _fluid_saturation[_i][ph] * _mass_frac[_i][ph][_fluid_component] *
145  _dporosity_dgradvar[_i][pvar] * _grad_phi[_j][nearest_qp];
146  }
147 
148  if (_i != _j)
149  return _test[_i][_qp] * dmass * _strain_rate_qp[_qp];
150 
151  for (unsigned ph = 0; ph < _num_phases; ++ph)
152  {
154  dmass += (*_dfluid_density_dvar)[_i][ph][pvar] * _fluid_saturation[_i][ph] *
156  const Real dens = (_multiply_by_density ? (*_fluid_density)[_i][ph] : 1.0);
157  dmass += dens * _dfluid_saturation_dvar[_i][ph][pvar] * _mass_frac[_i][ph][_fluid_component] *
158  _porosity[_i];
159  dmass += dens * _fluid_saturation[_i][ph] * _dmass_frac_dvar[_i][ph][_fluid_component][pvar] *
160  _porosity[_i];
161  dmass += dens * _fluid_saturation[_i][ph] * _mass_frac[_i][ph][_fluid_component] *
162  _dporosity_dvar[_i][pvar];
163  }
164 
165  return _test[_i][_qp] * dmass * _strain_rate_qp[_qp];
166 }
const MaterialProperty< std::vector< std::vector< Real > > > & _mass_frac
Mass fraction.
const MaterialProperty< std::vector< std::vector< Real > > > & _dfluid_saturation_dvar
d(fluid saturation)/d(PorousFlow variable)
PorousFlowMassVolumetricExpansion(const InputParameters &parameters)
bool notPorousFlowVariable(unsigned int moose_var_num) const
Returns true if moose_var_num is not a porous flow variabe.
MooseVariable & _var
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
unsigned int number() const
const MaterialProperty< std::vector< Real > > & _dporosity_dvar
d(porosity)/d(PorousFlow variable)
const MaterialProperty< Real > & _porosity
Porosity.
const VariablePhiGradient & _grad_phi
const unsigned int _fluid_component
The fluid component index.
const MaterialProperty< std::vector< std::vector< std::vector< Real > > > > & _dmass_frac_dvar
d(mass fraction)/d(PorousFlow variable)
T & set(const std::string &name, bool quiet_mode=false)
unsigned int numComponents() const
The number of fluid components.
const MaterialProperty< std::vector< Real > > & _fluid_saturation
Fluid saturation.
const bool _multiply_by_density
Whether to multiply by density: if true then this Kernel involves the fluid mass, otherwise it involv...
const PorousFlowDictator & _dictator
PorousFlowDictator UserObject.
void addRequiredParam(const std::string &name, const std::string &doc_string)
void suppressParameter(const std::string &name)
const VariableTestValue & _test
const MaterialProperty< std::vector< RealGradient > > & _dstrain_rate_qp_dvar
d(strain rate)/d(PorousFlow variable)
unsigned int _i
virtual Real computeQpOffDiagJacobian(unsigned int jvar) override
const unsigned int _num_phases
Number of fluid phases.
unsigned int _j
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Kernel = mass_component * d(volumetric_strain)/dt where mass_component = porosity*sum_phases(density_...
This holds maps between the nonlinear variables used in a PorousFlow simulation and the variable numb...
const MaterialProperty< Real > & _strain_rate_qp
Strain rate.
const MaterialProperty< std::vector< RealGradient > > & _dporosity_dgradvar
d(porosity)/d(grad PorousFlow variable)
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
unsigned int porousFlowVariableNum(unsigned int moose_var_num) const
The PorousFlow variable number.
Real computedMassQpJac(unsigned int jvar) const
Derivative of mass part of the residual with respect to the Variable with variable number jvar...
Real computedVolQpJac(unsigned int jvar) const
Derivative of volumetric-strain part of the residual with respect to the Variable with variable numbe...
static InputParameters validParams()
void ErrorVector unsigned int
registerMooseObject("PorousFlowApp", PorousFlowMassVolumetricExpansion)
unsigned int _qp
const bool _strain_at_nearest_qp
Whether the porosity uses the volumetric strain at the closest quadpoint.