Line data Source code
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 :
16 : registerMooseObject("NavierStokesApp", PINSFVMomentumFriction);
17 :
18 : InputParameters
19 4551 : PINSFVMomentumFriction::validParams()
20 : {
21 4551 : InputParameters params = INSFVElementalKernel::validParams();
22 4551 : 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 9102 : params.addParam<MooseFunctorName>("Darcy_name", "Name of the Darcy coefficients property.");
26 9102 : params.addParam<MooseFunctorName>("Forchheimer_name",
27 : "Name of the Forchheimer coefficients property.");
28 9102 : params.addParam<bool>("is_porous_medium", true, "Boolean to choose the type of medium.");
29 9102 : params.addParam<bool>(
30 9102 : "standard_friction_formulation", true, "Boolean to choose the type of friction formulation.");
31 4551 : params.addParam<MooseFunctorName>(NS::mu, "The dynamic viscosity");
32 4551 : params.addParam<MooseFunctorName>(NS::speed, "The magnitude of the interstitial velocity.");
33 9102 : params.addParam<MooseFunctorName>("u",
34 : "The velocity in the x direction. Superficial in the case of "
35 : "porous treatment, interstitial otherwise");
36 9102 : params.addParam<MooseFunctorName>("v",
37 : "The velocity in the y direction. Superficial in the case of "
38 : "porous treatment, interstitial otherwise");
39 9102 : params.addParam<MooseFunctorName>("w",
40 : "The velocity in the z direction. Superficial in the case of "
41 : "porous treatment, interstitial otherwise");
42 4551 : params.addParam<MooseFunctorName>(NS::porosity, 1.0, "The porosity");
43 4551 : params.addRequiredParam<MooseFunctorName>(NS::density, "The density.");
44 4551 : return params;
45 0 : }
46 :
47 2776 : PINSFVMomentumFriction::PINSFVMomentumFriction(const InputParameters & params)
48 : : INSFVElementalKernel(params),
49 7708 : _D(isParamValid("Darcy_name") ? &getFunctor<ADRealVectorValue>("Darcy_name") : nullptr),
50 10080 : _F(isParamValid("Forchheimer_name") ? &getFunctor<ADRealVectorValue>("Forchheimer_name")
51 : : nullptr),
52 5552 : _use_Darcy_friction_model(isParamValid("Darcy_name")),
53 5552 : _use_Forchheimer_friction_model(isParamValid("Forchheimer_name")),
54 5552 : _is_porous_medium(getParam<bool>("is_porous_medium")),
55 5552 : _standard_friction_formulation(getParam<bool>("standard_friction_formulation")),
56 2776 : _mu(isParamValid(NS::mu) ? &getFunctor<ADReal>(NS::mu) : nullptr),
57 2776 : _rho(getFunctor<ADReal>(NS::density)),
58 2776 : _speed(isParamValid(NS::speed) ? &getFunctor<ADReal>(NS::speed) : nullptr),
59 2776 : _dim(_subproblem.mesh().dimension()),
60 2944 : _u_var(params.isParamValid("u") ? &(getFunctor<ADReal>("u")) : nullptr),
61 2944 : _v_var(params.isParamValid("v") ? &(getFunctor<ADReal>("v")) : nullptr),
62 2776 : _w_var(params.isParamValid("w") ? &(getFunctor<ADReal>("w")) : nullptr),
63 2776 : _epsilon(getFunctor<ADReal>(NS::porosity))
64 : {
65 2776 : if (!_use_Darcy_friction_model && !_use_Forchheimer_friction_model)
66 0 : mooseError("At least one friction model needs to be specified.");
67 :
68 2776 : if (_standard_friction_formulation && _use_Darcy_friction_model && !_mu)
69 0 : mooseError("If using the standard Darcy friction model, then the '",
70 : NS::mu,
71 : "' parameter must be provided");
72 2776 : if (_use_Forchheimer_friction_model && !_speed)
73 : {
74 84 : if (_dim >= 1)
75 : {
76 84 : if (!_u_var)
77 0 : 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 84 : if (_dim >= 2)
81 : {
82 84 : if (!_v_var)
83 0 : 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 84 : if (_dim >= 3)
88 : {
89 0 : if (!_w_var)
90 0 : 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 2776 : }
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
119 9111052 : PINSFVMomentumFriction::computeFrictionWCoefficient(const Moose::ElemArg & elem_arg,
120 : const Moose::StateArg & state)
121 : {
122 : // Forward declaration of the coeffcients to be used and returned by the model
123 9111052 : ADReal coefficient = 0.0;
124 9111052 : ADReal speed = 0.0;
125 9111052 : ADReal rho = 0.0;
126 9111052 : ADReal mu = 0.0;
127 : /// Speed treatment
128 9111052 : if (_use_Forchheimer_friction_model && _speed)
129 7856706 : speed = (*_speed)(elem_arg, state);
130 1254346 : else if (_use_Forchheimer_friction_model && !_speed)
131 : {
132 : ADRealVectorValue superficial_velocity;
133 808500 : if (_dim >= 1)
134 : {
135 808500 : superficial_velocity(0) = (*_u_var)(elem_arg, state);
136 808500 : if (_dim >= 2)
137 : {
138 808500 : superficial_velocity(1) = (*_v_var)(elem_arg, state);
139 808500 : if (_dim >= 3)
140 0 : superficial_velocity(2) = (*_w_var)(elem_arg, state);
141 : }
142 : }
143 808500 : speed = NS::computeSpeed<ADReal>(superficial_velocity);
144 808500 : if (_is_porous_medium)
145 : {
146 1617000 : speed *= (1 / _epsilon(elem_arg, state));
147 : }
148 : }
149 :
150 : /// Fluid properies
151 9111052 : if (_use_Darcy_friction_model && _standard_friction_formulation)
152 : {
153 7476546 : mu = (*_mu)(elem_arg, state);
154 : }
155 :
156 9111052 : if (_use_Forchheimer_friction_model && _standard_friction_formulation)
157 : {
158 7488226 : rho = _rho(elem_arg, state);
159 : }
160 :
161 : ////////////////////////////////////////////////////////////////////
162 : ///// Switching across formulation cases
163 : ////////////////////////////////////////////////////////////////////
164 9111052 : if (_standard_friction_formulation)
165 : {
166 7645386 : if (_use_Darcy_friction_model)
167 14953092 : coefficient += mu * (*_D)(elem_arg, state)(_index);
168 7645386 : if (_use_Forchheimer_friction_model)
169 14976452 : coefficient += rho / 2 * (*_F)(elem_arg, state)(_index)*speed;
170 : }
171 : else
172 : {
173 1465666 : if (_use_Darcy_friction_model)
174 1097186 : coefficient += (*_D)(elem_arg, state)(_index);
175 1465666 : if (_use_Forchheimer_friction_model)
176 2353960 : coefficient += (*_F)(elem_arg, state)(_index)*speed;
177 : }
178 :
179 9111052 : return coefficient;
180 : }
181 :
182 : ADReal
183 1620000 : PINSFVMomentumFriction::computeSegregatedContribution()
184 : {
185 1620000 : const auto & elem_arg = makeElemArg(_current_elem);
186 1620000 : const auto state = determineState();
187 1620000 : return raw_value(computeFrictionWCoefficient(elem_arg, state)) * _u_functor(elem_arg, state);
188 : }
189 :
190 : void
191 7491052 : PINSFVMomentumFriction::gatherRCData(const Elem & elem)
192 : {
193 7491052 : const auto elem_arg = makeElemArg(&elem);
194 7491052 : const auto state = determineState();
195 : const auto coefficient =
196 7491052 : computeFrictionWCoefficient(elem_arg, state) * _assembly.elementVolume(&elem);
197 7491052 : _rc_uo.addToA(&elem, _index, coefficient);
198 7491052 : const auto dof_number = elem.dof_number(_sys.number(), _var.number(), 0);
199 14982104 : addResidualAndJacobian(coefficient * _u_functor(elem_arg, state), dof_number);
200 7491052 : }
|