https://mooseframework.inl.gov
FVPorousFlowDispersiveFlux.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 #include "PorousFlowDictator.h"
12 #include "MooseUtils.h"
13 
15 
18 {
21  RealVectorValue g(0, 0, -9.81);
22  params.addParam<RealVectorValue>("gravity", g, "Gravity vector. Defaults to (0, 0, -9.81)");
23  params.addRequiredParam<UserObjectName>("PorousFlowDictator",
24  "The PorousFlowDictator UserObject");
25  params.addParam<unsigned int>("fluid_component", 0, "The fluid component");
26  params.addRequiredParam<std::vector<Real>>(
27  "disp_long", "Vector of longitudinal dispersion coefficients for each phase");
28  params.addRequiredParam<std::vector<Real>>(
29  "disp_trans", "Vector of transverse dispersion coefficients for each phase");
30  params.addClassDescription(
31  "Dispersive and diffusive flux of the component given by fluid_component in all phases");
32  params.set<unsigned short>("ghost_layers") = 2;
33 
34  // We add the relationship manager here, this will select the right number of
35  // ghosting layers depending on the chosen interpolation method
37  "ElementSideNeighborLayers",
40  [](const InputParameters & obj_params, InputParameters & rm_params)
41  { FVRelationshipManagerInterface::setRMParamsDiffusion(obj_params, rm_params, 3); });
42 
43  params.addClassDescription("Advective Darcy flux");
44  return params;
45 }
46 
48  : FVFluxKernel(params),
50  _dictator(getUserObject<PorousFlowDictator>("PorousFlowDictator")),
51  _num_phases(_dictator.numPhases()),
52  _fluid_component(getParam<unsigned int>("fluid_component")),
53  _density(getADMaterialProperty<std::vector<Real>>("PorousFlow_fluid_phase_density_qp")),
54  _viscosity(getADMaterialProperty<std::vector<Real>>("PorousFlow_viscosity_qp")),
55  _viscosity_neighbor(
56  getNeighborADMaterialProperty<std::vector<Real>>("PorousFlow_viscosity_qp")),
57  _relperm(getADMaterialProperty<std::vector<Real>>("PorousFlow_relative_permeability_qp")),
58  _relperm_neighbor(
59  getNeighborADMaterialProperty<std::vector<Real>>("PorousFlow_relative_permeability_qp")),
60  _mass_fractions(
61  getADMaterialProperty<std::vector<std::vector<Real>>>("PorousFlow_mass_frac_qp")),
62  _mass_fractions_neighbor(
63  getNeighborADMaterialProperty<std::vector<std::vector<Real>>>("PorousFlow_mass_frac_qp")),
64  _grad_mass_frac(getADMaterialProperty<std::vector<std::vector<RealGradient>>>(
65  "PorousFlow_grad_mass_frac_qp")),
66  _permeability(getADMaterialProperty<RealTensorValue>("PorousFlow_permeability_qp")),
67  _permeability_neighbor(
68  getNeighborADMaterialProperty<RealTensorValue>("PorousFlow_permeability_qp")),
69  _pressure(getADMaterialProperty<std::vector<Real>>("PorousFlow_porepressure_qp")),
70  _pressure_neighbor(
71  getNeighborADMaterialProperty<std::vector<Real>>("PorousFlow_porepressure_qp")),
72  _grad_p(getADMaterialProperty<std::vector<RealGradient>>("PorousFlow_grad_porepressure_qp")),
73  _porosity(getADMaterialProperty<Real>("PorousFlow_porosity_qp")),
74  _porosity_neighbor(getNeighborADMaterialProperty<Real>("PorousFlow_porosity_qp")),
75  _tortuosity(getADMaterialProperty<std::vector<Real>>("PorousFlow_tortuosity_qp")),
76  _tortuosity_neighbor(
77  getNeighborADMaterialProperty<std::vector<Real>>("PorousFlow_tortuosity_qp")),
78  _diffusion_coeff(
79  getMaterialProperty<std::vector<std::vector<Real>>>("PorousFlow_diffusion_coeff_qp")),
80  _diffusion_coeff_neighbor(getNeighborMaterialProperty<std::vector<std::vector<Real>>>(
81  "PorousFlow_diffusion_coeff_qp")),
82  _gravity(getParam<RealVectorValue>("gravity")),
83  _identity_tensor(ADRankTwoTensor::initIdentity),
84  _disp_long(getParam<std::vector<Real>>("disp_long")),
85  _disp_trans(getParam<std::vector<Real>>("disp_trans"))
86 {
88  paramError(
89  "fluid_component",
90  "The Dictator proclaims that the maximum fluid component index in this simulation is ",
92  " whereas you have used ",
94  ". Remember that indexing starts at 0. The Dictator does not take such mistakes lightly.");
95 
96  // Check that sufficient values of the dispersion coefficients have been entered
97  if (_disp_long.size() != _num_phases)
98  paramError(
99  "disp_long",
100  "The number of longitudinal dispersion coefficients is not equal to the number of phases");
101 
102  if (_disp_trans.size() != _num_phases)
103  paramError("disp_trans",
104  "The number of transverse dispersion coefficients disp_trans is not equal to the "
105  "number of phases");
106 }
107 
108 ADReal
110 {
111  ADReal flux = 0.0;
112  ADRankTwoTensor dispersion;
113  ADReal diffusion;
114 
115  for (unsigned int p = 0; p < _num_phases; ++p)
116  {
117  // Diffusive component
118  ADRealGradient gradX;
119 
120  const auto state = determineState();
121  const auto dudn = gradUDotNormal(state, _correct_skewness);
122 
123  // If we are on a boundary face, use the reconstructed gradient computed in _grad_mass_frac
124  if (onBoundary(*_face_info))
125  {
126  gradX = -1 * _grad_mass_frac[_qp][p][_fluid_component];
127  diffusion = _porosity[_qp] * _tortuosity[_qp][p] * _density[_qp][p] *
129  }
130  else
131  {
132  // If we are on an internal face, calculate the gradient explicitly
133  const auto & X_elem = _mass_fractions[_qp][p][_fluid_component];
134  const auto & X_neighbor = _mass_fractions_neighbor[_qp][p][_fluid_component];
135 
136  gradX = (X_elem - X_neighbor) * _face_info->eCN() / _face_info->dCNMag();
137 
138  const auto coeff =
140 
141  const auto coeff_neighbor = _porosity_neighbor[_qp] * _tortuosity_neighbor[_qp][p] *
143 
144  interpolate(
145  Moose::FV::InterpMethod::Average, diffusion, coeff, coeff_neighbor, *_face_info, true);
146  }
147 
148  // Dispersive component. Calculate Darcy velocity
149  ADRealGradient gradp;
150  ADRealTensorValue mobility;
151 
152  // If we are on a boundary face, use the gradient computed in _grad_p
153  if (onBoundary(*_face_info))
154  {
155  gradp = -_grad_p[_qp][p] + _density[_qp][p] * _gravity;
156  mobility = _relperm[_qp][p] * _permeability[_qp] * _density[_qp][p] / _viscosity[_qp][p];
157  }
158  else
159  {
160  // If we are on an internal face, calculate the gradient explicitly
161  const auto & p_elem = _pressure[_qp][p];
162  const auto & p_neighbor = _pressure_neighbor[_qp][p];
163 
164  gradp = (p_elem - p_neighbor) * _face_info->eCN() / _face_info->dCNMag() +
165  _density[_qp][p] * _gravity;
166 
167  const auto mobility_element = _relperm[_qp][p] * _permeability[_qp] / _viscosity[_qp][p];
168 
169  const auto mobility_neighbor =
171 
173  mobility,
174  mobility_element,
175  mobility_neighbor,
176  gradp,
177  *_face_info,
178  true);
179  }
180 
181  const auto velocity = mobility * gradp;
182  const auto velocity_abs = MetaPhysicL::raw_value(velocity).norm();
183 
184  if (!MooseUtils::isZero(velocity_abs))
185  {
187 
188  // Add longitudinal dispersion to diffusive component
189  diffusion += _disp_trans[p] * velocity_abs;
190  dispersion = (_disp_long[p] - _disp_trans[p]) * v2 / velocity_abs;
191  }
192 
193  flux += (diffusion * _identity_tensor + dispersion) * _density[_qp][p] * gradX * _normal;
194  }
195 
196  return flux;
197 }
FVPorousFlowDispersiveFlux(const InputParameters &params)
virtual ADReal gradUDotNormal(const Moose::StateArg &time, const bool correct_skewness) const
const ADMaterialProperty< std::vector< Real > > & _viscosity_neighbor
const PorousFlowDictator & _dictator
UserObject that holds information (number of phases, components, etc)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
bool isZero(const T &value, const Real tolerance=TOLERANCE *TOLERANCE *TOLERANCE)
const FaceInfo * _face_info
Moose::StateArg determineState() const
T & set(const std::string &name, bool quiet_mode=false)
const ADMaterialProperty< Real > & _porosity
Porosity.
unsigned int numComponents() const
The number of fluid components.
auto raw_value(const Eigen::Map< T > &in)
const ADMaterialProperty< std::vector< Real > > & _pressure_neighbor
const ADMaterialProperty< std::vector< RealGradient > > & _grad_p
const std::vector< Real > _disp_trans
Transverse dispersivity for each phase.
const ADMaterialProperty< std::vector< Real > > & _density
Fluid density.
void addRelationshipManager(const std::string &name, Moose::RelationshipManagerType rm_type, Moose::RelationshipManagerInputParameterCallback input_parameter_callback=nullptr)
RealVectorValue _normal
DualNumber< Real, DNDerivativeType, true > ADReal
void addRequiredParam(const std::string &name, const std::string &doc_string)
const ADMaterialProperty< std::vector< Real > > & _relperm_neighbor
static RankTwoTensorTempl< ADReal > selfOuterProduct(const libMesh::TypeVector< ADReal > &)
bool onBoundary(const FaceInfo &fi) const
TensorValue< Real > RealTensorValue
static InputParameters validParams()
const ADRankTwoTensor _identity_tensor
Dispersive flux of component k in fluid phase alpha.
const unsigned int _num_phases
Number of fluid phases present.
const unsigned int _qp
static InputParameters validParams()
const ADMaterialProperty< RealTensorValue > & _permeability
Permeability.
registerADMooseObject("PorousFlowApp", FVPorousFlowDispersiveFlux)
const ADMaterialProperty< std::vector< std::vector< Real > > > & _mass_fractions
Mass fraction of fluid components in fluid phases.
void paramError(const std::string &param, Args... args) const
const ADMaterialProperty< std::vector< Real > > & _pressure
Fluid pressure.
const ADMaterialProperty< std::vector< Real > > & _tortuosity_neighbor
Real dCNMag() const
virtual ADReal computeQpResidual() override
const ADMaterialProperty< RealTensorValue > & _permeability_neighbor
const ADMaterialProperty< Real > & _porosity_neighbor
const MaterialProperty< std::vector< std::vector< Real > > > & _diffusion_coeff
Diffusion coefficients of component k in fluid phase alpha.
const ADMaterialProperty< std::vector< Real > > & _tortuosity
Tortuosity tau_0 * tau_{alpha} for fluid phase alpha.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const ADMaterialProperty< std::vector< std::vector< Real > > > & _mass_fractions_neighbor
const Point & eCN() const
const ADMaterialProperty< std::vector< Real > > & _viscosity
Fluid viscosity.
This holds maps between the nonlinear variables used in a PorousFlow simulation and the variable numb...
static InputParameters validParams()
const MaterialProperty< std::vector< std::vector< Real > > > & _diffusion_coeff_neighbor
void addClassDescription(const std::string &doc_string)
const std::vector< Real > _disp_long
Longitudinal dispersivity for each phase.
const RealVectorValue & _gravity
Gravity vector.
static const std::string velocity
Definition: NS.h:45
const ADMaterialProperty< std::vector< std::vector< RealGradient > > > & _grad_mass_frac
static void setRMParamsDiffusion(const InputParameters &obj_params, InputParameters &rm_params, const unsigned short conditional_extended_layers)
void interpolate(InterpMethod m, T &result, const T2 &value1, const T3 &value2, const FaceInfo &fi, const bool one_is_elem)
const unsigned int _fluid_component
Index of the fluid component this kernel applies to.
const ADMaterialProperty< std::vector< Real > > & _relperm
Relative permeability.
void ErrorVector unsigned int