https://mooseframework.inl.gov
Loading...
Searching...
No Matches
LinearFVTurbulentDiffusion.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 "Assembly.h"
12#include "SubProblem.h"
14#include "NavierStokesMethods.h"
15#include "NS.h"
16
18
21{
24 "Represents the matrix and right hand side contributions of a "
25 "diffusion term for a turbulent variable in a partial differential equation.");
26
27 params.addParam<MooseFunctorName>(
28 "scaling_coeff", 1.0, "The scaling coefficient for the diffusion term.");
29
30 params.addParam<std::vector<BoundaryName>>(
31 "walls", {}, "Boundaries that correspond to solid walls.");
32 return params;
33}
34
36 : LinearFVDiffusion(params),
37 _scaling_coeff(getFunctor<Real>("scaling_coeff")),
38 _wall_boundary_names(getParam<std::vector<BoundaryName>>("walls"))
39{
42}
43
44void
51
52Real
58
59Real
65
66Real
72
73Real
79
80Real
82{
83 const auto * const diff_bc = static_cast<const LinearFVAdvectionDiffusionBC *>(&bc);
84 mooseAssert(diff_bc, "This should be a valid BC!");
85
86 auto grad_contrib = diff_bc->computeBoundaryGradientMatrixContribution() * _current_face_area;
87 // If the boundary condition does not include the diffusivity contribution then
88 // add it here.
89 if (!diff_bc->includesMaterialPropertyMultiplier())
90 {
91 const auto face_arg = singleSidedFaceArg(_current_face_info);
92 grad_contrib *=
94 }
95
96 return grad_contrib;
97}
98
99Real
101{
102 const auto * const diff_bc = static_cast<const LinearFVAdvectionDiffusionBC *>(&bc);
103 mooseAssert(diff_bc, "This should be a valid BC!");
104
105 const auto face_arg = singleSidedFaceArg(_current_face_info);
106 const auto state = determineState();
107 auto grad_contrib = diff_bc->computeBoundaryGradientRHSContribution() * _current_face_area;
108
109 // If the boundary condition does not include the diffusivity contribution then
110 // add it here.
111 if (!diff_bc->includesMaterialPropertyMultiplier())
112 grad_contrib *= _diffusion_coeff(face_arg, state) / _scaling_coeff(face_arg, state);
113
114 // We add the nonorthogonal corrector for the face here. Potential idea: we could do
115 // this in the boundary condition too. For now, however, we keep it like this.
116 if (_use_nonorthogonal_correction && diff_bc->needsBoundaryNonorthogonalCorrection())
117 {
118 const auto correction_vector =
121
122 grad_contrib += _diffusion_coeff(face_arg, state) *
123 _var.gradSln(*_current_face_info->elemInfo(), state) * correction_vector *
125 }
126
127 return grad_contrib;
128}
129
130void
132{
133 // Coumputing bounding map
134 const Elem * elem = _current_face_info->elemPtr();
135 const auto bounded_elem = _wall_bounded.find(elem) != _wall_bounded.end();
136 const Elem * neighbor = _current_face_info->neighborPtr();
137 const auto bounded_neigh = _wall_bounded.find(neighbor) != _wall_bounded.end();
138
139 // If we are on an internal face, we populate the four entries in the system matrix
140 // which touch the face
141 if (_current_face_type == FaceInfo::VarFaceNeighbors::BOTH)
142 {
143 // The dof ids of the variable corresponding to the element and neighbor
146
147 // Compute the entries which will go to the neighbor (offdiagonal) and element
148 // (diagonal).
149 const auto elem_matrix_contribution = computeElemMatrixContribution();
150 const auto neighbor_matrix_contribution = computeNeighborMatrixContribution();
151
152 // Populate matrix
153 if (hasBlocks(_current_face_info->elemInfo()->subdomain_id()) && !(bounded_elem))
154 {
155 _matrix_contribution(0, 0) = elem_matrix_contribution;
156 _matrix_contribution(0, 1) = neighbor_matrix_contribution;
157 }
158
159 if (hasBlocks(_current_face_info->neighborInfo()->subdomain_id()) && !(bounded_neigh))
160 {
161 _matrix_contribution(1, 0) = -elem_matrix_contribution;
162 _matrix_contribution(1, 1) = -neighbor_matrix_contribution;
163 }
165 }
166 // We are at a block boundary where the variable is not defined on one of the adjacent cells.
167 // We check if we have a boundary condition here
168 else if (_current_face_type == FaceInfo::VarFaceNeighbors::ELEM ||
169 _current_face_type == FaceInfo::VarFaceNeighbors::NEIGHBOR)
170 {
171 mooseAssert(_current_face_info->boundaryIDs().size() == 1,
172 "We should only have one boundary on every face.");
173
174 LinearFVBoundaryCondition * bc_pointer =
176
177 if (bc_pointer || _force_boundary_execution)
178 {
179 if (bc_pointer)
181 const auto matrix_contribution = computeBoundaryMatrixContribution(*bc_pointer);
182
183 // We allow internal (for the mesh) boundaries too, so we have to check on which side we
184 // are on (assuming that this is a boundary for the variable)
185 if ((_current_face_type == FaceInfo::VarFaceNeighbors::ELEM) && !(bounded_elem))
186 {
187 const auto dof_id_elem = _current_face_info->elemInfo()->dofIndices()[_sys_num][_var_num];
188 (*_linear_system.matrix).add(dof_id_elem, dof_id_elem, matrix_contribution);
189 }
190 else if ((_current_face_type == FaceInfo::VarFaceNeighbors::NEIGHBOR) && !(bounded_neigh))
191 {
192 const auto dof_id_neighbor =
194 (*_linear_system.matrix).add(dof_id_neighbor, dof_id_neighbor, matrix_contribution);
195 }
196 }
197 }
198}
199
200void
202{
203 // Coumputing bounding map
204 const Elem * elem = _current_face_info->elemPtr();
205 const auto bounded_elem = _wall_bounded.find(elem) != _wall_bounded.end();
206 const Elem * neighbor = _current_face_info->neighborPtr();
207 const auto bounded_neigh = _wall_bounded.find(neighbor) != _wall_bounded.end();
208
209 // If we are on an internal face, we populate the two entries in the right hand side
210 // which touch the face
211 if (_current_face_type == FaceInfo::VarFaceNeighbors::BOTH)
212 {
213 // The dof ids of the variable corresponding to the element and neighbor
216
217 // Compute the entries which will go to the neighbor and element positions.
218 const auto elem_rhs_contribution = computeElemRightHandSideContribution();
219 const auto neighbor_rhs_contribution = computeNeighborRightHandSideContribution();
220
221 // Populate right hand side
223 _rhs_contribution(0) = elem_rhs_contribution;
225 _rhs_contribution(1) = neighbor_rhs_contribution;
226
228 .add_vector(_rhs_contribution.get_values().data(), _dof_indices.get_values());
229 }
230 // We are at a block boundary where the variable is not defined on one of the adjacent cells.
231 // We check if we have a boundary condition here
232 else if (_current_face_type == FaceInfo::VarFaceNeighbors::ELEM ||
233 _current_face_type == FaceInfo::VarFaceNeighbors::NEIGHBOR)
234 {
235 mooseAssert(_current_face_info->boundaryIDs().size() == 1,
236 "We should only have one boundary on every face.");
237 LinearFVBoundaryCondition * bc_pointer =
239
240 if (bc_pointer || _force_boundary_execution)
241 {
242 if (bc_pointer)
244
245 const auto rhs_contribution = computeBoundaryRHSContribution(*bc_pointer);
246
247 // We allow internal (for the mesh) boundaries too, so we have to check on which side we
248 // are on (assuming that this is a boundary for the variable)
249 if ((_current_face_type == FaceInfo::VarFaceNeighbors::ELEM) && !(bounded_elem))
250 {
251 const auto dof_id_elem = _current_face_info->elemInfo()->dofIndices()[_sys_num][_var_num];
252 (*_linear_system.rhs).add(dof_id_elem, rhs_contribution);
253 }
254 else if ((_current_face_type == FaceInfo::VarFaceNeighbors::NEIGHBOR) && !(bounded_neigh))
255 {
256 const auto dof_id_neighbor =
258 (*_linear_system.rhs).add(dof_id_neighbor, rhs_contribution);
259 }
260 }
261 }
262}
registerMooseObject("NavierStokesApp", LinearFVTurbulentDiffusion)
bool hasBlocks(const SubdomainName &name) const
virtual const std::set< SubdomainID > & blockIDs() const
SubdomainID subdomain_id() const
const std::vector< std::vector< dof_id_type > > & dofIndices() const
Moose::FaceArg makeCDFace(const FaceInfo &fi, const bool correct_skewness=false) const
const Point & normal() const
const Point & eCN() const
const std::set< BoundaryID > & boundaryIDs() const
const Elem * neighborPtr() const
const ElemInfo * elemInfo() const
const ElemInfo * neighborInfo() const
const Elem * elemPtr() const
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)
void setupFaceData(const FaceInfo *face_info, const FaceInfo::VarFaceNeighbors face_type)
const bool _use_nonorthogonal_correction
static InputParameters validParams()
Real computeFluxMatrixContribution()
Real computeFluxRHSContribution()
const Moose::Functor< Real > & _diffusion_coeff
virtual void initialSetup() override
FaceInfo::VarFaceNeighbors _current_face_type
Moose::FaceArg singleSidedFaceArg(const FaceInfo *fi, Moose::FV::LimiterType limiter_type=Moose::FV::LimiterType::CentralDifference, bool correct_skewness=false) const
DenseMatrix< Real > _matrix_contribution
DenseVector< Real > _rhs_contribution
DenseVector< dof_id_type > _dof_indices
const bool _force_boundary_execution
const FaceInfo * _current_face_info
MooseLinearVariableFV< Real > & _var
const unsigned int _sys_num
const unsigned int _var_num
Kernel that adds contributions from a diffusion term of the turbulent variables, limited in the near-...
static InputParameters validParams()
LinearFVTurbulentDiffusion(const InputParameters &params)
Class constructor.
const std::vector< BoundaryName > & _wall_boundary_names
Wall boundaries.
virtual void addRightHandSideContribution() override
virtual void addMatrixContribution() override
virtual Real computeElemMatrixContribution() override
std::unordered_set< const Elem * > _wall_bounded
List for wall bounded elements.
virtual Real computeNeighborRightHandSideContribution() override
virtual Real computeBoundaryRHSContribution(const LinearFVBoundaryCondition &bc) override
virtual Real computeBoundaryMatrixContribution(const LinearFVBoundaryCondition &bc) override
virtual Real computeElemRightHandSideContribution() override
const Moose::Functor< Real > & _scaling_coeff
The functor for the scaling coefficient for the diffusion term.
virtual Real computeNeighborMatrixContribution() override
FEProblemBase & _fe_problem
libMesh::LinearImplicitSystem & _linear_system
LinearFVBoundaryCondition * getBoundaryCondition(const BoundaryID bd_id) const
VectorValue< Real > gradSln(const ElemInfo &elem_info, const StateArg &state) const
SubProblem & _subproblem
Moose::StateArg determineState() const
std::vector< T > & get_values()
NumericVector< Number > * rhs
SparseMatrix< Number > * matrix
void getWallBoundedElements(const std::vector< BoundaryName > &wall_boundary_name, const FEProblemBase &fe_problem, const SubProblem &subproblem, const std::set< SubdomainID > &block_ids, std::unordered_set< const Elem * > &wall_bounded)
Map marking wall bounded elements The map passed in wall_bounded_map gets cleared and re-populated.