https://mooseframework.inl.gov
PINSFVMomentumFriction.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 
10 #include "PINSFVMomentumFriction.h"
11 #include "NS.h"
12 #include "SystemBase.h"
13 #include "MooseVariableFV.h"
14 #include "NavierStokesMethods.h"
15 
17 
20 {
22  params.addClassDescription(
23  "Computes a friction force term on fluid in porous media in the "
24  "Navier Stokes i-th momentum equation in Rhie-Chow (incompressible) contexts.");
25  params.addParam<MooseFunctorName>("Darcy_name", "Name of the Darcy coefficients property.");
26  params.addParam<MooseFunctorName>("Forchheimer_name",
27  "Name of the Forchheimer coefficients property.");
28  params.addParam<bool>("is_porous_medium", true, "Boolean to choose the type of medium.");
29  params.addParam<bool>(
30  "standard_friction_formulation", true, "Boolean to choose the type of friction formulation.");
31  params.addParam<MooseFunctorName>(NS::mu, "The dynamic viscosity");
32  params.addParam<MooseFunctorName>(NS::speed, "The magnitude of the interstitial velocity.");
33  params.addParam<MooseFunctorName>("u",
34  "The velocity in the x direction. Superficial in the case of "
35  "porous treatment, interstitial otherwise");
36  params.addParam<MooseFunctorName>("v",
37  "The velocity in the y direction. Superficial in the case of "
38  "porous treatment, interstitial otherwise");
39  params.addParam<MooseFunctorName>("w",
40  "The velocity in the z direction. Superficial in the case of "
41  "porous treatment, interstitial otherwise");
42  params.addParam<MooseFunctorName>(NS::porosity, 1.0, "The porosity");
43  params.addRequiredParam<MooseFunctorName>(NS::density, "The density.");
44  return params;
45 }
46 
48  : INSFVElementalKernel(params),
49  _D(isParamValid("Darcy_name") ? &getFunctor<ADRealVectorValue>("Darcy_name") : nullptr),
50  _F(isParamValid("Forchheimer_name") ? &getFunctor<ADRealVectorValue>("Forchheimer_name")
51  : nullptr),
52  _use_Darcy_friction_model(isParamValid("Darcy_name")),
53  _use_Forchheimer_friction_model(isParamValid("Forchheimer_name")),
54  _is_porous_medium(getParam<bool>("is_porous_medium")),
55  _standard_friction_formulation(getParam<bool>("standard_friction_formulation")),
56  _mu(isParamValid(NS::mu) ? &getFunctor<ADReal>(NS::mu) : nullptr),
57  _rho(getFunctor<ADReal>(NS::density)),
58  _speed(isParamValid(NS::speed) ? &getFunctor<ADReal>(NS::speed) : nullptr),
59  _dim(_subproblem.mesh().dimension()),
60  _u_var(params.isParamValid("u") ? &(getFunctor<ADReal>("u")) : nullptr),
61  _v_var(params.isParamValid("v") ? &(getFunctor<ADReal>("v")) : nullptr),
62  _w_var(params.isParamValid("w") ? &(getFunctor<ADReal>("w")) : nullptr),
63  _epsilon(getFunctor<ADReal>(NS::porosity))
64 {
66  mooseError("At least one friction model needs to be specified.");
67 
69  mooseError("If using the standard Darcy friction model, then the '",
70  NS::mu,
71  "' parameter must be provided");
73  {
74  if (_dim >= 1)
75  {
76  if (!_u_var)
77  mooseError("The velocity variable 'u' should be defined if no speed functor material is "
78  "defined for this kernel when using the Forchheimer fromulation.");
79  }
80  if (_dim >= 2)
81  {
82  if (!_v_var)
83  mooseError(
84  "The velocity variable 'v' should be defined if no speed functor material is "
85  "defined for this kernel and dimensions >= 2 when using the Forchheimer fromulation.");
86  }
87  if (_dim >= 3)
88  {
89  if (!_w_var)
90  mooseError(
91  "The velocity variable 'w' should be defined if no speed functor material is "
92  "defined for this kernel and dimensions >= 3 when using the Forchheimer fromulation.");
93  }
94  }
95 }
96 
97 // We are going to follow the formulations in
98 // https://holzmann-cfd.com/community/blog-and-tools/darcy-forchheimer and
99 // https://www.simscale.com/knowledge-base/predict-darcy-and-forchheimer-coefficients-for-perforated-plates-using-analytical-approach/
100 // for Darcy and Forchheimer which define:
101 //
102 // \nabla p = \mu D v + \frac{\rho}{2} F |v| v
103 //
104 // where v denotes the superficial velocity.
105 // Both monolithic and segregated solves get multiplied by v in the gatherRCData and
106 // computeSegregatedContribution methods respectively, it is the job of the
107 // computeFrictionWCoefficient method to compute, for the Darcy term:
108 //
109 // \mu D
110 //
111 // and for the Forchheimer term
112 //
113 // \frac{\rho}{2} F |v|
114 //
115 // For the non standard formulation we define :
116 // \nabla p = D v + F |v| v
117 
118 ADReal
120  const Moose::StateArg & state)
121 {
122  // Forward declaration of the coeffcients to be used and returned by the model
123  ADReal coefficient = 0.0;
124  ADReal speed = 0.0;
125  ADReal rho = 0.0;
126  ADReal mu = 0.0;
129  speed = (*_speed)(elem_arg, state);
131  {
133  if (_dim >= 1)
134  {
135  superficial_velocity(0) = (*_u_var)(elem_arg, state);
136  if (_dim >= 2)
137  {
138  superficial_velocity(1) = (*_v_var)(elem_arg, state);
139  if (_dim >= 3)
140  superficial_velocity(2) = (*_w_var)(elem_arg, state);
141  }
142  }
144  if (_is_porous_medium)
145  {
146  speed *= (1 / _epsilon(elem_arg, state));
147  }
148  }
149 
152  {
153  mu = (*_mu)(elem_arg, state);
154  }
155 
157  {
158  rho = _rho(elem_arg, state);
159  }
160 
165  {
167  coefficient += mu * (*_D)(elem_arg, state)(_index);
169  coefficient += rho / 2 * (*_F)(elem_arg, state)(_index)*speed;
170  }
171  else
172  {
174  coefficient += (*_D)(elem_arg, state)(_index);
176  coefficient += (*_F)(elem_arg, state)(_index)*speed;
177  }
178 
179  return coefficient;
180 }
181 
182 ADReal
184 {
185  const auto & elem_arg = makeElemArg(_current_elem);
186  const auto state = determineState();
187  return raw_value(computeFrictionWCoefficient(elem_arg, state)) * _u_functor(elem_arg, state);
188 }
189 
190 void
192 {
193  const auto elem_arg = makeElemArg(&elem);
194  const auto state = determineState();
195  const auto coefficient =
196  computeFrictionWCoefficient(elem_arg, state) * _assembly.elementVolume(&elem);
197  _rc_uo.addToA(&elem, _index, coefficient);
198  const auto dof_number = elem.dof_number(_sys.number(), _var.number(), 0);
199  addResidualAndJacobian(coefficient * _u_functor(elem_arg, state), dof_number);
200 }
const Moose::Functor< ADReal > * _w_var
z-velocity
ADReal computeFrictionWCoefficient(const Moose::ElemArg &elem_arg, const Moose::StateArg &state)
Computes the friction coefficient which gets multiplied by the velocity.
void addResidualAndJacobian(const ADReal &residual, dof_id_type dof)
Process into either the system residual or Jacobian.
static const std::string superficial_velocity
Definition: NS.h:53
Imposes a friction force on the momentum equation in porous media in Rhie-Chow contexts.
static const std::string speed
Definition: NS.h:143
An elemental kernel that momentum residual objects that add body forces should inherit from...
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
const Moose::Functor< ADReal > *const _speed
Speed (norm of the interstitial velocity) as a functor.
registerMooseObject("NavierStokesApp", PINSFVMomentumFriction)
unsigned int number() const
const Moose::Functor< ADReal > *const _mu
Dynamic viscosity.
Moose::StateArg determineState() const
const unsigned int _index
index x|y|z
MeshBase & mesh
static const std::string density
Definition: NS.h:33
auto raw_value(const Eigen::Map< T > &in)
DualNumber< Real, DNDerivativeType, true > ADReal
void addRequiredParam(const std::string &name, const std::string &doc_string)
RhieChowInterpolatorBase & _rc_uo
The Rhie Chow user object that is responsible for generating face velocities for advection terms...
SystemBase & _sys
Moose::ElemArg makeElemArg(const Elem *elem, bool correct_skewnewss=false) const
static const std::string porosity
Definition: NS.h:104
const unsigned int _dim
The dimension of the domain.
const Elem *const & _current_elem
Real elementVolume(const Elem *elem) const
const Moose::Functor< ADReal > & _rho
Density as a functor.
static const std::string mu
Definition: NS.h:123
const Moose::Functor< ADReal > & _epsilon
Adding porosity functor.
unsigned int number() const
static InputParameters validParams()
Assembly & _assembly
static InputParameters validParams()
virtual void addToA(const libMesh::Elem *elem, unsigned int component, const ADReal &value)=0
API for momentum residual objects that have on-diagonals for velocity call.
const Moose::Functor< ADReal > * _u_var
x-velocity
const bool _use_Darcy_friction_model
Booleans to select the right models.
const Moose::Functor< ADReal > * _v_var
y-velocity
const Moose::Functor< ADReal > & _u_functor
void mooseError(Args &&... args) const
PINSFVMomentumFriction(const InputParameters &params)
void addClassDescription(const std::string &doc_string)
void gatherRCData(const Elem &) override
Should be a non-empty implementation if the residual object is a FVElementalKernel and introduces res...
ADReal computeSpeed(const ADRealVectorValue &velocity)
Compute the speed (velocity norm) given the supplied velocity.
ADReal computeSegregatedContribution() override
Compute the contribution which goes into the residual of the segregated system.
MooseVariableFV< Real > & _var