14#include "libmesh/quadrature.h"
26 params.
addParam<
bool>(
"strain_at_nearest_qp",
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");
34 "multiply_by_density",
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).");
41 "fluid_component", 0,
"The index corresponding to the component for this kernel");
43 "PorousFlowDictator",
"The UserObject that holds the list of PorousFlow variable names.");
44 params.
set<
bool>(
"use_displaced_mesh") =
false;
46 params.
addClassDescription(
"Component_mass*rate_of_solid_volumetric_expansion. This Kernel "
47 "lumps the component mass to the nodes.");
55 _fluid_component(this->template getParam<unsigned
int>(
"fluid_component")),
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")
71 _fluid_density(_multiply_by_density
72 ? &this->template getGenericMaterialProperty<
std::vector<Real>, is_ad>(
73 "PorousFlow_fluid_phase_density_nodal")
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")
79 _fluid_saturation(this->template getGenericMaterialProperty<
std::vector<Real>, is_ad>(
80 "PorousFlow_saturation_nodal")),
81 _dfluid_saturation_dvar(
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")),
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"))
99 "The Dictator proclaims that the number of components in this simulation is ",
101 " whereas you have used the Kernel PorousFlowComponetMassVolumetricExpansion with "
104 ". The Dictator is watching you");
112 for (
unsigned ph = 0; ph < _num_phases; ++ph)
116 mass += dens * _fluid_saturation[_i][ph] * _mass_frac[_i][ph][_fluid_component];
119 return _test[_i][_qp] * mass * _porosity[_i] * _strain_rate_qp[_qp];
126 return computedMassQpJac(_var.number()) + computedVolQpJac(_var.number());
133 return computedMassQpJac(jvar) + computedVolQpJac(jvar);
140 if constexpr (!is_ad)
142 if (_dictator.notPorousFlowVariable(jvar))
145 const unsigned int pvar = _dictator.porousFlowVariableNum(jvar);
148 for (
unsigned ph = 0; ph < _num_phases; ++ph)
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];
154 Real dvol = (*_dstrain_rate_qp_dvar)[_qp][pvar] * _grad_phi[_j][_qp];
156 return _test[_i][_qp] * mass * _porosity[_i] * dvol;
160 libmesh_ignore(jvar);
169 if constexpr (!is_ad)
171 if (_dictator.notPorousFlowVariable(jvar))
174 const unsigned int pvar = _dictator.porousFlowVariableNum(jvar);
175 const unsigned nearest_qp = (_strain_at_nearest_qp ? (*_nearest_qp)[_i] : _i);
178 for (
unsigned ph = 0; ph < _num_phases; ++ph)
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];
186 return _test[_i][_qp] * dmass * _strain_rate_qp[_qp];
188 for (
unsigned ph = 0; ph < _num_phases; ++ph)
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];
202 return _test[_i][_qp] * dmass * _strain_rate_qp[_qp];
206 libmesh_ignore(jvar);
Moose::GenericType< Real, is_ad > GenericReal
registerMooseObject("PorousFlowApp", PorousFlowMassVolumetricExpansion)
void ErrorVector unsigned int
static InputParameters validParams()
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 computeQpJacobian() override
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 ¶meters)
const PorousFlowDictator & _dictator
PorousFlowDictator UserObject.
static InputParameters validParams()