23 "fluid_component", 0,
"The index corresponding to the fluid component for this kernel");
25 "PorousFlowDictator",
"The UserObject that holds the list of PorousFlow variable names");
27 "disp_long",
"Vector of longitudinal dispersion coefficients for each phase");
29 "disp_trans",
"Vector of transverse dispersion coefficients for each phase");
31 "Gravitational acceleration vector downwards (m/s^2)");
33 "Dispersive and diffusive flux of the component given by fluid_component in all phases");
41 _fluid_density_qp(this->template getGenericMaterialProperty<
std::vector<
Real>, is_ad>(
42 "PorousFlow_fluid_phase_density_qp")),
43 _dfluid_density_qp_dvar(
45 : &this->template getMaterialProperty<
std::vector<
std::vector<
Real>>>(
46 "dPorousFlow_fluid_phase_density_qp_dvar")),
48 this->template getGenericMaterialProperty<
std::vector<
std::vector<
RealGradient>>, is_ad>(
49 "PorousFlow_grad_mass_frac_qp")),
52 : &this->template getMaterialProperty<
std::vector<
std::vector<
std::vector<
Real>>>>(
53 "dPorousFlow_mass_frac_qp_dvar")),
54 _porosity_qp(this->template getGenericMaterialProperty<
Real, is_ad>(
"PorousFlow_porosity_qp")),
55 _dporosity_qp_dvar(is_ad ? nullptr
56 : &this->template getMaterialProperty<
std::vector<
Real>>(
57 "dPorousFlow_porosity_qp_dvar")),
58 _tortuosity(this->template getGenericMaterialProperty<
std::vector<
Real>, is_ad>(
59 "PorousFlow_tortuosity_qp")),
60 _dtortuosity_dvar(is_ad ? nullptr
61 : &this->template getMaterialProperty<
std::vector<
std::vector<
Real>>>(
62 "dPorousFlow_tortuosity_qp_dvar")),
63 _diffusion_coeff(this->template getMaterialProperty<
std::vector<
std::vector<
Real>>>(
64 "PorousFlow_diffusion_coeff_qp")),
65 _ddiffusion_coeff_dvar(
67 : &this->template getMaterialProperty<
std::vector<
std::vector<
std::vector<
Real>>>>(
68 "dPorousFlow_diffusion_coeff_qp_dvar")),
70 _fluid_component(this->template getParam<unsigned
int>(
"fluid_component")),
71 _num_phases(_dictator.numPhases()),
73 _relative_permeability(this->template getGenericMaterialProperty<
std::vector<
Real>, is_ad>(
74 "PorousFlow_relative_permeability_qp")),
75 _drelative_permeability_dvar(
77 : &this->template getMaterialProperty<
std::vector<
std::vector<
Real>>>(
78 "dPorousFlow_relative_permeability_qp_dvar")),
79 _fluid_viscosity(this->template getGenericMaterialProperty<
std::vector<
Real>, is_ad>(
80 "PorousFlow_viscosity_qp")),
81 _dfluid_viscosity_dvar(
83 : &this->template getMaterialProperty<
std::vector<
std::vector<
Real>>>(
84 "dPorousFlow_viscosity_qp_dvar")),
85 _permeability(this->template getGenericMaterialProperty<
RealTensorValue, is_ad>(
86 "PorousFlow_permeability_qp")),
87 _dpermeability_dvar(is_ad ? nullptr
89 "dPorousFlow_permeability_qp_dvar")),
90 _dpermeability_dgradvar(
93 "dPorousFlow_permeability_qp_dgradvar")),
94 _grad_p(this->template getGenericMaterialProperty<
std::vector<
RealGradient>, is_ad>(
95 "PorousFlow_grad_porepressure_qp")),
96 _dgrad_p_dgrad_var(is_ad ? nullptr
97 : &this->template getMaterialProperty<
std::vector<
std::vector<
Real>>>(
98 "dPorousFlow_grad_porepressure_qp_dgradvar")),
102 "dPorousFlow_grad_porepressure_qp_dvar")),
104 _disp_long(this->template getParam<
std::vector<
Real>>(
"disp_long")),
105 _disp_trans(this->template getParam<
std::vector<
Real>>(
"disp_trans")),
106 _perm_derivs(_dictator.usePermDerivs())
111 "The Dictator proclaims that the maximum fluid component index in this simulation is ",
113 " whereas you have used ",
115 ". Remember that indexing starts at 0. The Dictator does not take such mistakes lightly.");
120 "The number of longitudinal dispersion coefficients is not equal to the number of phases");
124 "The number of transverse dispersion coefficients disp_trans is not equal to " 125 "the number of phases");
128 template <
bool is_ad>
140 for (
unsigned int ph = 0; ph < _num_phases; ++ph)
143 _porosity_qp[_qp] * _tortuosity[_qp][ph] * _diffusion_coeff[_qp][ph][_fluid_component];
145 velocity = _permeability[_qp] * (_grad_p[_qp][ph] - _fluid_density_qp[_qp][ph] * _gravity) *
146 _relative_permeability[_qp][ph] / _fluid_viscosity[_qp][ph];
153 dispersion =
GenericReal<is_ad>(_disp_long[ph] - _disp_trans[ph]) * v2 / velocity_abs;
156 flux += _fluid_density_qp[_qp][ph] * (diffusion * _identity_tensor + dispersion) *
157 _grad_mass_frac[_qp][ph][_fluid_component];
159 return _grad_test[_i][_qp] * flux;
162 template <
bool is_ad>
166 return computeQpJac(_var.number());
169 template <
bool is_ad>
173 return computeQpJac(jvar);
176 template <
bool is_ad>
180 if constexpr (!is_ad)
182 if (_dictator.notPorousFlowVariable(jvar))
185 const unsigned int pvar = _dictator.porousFlowVariableNum(jvar);
195 for (
unsigned int ph = 0; ph < _num_phases; ++ph)
198 _porosity_qp[_qp] * _tortuosity[_qp][ph] * _diffusion_coeff[_qp][ph][_fluid_component];
200 velocity = _permeability[_qp] * (_grad_p[_qp][ph] - _fluid_density_qp[_qp][ph] * _gravity) *
201 _relative_permeability[_qp][ph] / _fluid_viscosity[_qp][ph];
204 if (velocity_abs > 0.0)
207 diffusion += _disp_trans[ph] * velocity_abs;
208 dispersion = (_disp_long[ph] - _disp_trans[ph]) * v2 / velocity_abs;
213 (_grad_phi[_j][_qp] * (*_dgrad_p_dgrad_var)[_qp][ph][pvar] -
214 _phi[_j][_qp] * (*_dfluid_density_qp_dvar)[_qp][ph][pvar] * _gravity);
215 dvelocity += _permeability[_qp] * ((*_dgrad_p_dvar)[_qp][ph][pvar] * _phi[_j][_qp]);
219 dvelocity += (*_dpermeability_dvar)[_qp][pvar] * _phi[_j][_qp] *
220 (_grad_p[_qp][ph] - _fluid_density_qp[_qp][ph] * _gravity);
223 dvelocity += (*_dpermeability_dgradvar)[_qp][i][pvar] * _grad_phi[_j][_qp](i) *
224 (_grad_p[_qp][ph] - _fluid_density_qp[_qp][ph] * _gravity);
228 dvelocity * _relative_permeability[_qp][ph] / _fluid_viscosity[_qp][ph] +
229 (_permeability[_qp] * (_grad_p[_qp][ph] - _fluid_density_qp[_qp][ph] * _gravity)) *
230 ((*_drelative_permeability_dvar)[_qp][ph][pvar] / _fluid_viscosity[_qp][ph] -
231 _relative_permeability[_qp][ph] * (*_dfluid_viscosity_dvar)[_qp][ph][pvar] /
232 std::pow(_fluid_viscosity[_qp][ph], 2)) *
235 Real dvelocity_abs = 0.0;
236 if (velocity_abs > 0.0)
237 dvelocity_abs =
velocity * dvelocity / velocity_abs;
239 Real ddiffusion = _phi[_j][_qp] * (*_dporosity_qp_dvar)[_qp][pvar] * _tortuosity[_qp][ph] *
240 _diffusion_coeff[_qp][ph][_fluid_component];
241 ddiffusion += _phi[_j][_qp] * _porosity_qp[_qp] * (*_dtortuosity_dvar)[_qp][ph][pvar] *
242 _diffusion_coeff[_qp][ph][_fluid_component];
243 ddiffusion += _phi[_j][_qp] * _porosity_qp[_qp] * _tortuosity[_qp][ph] *
244 (*_ddiffusion_coeff_dvar)[_qp][ph][_fluid_component][pvar];
245 ddiffusion += _disp_trans[ph] * dvelocity_abs;
249 if (velocity_abs > 0.0)
254 ddispersion = (_disp_long[ph] - _disp_trans[ph]) * (dv2a + dv2b) / velocity_abs;
256 (_disp_long[ph] - _disp_trans[ph]) * v2 * dvelocity_abs / velocity_abs / velocity_abs;
259 dflux += _phi[_j][_qp] * (*_dfluid_density_qp_dvar)[_qp][ph][pvar] *
260 (diffusion * _identity_tensor + dispersion) *
261 _grad_mass_frac[_qp][ph][_fluid_component];
262 dflux += _fluid_density_qp[_qp][ph] * (ddiffusion * _identity_tensor + ddispersion) *
263 _grad_mass_frac[_qp][ph][_fluid_component];
268 dflux += _fluid_density_qp[_qp][ph] * (diffusion * _identity_tensor + dispersion) *
269 (*_dmass_frac_dvar)[_qp][ph][_fluid_component][pvar] * _grad_phi[_j][_qp];
272 return _grad_test[_i][_qp] * dflux;
RankFourTensorTempl< Real > outerProduct(const RankTwoTensorTempl< Real > &b) const
Moose::GenericType< Real, is_ad > GenericReal
registerMooseObject("PorousFlowApp", PorousFlowDispersiveFlux)
void paramError(const std::string ¶m, Args... args) const
const std::vector< Real > _disp_long
Longitudinal dispersivity for each phase.
static InputParameters validParams()
PorousFlowDispersiveFluxTempl(const InputParameters ¶meters)
unsigned int numComponents() const
The number of fluid components.
static InputParameters validParams()
static constexpr std::size_t dim
virtual GenericReal< is_ad > computeQpResidual() override
Real computeQpJac(unsigned int jvar) const
Derivative of the residual with respect to the PorousFlow variable with variable number jvar...
const PorousFlowDictator & _dictator
PorousFlowDictator UserObject.
static RankTwoTensorTempl< Real > selfOuterProduct(const libMesh::TypeVector< Real > &)
TensorValue< Real > RealTensorValue
void libmesh_ignore(const Args &...)
Moose::GenericType< RealVectorValue, is_ad > GenericRealVectorValue
virtual Real computeQpOffDiagJacobian(unsigned int jvar) override
const unsigned int _num_phases
The number of fluid phases.
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...
virtual Real computeQpJacobian() override
IntRange< T > make_range(T beg, T end)
static const std::string velocity
const std::vector< Real > _disp_trans
Transverse dispersivity for each phase.
Dispersive flux of component k in fluid phase alpha.
MooseUnits pow(const MooseUnits &, int)
const unsigned int _fluid_component
Index of the fluid component that this kernel acts on.
void ErrorVector unsigned int
Moose::GenericType< RankTwoTensor, is_ad > GenericRankTwoTensor