14 #include "libmesh/quadrature.h" 28 params.
addParam<
bool>(
"strain_at_nearest_qp",
30 "When calculating nodal porosity that depends on strain, use the strain at " 31 "the nearest quadpoint. This adds a small extra computational burden, and " 32 "is not necessary for simulations involving only linear lagrange elements. " 33 " If you set this to true, you will also want to set the same parameter to " 34 "true for related Kernels and Materials");
36 "fluid_component", 0,
"The index corresponding to the fluid component for this kernel");
38 "The decay rate (units 1/time) for the fluid component");
40 "PorousFlowDictator",
"The UserObject that holds the list of PorousFlow variable names.");
49 _decay_rate(this->template getParam<
Real>(
"decay_rate")),
50 _fluid_component(this->template getParam<unsigned
int>(
"fluid_component")),
52 _var_is_porflow_var(_dictator.isPorousFlowVariable(_var.number())),
53 _num_phases(_dictator.numPhases()),
54 _strain_at_nearest_qp(this->template getParam<bool>(
"strain_at_nearest_qp")),
55 _porosity(this->template getGenericMaterialProperty<
Real, is_ad>(
"PorousFlow_porosity_nodal")),
56 _dporosity_dvar(is_ad ? nullptr
57 : &this->template getMaterialProperty<
std::vector<
Real>>(
58 "dPorousFlow_porosity_nodal_dvar")),
59 _dporosity_dgradvar(is_ad ? nullptr
61 "dPorousFlow_porosity_nodal_dgradvar")),
62 _nearest_qp(_strain_at_nearest_qp ? &this->template getMaterialProperty<unsigned
int>(
63 "PorousFlow_nearestqp_nodal")
65 _fluid_density(this->template getGenericMaterialProperty<
std::vector<
Real>, is_ad>(
66 "PorousFlow_fluid_phase_density_nodal")),
67 _dfluid_density_dvar(is_ad
69 : &this->template getMaterialProperty<
std::vector<
std::vector<
Real>>>(
70 "dPorousFlow_fluid_phase_density_nodal_dvar")),
71 _fluid_saturation_nodal(this->template getGenericMaterialProperty<
std::vector<
Real>, is_ad>(
72 "PorousFlow_saturation_nodal")),
73 _dfluid_saturation_nodal_dvar(
75 : &this->template getMaterialProperty<
std::vector<
std::vector<
Real>>>(
76 "dPorousFlow_saturation_nodal_dvar")),
77 _mass_frac(this->template getGenericMaterialProperty<
std::vector<
std::vector<
Real>>, is_ad>(
78 "PorousFlow_mass_frac_nodal")),
81 : &this->template getMaterialProperty<
std::vector<
std::vector<
std::vector<
Real>>>>(
82 "dPorousFlow_mass_frac_nodal_dvar"))
87 "The Dictator proclaims that the maximum fluid component index in this simulation is ",
89 " whereas you have used ",
91 ". Remember that indexing starts at 0. The Dictator does not take such mistakes lightly.");
99 for (
unsigned ph = 0; ph < _num_phases; ++ph)
100 mass += _fluid_density[_i][ph] * _fluid_saturation_nodal[_i][ph] *
101 _mass_frac[_i][ph][_fluid_component];
103 return _test[_i][_qp] * _decay_rate * _porosity[_i] * mass;
106 template <
bool is_ad>
110 if constexpr (!is_ad)
112 if (!_var_is_porflow_var)
114 return computeQpJac(_dictator.porousFlowVariableNum(_var.number()));
119 template <
bool is_ad>
123 if constexpr (!is_ad)
125 if (_dictator.notPorousFlowVariable(jvar))
127 return computeQpJac(_dictator.porousFlowVariableNum(jvar));
134 template <
bool is_ad>
138 if constexpr (!is_ad)
140 const unsigned nearest_qp = (_strain_at_nearest_qp ? (*_nearest_qp)[_i] : _i);
145 for (
unsigned ph = 0; ph < _num_phases; ++ph)
146 dmass += _fluid_density[_i][ph] * _fluid_saturation_nodal[_i][ph] *
147 _mass_frac[_i][ph][_fluid_component] * (*_dporosity_dgradvar)[_i][pvar] *
148 _grad_phi[_j][nearest_qp];
151 return _test[_i][_qp] * _decay_rate * dmass;
154 for (
unsigned ph = 0; ph < _num_phases; ++ph)
156 dmass += (*_dfluid_density_dvar)[_i][ph][pvar] * _fluid_saturation_nodal[_i][ph] *
157 _mass_frac[_i][ph][_fluid_component] * _porosity[_i];
158 dmass += _fluid_density[_i][ph] * (*_dfluid_saturation_nodal_dvar)[_i][ph][pvar] *
159 _mass_frac[_i][ph][_fluid_component] * _porosity[_i];
160 dmass += _fluid_density[_i][ph] * _fluid_saturation_nodal[_i][ph] *
161 (*_dmass_frac_dvar)[_i][ph][_fluid_component][pvar] * _porosity[_i];
162 dmass += _fluid_density[_i][ph] * _fluid_saturation_nodal[_i][ph] *
163 _mass_frac[_i][ph][_fluid_component] * (*_dporosity_dvar)[_i][pvar];
165 return _test[_i][_qp] * _decay_rate * dmass;
Moose::GenericType< Real, is_ad > GenericReal
const unsigned int _fluid_component
The fluid component index.
void paramError(const std::string ¶m, Args... args) const
static InputParameters validParams()
virtual Real computeQpOffDiagJacobian(unsigned int jvar) override
registerMooseObject("PorousFlowApp", PorousFlowMassRadioactiveDecay)
unsigned int numComponents() const
The number of fluid components.
virtual GenericReal< is_ad > computeQpResidual() override
const PorousFlowDictator & _dictator
PorousFlowDictator UserObject.
void libmesh_ignore(const Args &...)
Real computeQpJac(unsigned int pvar)
Derivative of residual wrt PorousFlow variable pvar (non-AD path only)
static InputParameters validParams()
virtual Real computeQpJacobian() override
PorousFlowMassRadioactiveDecayTempl(const InputParameters ¶meters)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
This holds maps between the nonlinear variables used in a PorousFlow simulation and the variable numb...
Base class for PorousFlow kernels that use mass-lumped (nodal) material properties.
Kernel = _decay_rate * masscomponent where mass_component = porosity*sum_phases(density_phase*saturat...
void ErrorVector unsigned int