https://mooseframework.inl.gov
LinearWCNSFVMomentumFlux.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 "MooseLinearVariableFV.h"
12 #include "NSFVUtils.h"
13 #include "NS.h"
14 #include "RhieChowMassFlux.h"
17 
19 
22 {
24  params.addClassDescription("Represents the matrix and right hand side contributions of the "
25  "stress and advection terms of the momentum equation.");
26  params.addRequiredParam<SolverVariableName>("u", "The velocity in the x direction.");
27  params.addParam<SolverVariableName>("v", "The velocity in the y direction.");
28  params.addParam<SolverVariableName>("w", "The velocity in the z direction.");
29  params.addRequiredParam<UserObjectName>(
30  "rhie_chow_user_object",
31  "The rhie-chow user-object which is used to determine the face velocity.");
32  params.addRequiredParam<MooseFunctorName>(NS::mu, "The diffusion coefficient.");
33  MooseEnum momentum_component("x=0 y=1 z=2");
35  "momentum_component",
36  momentum_component,
37  "The component of the momentum equation that this kernel applies to.");
38  params.addParam<bool>(
39  "use_nonorthogonal_correction",
40  true,
41  "If the nonorthogonal correction should be used when computing the normal gradient.");
42  params.addParam<bool>(
43  "use_deviatoric_terms", false, "If deviatoric terms in the stress terms need to be used.");
44 
46  return params;
47 }
48 
50  : LinearFVFluxKernel(params),
51  _dim(_subproblem.mesh().dimension()),
52  _mass_flux_provider(getUserObject<RhieChowMassFlux>("rhie_chow_user_object")),
53  _mu(getFunctor<Real>(getParam<MooseFunctorName>(NS::mu))),
54  _use_nonorthogonal_correction(getParam<bool>("use_nonorthogonal_correction")),
55  _use_deviatoric_terms(getParam<bool>("use_deviatoric_terms")),
56  _advected_interp_coeffs(std::make_pair<Real, Real>(0, 0)),
57  _face_mass_flux(0.0),
58  _boundary_normal_factor(1.0),
59  _stress_matrix_contribution(0.0),
60  _stress_rhs_contribution(0.0),
61  _index(getParam<MooseEnum>("momentum_component")),
62  _u_var(dynamic_cast<const MooseLinearVariableFVReal *>(
63  &_fe_problem.getVariable(_tid, getParam<SolverVariableName>("u")))),
64  _v_var(params.isParamValid("v")
65  ? dynamic_cast<const MooseLinearVariableFVReal *>(
66  &_fe_problem.getVariable(_tid, getParam<SolverVariableName>("v")))
67  : nullptr),
68  _w_var(params.isParamValid("w")
69  ? dynamic_cast<const MooseLinearVariableFVReal *>(
70  &_fe_problem.getVariable(_tid, getParam<SolverVariableName>("w")))
71  : nullptr)
72 {
73  // We only need gradients if the nonorthogonal correction is enabled or when we request the
74  // computation of the deviatoric parts of the stress tensor.
77 
78  Moose::FV::setInterpolationMethod(*this, _advected_interp_method, "advected_interp_method");
79 
80  if (!_u_var)
81  paramError("u", "the u velocity must be a MooseLinearVariableFVReal.");
82 
83  if (_dim >= 2 && !_v_var)
84  paramError("v",
85  "In two or more dimensions, the v velocity must be supplied and it must be a "
86  "MooseLinearVariableFVReal.");
87 
88  if (_dim >= 3 && !_w_var)
89  paramError("w",
90  "In three-dimensions, the w velocity must be supplied and it must be a "
91  "MooseLinearVariableFVReal.");
92 }
93 
94 Real
96 {
100 }
101 
102 Real
104 {
108 }
109 
110 Real
112 {
114 }
115 
116 Real
118 {
120 }
121 
122 Real
124 {
125  const auto * const adv_diff_bc = static_cast<const LinearFVAdvectionDiffusionBC *>(&bc);
126  mooseAssert(adv_diff_bc, "This should be a valid BC!");
127  return (computeStressBoundaryMatrixContribution(adv_diff_bc) +
130 }
131 
132 Real
134 {
135  const auto * const adv_diff_bc = static_cast<const LinearFVAdvectionDiffusionBC *>(&bc);
136 
137  mooseAssert(adv_diff_bc, "This should be a valid BC!");
138  return (computeStressBoundaryRHSContribution(adv_diff_bc) +
141 }
142 
143 Real
145 {
147 }
148 
149 Real
151 {
153 }
154 
155 Real
157 {
158  // If we don't have the value yet, we compute it
160  {
161  const auto face_arg = makeCDFace(*_current_face_info);
162 
163  // If we requested nonorthogonal correction, we use the normal component of the
164  // cell to face vector.
165  const auto d = _use_nonorthogonal_correction
166  ? std::abs(_current_face_info->dCN() * _current_face_info->normal())
168 
169  // Cache the matrix contribution
172  }
173 
175 }
176 
177 Real
179 {
180  // We can have contributions to the right hand side in two occasions:
181  // (1) when we use nonorthogonal correction for the normal gradients
182  // (2) when we request the deviatoric parts of the stress tensor. (needed for space-dependent
183  // viscosities for example)
185  {
186  // scenario (1), we need to add the nonorthogonal correction. In 1D, we don't have
187  // any correction so we just skip this part
189  {
190  const auto face_arg = makeCDFace(*_current_face_info);
191  const auto state_arg = determineState();
192 
193  // Get the gradients from the adjacent cells
194  const auto grad_elem = _var.gradSln(*_current_face_info->elemInfo());
195  const auto & grad_neighbor = _var.gradSln(*_current_face_info->neighborInfo());
196 
197  // Interpolate the two gradients to the face
198  const auto interp_coeffs =
200 
201  const auto correction_vector =
205 
206  // Cache the matrix contribution
208  _mu(face_arg, state_arg) *
209  (interp_coeffs.first * grad_elem + interp_coeffs.second * grad_neighbor) *
210  correction_vector;
211  }
212  // scenario (2), we will have to account for the deviatoric parts of the stress tensor.
214  {
215  // Interpolate the two gradients to the face
216  const auto interp_coeffs =
218 
219  const auto u_grad_elem = _u_var->gradSln(*_current_face_info->elemInfo());
220  const auto u_grad_neighbor = _u_var->gradSln(*_current_face_info->neighborInfo());
221 
222  Real trace_elem = 0;
223  Real trace_neighbor = 0;
224  RealVectorValue deviatoric_vector_elem;
225  RealVectorValue deviatoric_vector_neighbor;
226 
227  deviatoric_vector_elem(0) = u_grad_elem(_index);
228  deviatoric_vector_neighbor(0) = u_grad_neighbor(_index);
229  trace_elem += u_grad_elem(0);
230  trace_neighbor += u_grad_neighbor(0);
231 
232  const auto face_arg = makeCDFace(*_current_face_info);
233  const auto state_arg = determineState();
234 
235  if (_dim > 1)
236  {
237  const auto v_grad_elem = _v_var->gradSln(*_current_face_info->elemInfo());
238  const auto v_grad_neighbor = _v_var->gradSln(*_current_face_info->neighborInfo());
239 
240  deviatoric_vector_elem(1) = v_grad_elem(_index);
241  deviatoric_vector_neighbor(1) = v_grad_neighbor(_index);
242  trace_elem += v_grad_elem(1);
243  trace_neighbor += v_grad_neighbor(1);
244  if (_dim > 2)
245  {
246  const auto w_grad_elem = _w_var->gradSln(*_current_face_info->elemInfo());
247  const auto w_grad_neighbor = _w_var->gradSln(*_current_face_info->neighborInfo());
248 
249  deviatoric_vector_elem(2) = w_grad_elem(_index);
250  deviatoric_vector_neighbor(2) = w_grad_neighbor(_index);
251  trace_elem += w_grad_elem(2);
252  trace_neighbor += w_grad_neighbor(2);
253  }
254  }
255  deviatoric_vector_elem(_index) -= 2 / 3 * trace_elem;
256  deviatoric_vector_neighbor(_index) -= 2 / 3 * trace_neighbor;
257 
258  _stress_rhs_contribution += _mu(face_arg, state_arg) *
259  (interp_coeffs.first * deviatoric_vector_elem +
260  interp_coeffs.second * deviatoric_vector_neighbor) *
262  }
264  }
265 
267 }
268 
269 Real
271  const LinearFVAdvectionDiffusionBC * bc)
272 {
273  auto grad_contrib = bc->computeBoundaryGradientMatrixContribution();
274  // If the boundary condition does not include the diffusivity contribution then
275  // add it here.
277  {
278  const auto face_arg = singleSidedFaceArg(_current_face_info);
279  grad_contrib *= _mu(face_arg, determineState());
280  }
281 
282  return grad_contrib;
283 }
284 
285 Real
287  const LinearFVAdvectionDiffusionBC * bc)
288 {
289  const auto face_arg = singleSidedFaceArg(_current_face_info);
290  auto grad_contrib = bc->computeBoundaryGradientRHSContribution();
291 
292  // If the boundary condition does not include the diffusivity contribution then
293  // add it here.
295  grad_contrib *= _mu(face_arg, determineState());
296 
297  // We add the nonorthogonal corrector for the face here. Potential idea: we could do
298  // this in the boundary condition too. For now, however, we keep it like this.
300  {
301  // We support internal boundaries as well. In that case we have to decide on which side
302  // of the boundary we are on.
303  const auto elem_info = (_current_face_type == FaceInfo::VarFaceNeighbors::ELEM)
306 
307  // Unit vector to the boundary. Unfortunately, we have to recompute it because the value
308  // stored in the face info is only correct for external boundaries
309  const auto e_Cf = _current_face_info->faceCentroid() - elem_info->centroid();
310  const auto correction_vector =
311  _current_face_info->normal() - 1 / (_current_face_info->normal() * e_Cf) * e_Cf;
312 
313  grad_contrib += _mu(face_arg, determineState()) * _var.gradSln(*elem_info) *
314  _boundary_normal_factor * correction_vector;
315  }
316 
318  {
319  // We might be on a face which is an internal boundary so we want to make sure we
320  // get the gradient from the right side.
321  const auto elem_info = (_current_face_type == FaceInfo::VarFaceNeighbors::ELEM)
324 
325  const auto u_grad_elem = _u_var->gradSln(*elem_info);
326 
327  Real trace_elem = 0;
328  RealVectorValue frace_grad_approx;
329 
330  trace_elem += u_grad_elem(0);
331  frace_grad_approx(0) = u_grad_elem(_index);
332 
333  const auto state_arg = determineState();
334 
335  if (_dim > 1)
336  {
337  const auto v_grad_elem = _v_var->gradSln(*elem_info);
338  trace_elem += v_grad_elem(1);
339  frace_grad_approx(1) = v_grad_elem(_index);
340 
341  if (_dim > 2)
342  {
343  const auto w_grad_elem = _w_var->gradSln(*elem_info);
344  trace_elem += w_grad_elem(2);
345  frace_grad_approx(2) = w_grad_elem(_index);
346  }
347  }
348 
349  frace_grad_approx(_index) -= 2 / 3 * trace_elem;
350 
351  // We support internal boundaries too so we have to make sure the normal points always outward
352  grad_contrib += _mu(face_arg, state_arg) * frace_grad_approx * _boundary_normal_factor *
354  }
355 
356  return grad_contrib;
357 }
358 
359 Real
361  const LinearFVAdvectionDiffusionBC * bc)
362 {
363  const auto boundary_value_matrix_contrib = bc->computeBoundaryValueMatrixContribution();
364  return boundary_value_matrix_contrib * _face_mass_flux;
365 }
366 
367 Real
369  const LinearFVAdvectionDiffusionBC * bc)
370 {
371  const auto boundary_value_rhs_contrib = bc->computeBoundaryValueRHSContribution();
372  return -boundary_value_rhs_contrib * _face_mass_flux;
373 }
374 
375 void
377 {
379 
380  // Multiplier that ensures the normal of the boundary always points outwards, even in cases
381  // when the boundary is within the mesh.
383 
384  // Caching the mass flux on the face which will be reused in the advection term's matrix and
385  // right hand side contributions
387 
388  // Caching the interpolation coefficients so they will be reused for the matrix and right hand
389  // side terms
392 
393  // We'll have to set this to zero to make sure that we don't accumulate values over multiple
394  // faces. The matrix contribution should be fine.
396 }
virtual Real computeBoundaryMatrixContribution(const LinearFVBoundaryCondition &bc) override
Real computeInternalAdvectionNeighborMatrixContribution()
Computes the matrix contribution of the advective flux on the neighbor side of current face when the ...
const unsigned int _index
Index x|y|z, this is mainly to handle the deviatoric parts correctly in in the stress term...
User object responsible for determining the face fluxes using the Rhie-Chow interpolation in a segreg...
const MooseLinearVariableFVReal *const _w_var
Velocity in direction z.
virtual Real computeBoundaryGradientRHSContribution() const=0
void paramError(const std::string &param, Args... args) const
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
Real computeInternalAdvectionElemMatrixContribution()
Computes the matrix contribution of the advective flux on the element side of current face when the f...
virtual Real computeNeighborRightHandSideContribution() override
std::pair< Real, Real > interpCoeffs(const InterpMethod m, const FaceInfo &fi, const bool one_is_elem, const T &face_flux=0.0)
Real getMassFlux(const FaceInfo &fi) const
Get the face velocity times density (used in advection terms)
Real computeStressBoundaryRHSContribution(const LinearFVAdvectionDiffusionBC *bc)
Computes the right hand side contributions of the boundary conditions resulting from the stress tenso...
Moose::FaceArg singleSidedFaceArg(const FaceInfo *fi, Moose::FV::LimiterType limiter_type=Moose::FV::LimiterType::CentralDifference, bool correct_skewness=false) const
Moose::StateArg determineState() const
const ElemInfo * neighborInfo() const
const Point & faceCentroid() const
Real computeInternalStressMatrixContribution()
Computes the matrix contribution of the stress term on the current face when the face is an internal ...
MooseLinearVariableFV< Real > & _var
MeshBase & mesh
virtual void setupFaceData(const FaceInfo *face_info)
virtual Real computeBoundaryGradientMatrixContribution() const=0
const bool _use_nonorthogonal_correction
Switch to enable/disable nonorthogonal correction in the stress term.
const ElemInfo * elemInfo() const
const RhieChowMassFlux & _mass_flux_provider
The Rhie-Chow user object that provides us with the face velocity.
registerMooseObject("NavierStokesApp", LinearWCNSFVMomentumFlux)
FaceInfo::VarFaceNeighbors _current_face_type
void addRequiredParam(const std::string &name, const std::string &doc_string)
Real _boundary_normal_factor
Multiplier that ensures the normal of the boundary always points outwards, even in cases when the bou...
const Moose::Functor< Real > & _mu
The functor for the dynamic viscosity.
static InputParameters validParams()
static InputParameters validParams()
const FaceInfo * _current_face_info
InputParameters advectedInterpolationParameter()
virtual void setupFaceData(const FaceInfo *face_info) override
Set the current FaceInfo object.
Real computeAdvectionBoundaryMatrixContribution(const LinearFVAdvectionDiffusionBC *bc)
Computes the matrix contributions of the boundary conditions resulting from the advection term...
static const std::string mu
Definition: NS.h:123
Kernel that implements the stress tensor and advection terms for the momentum equation.
std::pair< Real, Real > _advected_interp_coeffs
Container for the current advected interpolation coefficients on the face to make sure we don&#39;t compu...
Real computeAdvectionBoundaryRHSContribution(const LinearFVAdvectionDiffusionBC *bc)
Computes the right hand side contributions of the boundary conditions resulting from the advection te...
Real _stress_rhs_contribution
The cached right hand side contribution.
const Point & normal() const
virtual Real computeElemRightHandSideContribution() override
virtual bool includesMaterialPropertyMultiplier() const
const unsigned int _dim
The dimension of the mesh.
Real dCNMag() const
Real _stress_matrix_contribution
The cached matrix contribution.
Real computeStressBoundaryMatrixContribution(const LinearFVAdvectionDiffusionBC *bc)
Computes the matrix contributions of the boundary conditions resulting from the stress tensor...
virtual Real computeBoundaryValueMatrixContribution() const=0
virtual Real computeNeighborMatrixContribution() override
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const Point & eCN() const
Real _face_mass_flux
Container for the mass flux on the face which will be reused in the advection term&#39;s matrix and right...
const MooseLinearVariableFVReal *const _v_var
Velocity in direction y.
virtual Real computeElemMatrixContribution() override
const VectorValue< Real > gradSln(const ElemInfo &elem_info) const
virtual Real computeBoundaryValueRHSContribution() const=0
Moose::FV::InterpMethod _advected_interp_method
The interpolation method to use for the advected quantity.
void addClassDescription(const std::string &doc_string)
bool _cached_matrix_contribution
LinearWCNSFVMomentumFlux(const InputParameters &params)
Class constructor.
Moose::FaceArg makeCDFace(const FaceInfo &fi, const bool correct_skewness=false) const
Real computeInternalStressRHSContribution()
Computes the right hand side contribution of the stress term on the current face when the face is an ...
bool setInterpolationMethod(const MooseObject &obj, Moose::FV::InterpMethod &interp_method, const std::string &param_name)
const Point & dCN() const
const bool _use_deviatoric_terms
Switch to enable/disable deviatoric parts in the stress term.
const MooseLinearVariableFVReal *const _u_var
Velocity in direction x.
virtual Real computeBoundaryRHSContribution(const LinearFVBoundaryCondition &bc) override