https://mooseframework.inl.gov
Loading...
Searching...
No Matches
PorousFlowMassVolumetricExpansion.C
Go to the documentation of this file.
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
11
12#include "MooseVariable.h"
13
14#include "libmesh/quadrature.h"
15
18
19template <bool is_ad>
22{
24 params.set<MultiMooseEnum>("vector_tags") = "time";
25 params.set<MultiMooseEnum>("matrix_tags") = "system time";
26 params.addParam<bool>("strain_at_nearest_qp",
27 false,
28 "When calculating nodal porosity that depends on strain, use the strain at "
29 "the nearest quadpoint. This adds a small extra computational burden, and "
30 "is not necessary for simulations involving only linear lagrange elements. "
31 " If you set this to true, you will also want to set the same parameter to "
32 "true for related Kernels and Materials");
33 params.addParam<bool>(
34 "multiply_by_density",
35 true,
36 "If true, then this Kernel represents component_mass*rate_of_solid_volumetric_expansion. If "
37 "flase, then this Kernel represents component_volume*rate_of_solid_volumetric_expansion "
38 "(care must then be taken when using other PorousFlow objects, such as the "
39 "PorousFlowFluidMass postprocessor).");
40 params.addParam<unsigned int>(
41 "fluid_component", 0, "The index corresponding to the component for this kernel");
42 params.addRequiredParam<UserObjectName>(
43 "PorousFlowDictator", "The UserObject that holds the list of PorousFlow variable names.");
44 params.set<bool>("use_displaced_mesh") = false;
45 params.suppressParameter<bool>("use_displaced_mesh");
46 params.addClassDescription("Component_mass*rate_of_solid_volumetric_expansion. This Kernel "
47 "lumps the component mass to the nodes.");
48 return params;
49}
50
51template <bool is_ad>
53 const InputParameters & parameters)
54 : PorousFlowLumpedKernelBaseTempl<is_ad>(parameters),
55 _fluid_component(this->template getParam<unsigned int>("fluid_component")),
56 _dictator(this->template getUserObject<PorousFlowDictator>("PorousFlowDictator")),
57 _var_is_porflow_var(!_dictator.notPorousFlowVariable(_var.number())),
58 _num_phases(_dictator.numPhases()),
59 _strain_at_nearest_qp(this->template getParam<bool>("strain_at_nearest_qp")),
60 _multiply_by_density(this->template getParam<bool>("multiply_by_density")),
61 _porosity(this->template getGenericMaterialProperty<Real, is_ad>("PorousFlow_porosity_nodal")),
62 _dporosity_dvar(is_ad ? nullptr
63 : &this->template getMaterialProperty<std::vector<Real>>(
64 "dPorousFlow_porosity_nodal_dvar")),
65 _dporosity_dgradvar(is_ad ? nullptr
66 : &this->template getMaterialProperty<std::vector<RealGradient>>(
67 "dPorousFlow_porosity_nodal_dgradvar")),
68 _nearest_qp(_strain_at_nearest_qp ? &this->template getMaterialProperty<unsigned int>(
69 "PorousFlow_nearestqp_nodal")
70 : nullptr),
71 _fluid_density(_multiply_by_density
72 ? &this->template getGenericMaterialProperty<std::vector<Real>, is_ad>(
73 "PorousFlow_fluid_phase_density_nodal")
74 : nullptr),
75 _dfluid_density_dvar(_multiply_by_density && !is_ad
76 ? &this->template getMaterialProperty<std::vector<std::vector<Real>>>(
77 "dPorousFlow_fluid_phase_density_nodal_dvar")
78 : nullptr),
79 _fluid_saturation(this->template getGenericMaterialProperty<std::vector<Real>, is_ad>(
80 "PorousFlow_saturation_nodal")),
81 _dfluid_saturation_dvar(
82 is_ad ? nullptr
83 : &this->template getMaterialProperty<std::vector<std::vector<Real>>>(
84 "dPorousFlow_saturation_nodal_dvar")),
85 _mass_frac(this->template getGenericMaterialProperty<std::vector<std::vector<Real>>, is_ad>(
86 "PorousFlow_mass_frac_nodal")),
87 _dmass_frac_dvar(
88 is_ad ? nullptr
89 : &this->template getMaterialProperty<std::vector<std::vector<std::vector<Real>>>>(
90 "dPorousFlow_mass_frac_nodal_dvar")),
91 _strain_rate_qp(this->template getGenericMaterialProperty<Real, is_ad>(
92 "PorousFlow_volumetric_strain_rate_qp")),
93 _dstrain_rate_qp_dvar(is_ad ? nullptr
94 : &this->template getMaterialProperty<std::vector<RealGradient>>(
95 "dPorousFlow_volumetric_strain_rate_qp_dvar"))
96{
98 this->mooseError(
99 "The Dictator proclaims that the number of components in this simulation is ",
101 " whereas you have used the Kernel PorousFlowComponetMassVolumetricExpansion with "
102 "component = ",
104 ". The Dictator is watching you");
105}
106
107template <bool is_ad>
110{
111 GenericReal<is_ad> mass = 0.0;
112 for (unsigned ph = 0; ph < _num_phases; ++ph)
113 {
114 const GenericReal<is_ad> dens =
115 (_multiply_by_density ? (*_fluid_density)[_i][ph] : GenericReal<is_ad>(1.0));
116 mass += dens * _fluid_saturation[_i][ph] * _mass_frac[_i][ph][_fluid_component];
117 }
118
119 return _test[_i][_qp] * mass * _porosity[_i] * _strain_rate_qp[_qp];
120}
121
122template <bool is_ad>
123Real
125{
126 return computedMassQpJac(_var.number()) + computedVolQpJac(_var.number());
127}
128
129template <bool is_ad>
130Real
132{
133 return computedMassQpJac(jvar) + computedVolQpJac(jvar);
134}
135
136template <bool is_ad>
137Real
139{
140 if constexpr (!is_ad)
141 {
142 if (_dictator.notPorousFlowVariable(jvar))
143 return 0.0;
144
145 const unsigned int pvar = _dictator.porousFlowVariableNum(jvar);
146
147 Real mass = 0.0;
148 for (unsigned ph = 0; ph < _num_phases; ++ph)
149 {
150 const Real dens = (_multiply_by_density ? (*_fluid_density)[_i][ph] : 1.0);
151 mass += dens * _fluid_saturation[_i][ph] * _mass_frac[_i][ph][_fluid_component];
152 }
153
154 Real dvol = (*_dstrain_rate_qp_dvar)[_qp][pvar] * _grad_phi[_j][_qp];
155
156 return _test[_i][_qp] * mass * _porosity[_i] * dvol;
157 }
158 else
159 {
160 libmesh_ignore(jvar);
161 return 0.0;
162 }
163}
164
165template <bool is_ad>
166Real
168{
169 if constexpr (!is_ad)
170 {
171 if (_dictator.notPorousFlowVariable(jvar))
172 return 0.0;
173
174 const unsigned int pvar = _dictator.porousFlowVariableNum(jvar);
175 const unsigned nearest_qp = (_strain_at_nearest_qp ? (*_nearest_qp)[_i] : _i);
176
177 Real dmass = 0.0;
178 for (unsigned ph = 0; ph < _num_phases; ++ph)
179 {
180 const Real dens = (_multiply_by_density ? (*_fluid_density)[_i][ph] : 1.0);
181 dmass += dens * _fluid_saturation[_i][ph] * _mass_frac[_i][ph][_fluid_component] *
182 (*_dporosity_dgradvar)[_i][pvar] * _grad_phi[_j][nearest_qp];
183 }
184
185 if (_i != _j)
186 return _test[_i][_qp] * dmass * _strain_rate_qp[_qp];
187
188 for (unsigned ph = 0; ph < _num_phases; ++ph)
189 {
190 if (_multiply_by_density)
191 dmass += (*_dfluid_density_dvar)[_i][ph][pvar] * _fluid_saturation[_i][ph] *
192 _mass_frac[_i][ph][_fluid_component] * _porosity[_i];
193 const Real dens = (_multiply_by_density ? (*_fluid_density)[_i][ph] : 1.0);
194 dmass += dens * (*_dfluid_saturation_dvar)[_i][ph][pvar] *
195 _mass_frac[_i][ph][_fluid_component] * _porosity[_i];
196 dmass += dens * _fluid_saturation[_i][ph] *
197 (*_dmass_frac_dvar)[_i][ph][_fluid_component][pvar] * _porosity[_i];
198 dmass += dens * _fluid_saturation[_i][ph] * _mass_frac[_i][ph][_fluid_component] *
199 (*_dporosity_dvar)[_i][pvar];
200 }
201
202 return _test[_i][_qp] * dmass * _strain_rate_qp[_qp];
203 }
204 else
205 {
206 libmesh_ignore(jvar);
207 return 0.0;
208 }
209}
210
Moose::GenericType< Real, is_ad > GenericReal
registerMooseObject("PorousFlowApp", PorousFlowMassVolumetricExpansion)
void ErrorVector unsigned int
static InputParameters validParams()
void suppressParameter(const std::string &name)
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
T & set(const std::string &name, bool quiet_mode=false)
void mooseError(Args &&... args) const
This holds maps between the nonlinear variables used in a PorousFlow simulation and the variable numb...
unsigned int numComponents() const
The number of fluid components.
Base class for PorousFlow kernels that use mass-lumped (nodal) material properties.
Kernel = mass_component * rate_of_solid_volumetric_expansion where mass_component = porosity * sum_ph...
virtual Real computeQpOffDiagJacobian(unsigned int jvar) override
const unsigned int _fluid_component
The fluid component index.
Real computedVolQpJac(unsigned int jvar) const
Derivative of volumetric-strain part of the residual with respect to the Variable with variable numbe...
Real computedMassQpJac(unsigned int jvar) const
Derivative of mass part of the residual with respect to the Variable with variable number jvar.
virtual GenericReal< is_ad > computeQpResidual() override
PorousFlowMassVolumetricExpansionTempl(const InputParameters &parameters)
const PorousFlowDictator & _dictator
PorousFlowDictator UserObject.