https://mooseframework.inl.gov
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 {
23  params.addClassDescription(
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 
44 void
46 {
50 }
51 
52 Real
54 {
55  const auto face_arg = makeCDFace(*_current_face_info);
57 }
58 
59 Real
61 {
62  const auto face_arg = makeCDFace(*_current_face_info);
64 }
65 
66 Real
68 {
69  const auto face_arg = makeCDFace(*_current_face_info);
71 }
72 
73 Real
75 {
76  const auto face_arg = makeCDFace(*_current_face_info);
78 }
79 
80 Real
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 
99 Real
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.
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 
130 void
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
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  }
164  (*_linear_system.matrix).add_matrix(_matrix_contribution, _dof_indices.get_values());
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
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 
200 void
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
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
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 }
const unsigned int _var_num
SubProblem & _subproblem
const std::vector< BoundaryName > & _wall_boundary_names
Wall boundaries.
virtual Real computeBoundaryMatrixContribution(const LinearFVBoundaryCondition &bc) override
const std::set< BoundaryID > & boundaryIDs() const
const Moose::Functor< Real > & _diffusion_coeff
LinearFVTurbulentDiffusion(const InputParameters &params)
Class constructor.
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
libMesh::LinearImplicitSystem & _linear_system
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
void setupFaceData(const FaceInfo *face_info, const FaceInfo::VarFaceNeighbors face_type)
MooseLinearVariableFV< Real > & _var
NumericVector< Number > * rhs
const ElemInfo * elemInfo() const
LinearFVBoundaryCondition * getBoundaryCondition(const BoundaryID bd_id) const
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...
virtual const std::set< SubdomainID > & blockIDs() const
Real computeFluxMatrixContribution()
virtual Real computeBoundaryRHSContribution(const LinearFVBoundaryCondition &bc) override
virtual Real computeNeighborMatrixContribution() override
std::unordered_set< const Elem * > _wall_bounded
List for wall bounded elements.
FaceInfo::VarFaceNeighbors _current_face_type
const bool _force_boundary_execution
DenseVector< Real > _rhs_contribution
VectorValue< Real > gradSln(const ElemInfo &elem_info, const StateArg &state) const
const Moose::Functor< Real > & _scaling_coeff
The functor for the scaling coefficient for the diffusion term.
static InputParameters validParams()
const FaceInfo * _current_face_info
const Elem * neighborPtr() const
registerMooseObject("NavierStokesApp", LinearFVTurbulentDiffusion)
virtual Real computeElemMatrixContribution() override
virtual void addMatrixContribution() override
virtual Real computeElemRightHandSideContribution() override
const Point & normal() const
virtual void initialSetup() override
static InputParameters validParams()
const Elem * elemPtr() const
DenseVector< dof_id_type > _dof_indices
const std::vector< std::vector< dof_id_type > > & dofIndices() const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const Point & eCN() const
SparseMatrix< Number > * matrix
Kernel that adds contributions from a diffusion term of the turbulent variables, limited in the near-...
virtual Real computeNeighborRightHandSideContribution() override
Real computeFluxRHSContribution()
void addClassDescription(const std::string &doc_string)
virtual void initialSetup() override
virtual void addRightHandSideContribution() override
FEProblemBase & _fe_problem
bool hasBlocks(const SubdomainName &name) const
Moose::FaceArg makeCDFace(const FaceInfo &fi, const bool correct_skewness=false) const
const unsigned int _sys_num
SubdomainID subdomain_id() const
DenseMatrix< Real > _matrix_contribution
const bool _use_nonorthogonal_correction