https://mooseframework.inl.gov
LinearFVVelocitySymmetryBC.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 "FEProblemBase.h"
12 
14 
17 {
19  params.addClassDescription("Adds a symmetry boundary condition for the velocity.");
20  params.addRequiredParam<SolverVariableName>("u", "The velocity in the x direction.");
21  params.addParam<SolverVariableName>("v", "The velocity in the y direction.");
22  params.addParam<SolverVariableName>("w", "The velocity in the z direction.");
23  MooseEnum momentum_component("x=0 y=1 z=2");
25  "momentum_component",
26  momentum_component,
27  "The component of the momentum equation that this kernel applies to.");
28 
29  return params;
30 }
31 
33  : LinearFVAdvectionDiffusionBC(parameters),
34  _dim(_subproblem.mesh().dimension()),
35  _u_var(dynamic_cast<const MooseLinearVariableFVReal *>(
36  &_fv_problem.getVariable(_tid, getParam<SolverVariableName>("u")))),
37  _v_var(parameters.isParamValid("v")
38  ? dynamic_cast<const MooseLinearVariableFVReal *>(
39  &_fv_problem.getVariable(_tid, getParam<SolverVariableName>("v")))
40  : nullptr),
41  _w_var(parameters.isParamValid("w")
42  ? dynamic_cast<const MooseLinearVariableFVReal *>(
43  &_fv_problem.getVariable(_tid, getParam<SolverVariableName>("w")))
44  : nullptr),
45  _index(getParam<MooseEnum>("momentum_component"))
46 {
47  if (!_u_var)
48  paramError("u", "the u velocity must be a MooseLinearVariableFVReal.");
49 
50  _vel_vars.push_back(_u_var);
51 
52  if (_dim >= 2 && !_v_var)
53  paramError("v",
54  "In two or more dimensions, the v velocity must be supplied and it must be a "
55  "MooseLinearVariableFVReal.");
56 
57  _vel_vars.push_back(_v_var);
58 
59  if (_dim >= 3 && !_w_var)
60  paramError("w",
61  "In three-dimensions, the w velocity must be supplied and it must be a "
62  "MooseLinearVariableFVReal.");
63 
64  _vel_vars.push_back(_w_var);
65 }
66 
67 Real
69 {
70  // We allow internal boundaries too so we need to check which side we are on
74 
75  // By default we approximate the boundary value with the neighboring cell value
76  auto boundary_value = _var.getElemValue(*elem_info, determineState());
77  auto reflected_boundary_value = boundary_value;
78 
79  // We don't have to flip the sign of the normal because we are subtacting normal*normal.
80  auto scaled_normal = _current_face_info->normal();
81  scaled_normal *= 2 * scaled_normal(_index);
82 
83  for (const auto dim_i : make_range(_dim))
84  reflected_boundary_value -=
85  scaled_normal(dim_i) * _vel_vars[dim_i]->getElemValue(*elem_info, determineState());
86 
87  return 0.5 * (boundary_value + reflected_boundary_value);
88 }
89 
90 Real
92 {
93  // We allow internal boundaries too so we need to check which side we are on
97 
98  Real boundary_normal_grad = 0.0;
99 
100  // We don't have to flip the sign of the normal because we are subtacting normal*normal.
101  auto scaled_normal = _current_face_info->normal();
102  scaled_normal *= scaled_normal(_index);
103 
104  for (const auto dim_i : make_range(_dim))
105  boundary_normal_grad +=
106  scaled_normal(dim_i) * _vel_vars[dim_i]->getElemValue(*elem_info, determineState());
107 
108  return boundary_normal_grad / computeCellToFaceDistance();
109 }
110 
111 Real
113 {
114  // No matter if we have a one-term or two-term expansion we will always
115  // have a contribution to the matrix
116  const auto normal_component = _current_face_info->normal()(_index);
117  const auto normal_component_sq = normal_component * normal_component;
118  return 1.0 - normal_component_sq;
119 }
120 
121 Real
123 {
124  // We allow internal boundaries too so we need to check which side we are on
125  const auto elem_info = _current_face_type == FaceInfo::VarFaceNeighbors::ELEM
128 
129  // We don't have to flip the sign of the normal because we are subtacting normal*normal.
130  auto scaled_normal = _current_face_info->normal();
131  scaled_normal *= scaled_normal(_index);
132 
133  auto current_bd_value = computeBoundaryValue();
134  const auto normal_component = _current_face_info->normal()(_index);
135  const auto normal_component_sq = normal_component * normal_component;
136 
137  return current_bd_value -
138  (1.0 - normal_component_sq) * _var.getElemValue(*elem_info, determineState());
139 }
140 
141 Real
143 {
144  // We don't have to flip the sign of the normal because we are subtacting normal*normal.
145  const auto normal_component = _current_face_info->normal()(_index);
146  const auto normal_component_sq = normal_component * normal_component;
147 
148  return normal_component_sq / computeCellToFaceDistance();
149 }
150 
151 Real
153 {
154  // We allow internal boundaries too so we need to check which side we are on
155  const auto elem_info = _current_face_type == FaceInfo::VarFaceNeighbors::ELEM
158 
159  auto boundary_value = _var.getElemValue(*elem_info, determineState());
160 
161  // We don't have to flip the sign of the normal because we are subtacting normal*normal.
162  const auto normal_component = _current_face_info->normal()(_index);
163  const auto normal_component_sq = normal_component * normal_component;
165  normal_component_sq / computeCellToFaceDistance() * boundary_value;
166 }
Class implementing a symmetry boundary condition for the velocity variable.
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 computeCellToFaceDistance() const
virtual Real computeBoundaryValue() const override
Overriding all of these.
const MooseLinearVariableFVReal *const _u_var
Velocity in direction x.
virtual Real computeBoundaryGradientRHSContribution() const override
Moose::StateArg determineState() const
const ElemInfo * neighborInfo() const
MeshBase & mesh
LinearFVVelocitySymmetryBC(const InputParameters &parameters)
Class constructor.
const ElemInfo * elemInfo() const
virtual Real computeBoundaryGradientMatrixContribution() const override
void addRequiredParam(const std::string &name, const std::string &doc_string)
registerMooseObject("NavierStokesApp", LinearFVVelocitySymmetryBC)
static InputParameters validParams()
FaceInfo::VarFaceNeighbors _current_face_type
const Point & normal() const
std::vector< const MooseLinearVariableFVReal * > _vel_vars
For convenience we organize the velocity variables in a vector.
MooseLinearVariableFV< Real > & _var
const unsigned int _dim
The dimension of the mesh.
const MooseLinearVariableFVReal *const _v_var
Velocity in direction y.
virtual Real computeBoundaryValueMatrixContribution() const override
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const FaceInfo * _current_face_info
virtual Real computeBoundaryValueRHSContribution() const override
Real getElemValue(const ElemInfo &elem_info, const StateArg &state) const
IntRange< T > make_range(T beg, T end)
const MooseLinearVariableFVReal *const _w_var
Velocity in direction z.
void addClassDescription(const std::string &doc_string)
static InputParameters validParams()
virtual Real computeBoundaryNormalGradient() const override
const unsigned int _index
Index x|y|z, this is mainly to handle the deviatoric parts correctly in in the stress term...