https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
67Real
69{
70 // We allow internal boundaries too so we need to check which side we are on
71 const auto elem_info = _current_face_type == FaceInfo::VarFaceNeighbors::ELEM
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
90Real
92{
93 // We allow internal boundaries too so we need to check which side we are on
94 const auto elem_info = _current_face_type == FaceInfo::VarFaceNeighbors::ELEM
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
111Real
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
121Real
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
141Real
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
151Real
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}
registerMooseObject("NavierStokesApp", LinearFVVelocitySymmetryBC)
const Point & normal() const
const ElemInfo * elemInfo() const
const ElemInfo * neighborInfo() const
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
static InputParameters validParams()
const FaceInfo * _current_face_info
Real computeCellToFaceDistance() const
FaceInfo::VarFaceNeighbors _current_face_type
MooseLinearVariableFV< Real > & _var
Class implementing a symmetry boundary condition for the velocity variable.
virtual Real computeBoundaryValueRHSContribution() const override
const unsigned int _index
Index x|y|z, this is mainly to handle the deviatoric parts correctly in in the stress term.
std::vector< const MooseLinearVariableFVReal * > _vel_vars
For convenience we organize the velocity variables in a vector.
const unsigned int _dim
The dimension of the mesh.
virtual Real computeBoundaryNormalGradient() const override
virtual Real computeBoundaryValueMatrixContribution() const override
const MooseLinearVariableFVReal *const _u_var
Velocity in direction x.
LinearFVVelocitySymmetryBC(const InputParameters &parameters)
Class constructor.
virtual Real computeBoundaryGradientRHSContribution() const override
const MooseLinearVariableFVReal *const _v_var
Velocity in direction y.
const MooseLinearVariableFVReal *const _w_var
Velocity in direction z.
virtual Real computeBoundaryGradientMatrixContribution() const override
static InputParameters validParams()
virtual Real computeBoundaryValue() const override
Overriding all of these.
void paramError(const std::string &param, Args... args) const
Real getElemValue(const ElemInfo &elem_info, const StateArg &state) const
Moose::StateArg determineState() const
MeshBase & mesh