https://mooseframework.inl.gov
LinearFVAnisotropicDiffusion.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 "Assembly.h"
12 #include "SubProblem.h"
14 
16 
19 {
21  params.addClassDescription("Represents the matrix and right hand side contributions of a "
22  "diffusion term in a partial differential equation.");
23  params.addParam<bool>(
24  "use_nonorthogonal_correction",
25  true,
26  "If the nonorthogonal correction should be used when computing the normal gradient.");
27  params.addParam<bool>(
28  "use_nonorthogonal_correction_on_boundary",
29  "If the nonorthogonal correction should be used when computing the normal gradient.");
30  params.addRequiredParam<MooseFunctorName>("diffusion_tensor",
31  "Functor describing a diagonal diffusion tensor.");
32  return params;
33 }
34 
36  : LinearFVFluxKernel(params),
37  _diffusion_tensor(getFunctor<RealVectorValue>("diffusion_tensor")),
38  _use_nonorthogonal_correction(getParam<bool>("use_nonorthogonal_correction")),
39  _use_nonorthogonal_correction_on_boundary(
40  isParamValid("use_nonorthogonal_correction_on_boundary")
41  ? getParam<bool>("use_nonorthogonal_correction_on_boundary")
42  : _use_nonorthogonal_correction),
43  _flux_matrix_contribution(0.0),
44  _flux_rhs_contribution(0.0)
45 {
47 }
48 
49 void
51 {
52  for (const auto bc : _var.getBoundaryConditionMap())
53  if (!dynamic_cast<const LinearFVAdvectionDiffusionBC *>(bc.second))
54  mooseError(
55  bc.second->type(), " is not a compatible boundary condition with ", this->type(), "!");
56 }
57 
58 Real
60 {
62 }
63 
64 Real
66 {
68 }
69 
70 Real
72 {
74 }
75 
76 Real
78 {
80 }
81 
82 Real
84 {
85  // If we don't have the value yet, we compute it
87  {
88  const auto face_arg = makeCDFace(*_current_face_info);
89 
90  // If we requested nonorthogonal correction, we use the normal component of the
91  // cell to face vector.
92  const auto d = _use_nonorthogonal_correction
95 
96  auto scaled_diff_tensor = _diffusion_tensor(face_arg, determineState());
97 
98  for (const auto i : make_range(Moose::dim))
99  scaled_diff_tensor(i) = _current_face_info->normal()(i) * scaled_diff_tensor(i);
100 
101  auto normal_scaled_diff_tensor = scaled_diff_tensor * _current_face_info->normal();
102 
103  // Cache the matrix contribution
104  _flux_matrix_contribution = normal_scaled_diff_tensor / d * _current_face_area;
106  }
107 
109 }
110 
111 Real
113 {
114  // Cache the RHS contribution
116  {
117  const auto face_arg = makeCDFace(*_current_face_info);
118  const auto state_arg = determineState();
119 
120  // Get the gradients from the adjacent cells
121  const auto grad_elem = _var.gradSln(*_current_face_info->elemInfo());
122  const auto grad_neighbor = _var.gradSln(*_current_face_info->neighborInfo());
123 
124  // Interpolate the two gradients to the face
125  const auto interp_coeffs =
127 
128  const auto interpolated_gradient =
129  (interp_coeffs.first * grad_elem + interp_coeffs.second * grad_neighbor);
130 
131  auto scaled_diff_tensor = _diffusion_tensor(face_arg, state_arg);
132 
133  for (const auto i : make_range(Moose::dim))
134  scaled_diff_tensor(i) = _current_face_info->normal()(i) * scaled_diff_tensor(i);
135 
136  auto normal_scaled_diff_tensor = scaled_diff_tensor * _current_face_info->normal();
137 
139  (scaled_diff_tensor - normal_scaled_diff_tensor * _current_face_info->normal()) *
140  interpolated_gradient;
141 
143  {
144  // Compute correction vector. Potential optimization: this only depends on the geometry
145  // so we can cache it in FaceInfo at some point.
146  const auto correction_vector =
150 
152  normal_scaled_diff_tensor * interpolated_gradient * correction_vector;
153  }
156  }
157 
158  return _flux_rhs_contribution;
159 }
160 
161 Real
163  const LinearFVBoundaryCondition & bc)
164 {
165  const auto * const diff_bc = static_cast<const LinearFVAdvectionDiffusionBC *>(&bc);
166  mooseAssert(diff_bc, "This should be a valid BC!");
167 
168  auto grad_contrib = diff_bc->computeBoundaryGradientMatrixContribution() * _current_face_area;
169  // If the boundary condition does not include the diffusivity contribution then
170  // add it here.
171  if (!diff_bc->includesMaterialPropertyMultiplier())
172  {
173  const auto face_arg = singleSidedFaceArg(_current_face_info);
174 
175  auto scaled_diff_tensor = _diffusion_tensor(face_arg, determineState());
176 
177  for (const auto i : make_range(Moose::dim))
178  scaled_diff_tensor(i) = _current_face_info->normal()(i) * scaled_diff_tensor(i);
179 
180  auto normal_scaled_diff_tensor = scaled_diff_tensor * _current_face_info->normal();
181 
182  grad_contrib *= normal_scaled_diff_tensor;
183  }
184 
185  return grad_contrib;
186 }
187 
188 Real
190 {
191  const auto * const diff_bc = static_cast<const LinearFVAdvectionDiffusionBC *>(&bc);
192  mooseAssert(diff_bc, "This should be a valid BC!");
193 
194  const auto face_arg = singleSidedFaceArg(_current_face_info);
195  auto grad_contrib = diff_bc->computeBoundaryGradientRHSContribution();
196 
197  auto scaled_diff_tensor = _diffusion_tensor(face_arg, determineState());
198 
199  for (const auto i : make_range(Moose::dim))
200  scaled_diff_tensor(i) = _current_face_info->normal()(i) * scaled_diff_tensor(i);
201 
202  auto normal_scaled_diff_tensor = scaled_diff_tensor * _current_face_info->normal();
203  auto boundary_grad = _var.gradSln(*_current_face_info->elemInfo());
204 
205  // If the boundary condition does not include the diffusivity contribution then
206  // add it here.
207  if (!diff_bc->includesMaterialPropertyMultiplier())
208  grad_contrib *= normal_scaled_diff_tensor;
209 
210  // We allow internal boundaries as well, in that case we have to make sure the normals point in
211  // the right direction
212  const Real boundary_normal_multiplier =
214 
215  grad_contrib += (scaled_diff_tensor - normal_scaled_diff_tensor * boundary_normal_multiplier *
217  boundary_grad;
218 
219  // We add the nonorthogonal corrector for the face here. Potential idea: we could do
220  // this in the boundary condition too. For now, however, we keep it like this.
222  {
223  const auto elem_info = (_current_face_type == FaceInfo::VarFaceNeighbors::ELEM)
226  const auto e_Cf = _current_face_info->faceCentroid() - elem_info->centroid();
227  const auto correction_vector =
228  _current_face_info->normal() - 1 / (_current_face_info->normal() * e_Cf) * e_Cf;
229 
230  grad_contrib +=
231  normal_scaled_diff_tensor * boundary_grad * boundary_normal_multiplier * correction_vector;
232  }
233 
234  return grad_contrib * _current_face_area;
235 }
MetaPhysicL::DualNumber< V, D, asd > abs(const MetaPhysicL::DualNumber< V, D, asd > &a)
Definition: EigenADReal.h:42
gc*elem+(1-gc)*neighbor
Base class for boundary conditions for linear FV systems.
std::pair< Real, Real > interpCoeffs(const InterpMethod m, const FaceInfo &fi, const bool one_is_elem, const T &face_flux=0.0)
Produce the interpolation coefficients in the equation:
Definition: MathFVUtils.h:114
const Moose::Functor< RealVectorValue > & _diffusion_tensor
The functor for the diagonal diffusion tensor (diagonal entries arranged in a vector) ...
virtual Real computeElemMatrixContribution() override
Computes the system matrix contribution from an element side on an internal face. ...
Moose::FaceArg singleSidedFaceArg(const FaceInfo *fi, Moose::FV::LimiterType limiter_type=Moose::FV::LimiterType::CentralDifference, bool correct_skewness=false) const
Determine the single sided face argument when evaluating a functor on a face.
registerMooseObject("MooseApp", LinearFVAnisotropicDiffusion)
Moose::StateArg determineState() const
Create a functor state argument that corresponds to the implicit state of this object.
const ElemInfo * neighborInfo() const
Definition: FaceInfo.h:86
const Point & faceCentroid() const
Returns the coordinates of the face centroid.
Definition: FaceInfo.h:71
Finite volume kernel that contributes approximations of discretized face flux terms to the matrix and...
MooseLinearVariableFV< Real > & _var
Reference to the linear finite volume variable.
Kernel that adds contributions from an anisotropic diffusion term discretized using the finite volume...
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
Definition: Moose.h:159
const ElemInfo * elemInfo() const
Definition: FaceInfo.h:85
FaceInfo::VarFaceNeighbors _current_face_type
Face ownership information for the current face.
virtual Real computeBoundaryMatrixContribution(const LinearFVBoundaryCondition &bc) override
Computes the matrix contribution from a boundary face.
void addRequiredParam(const std::string &name, const std::string &doc_string)
This method adds a parameter and documentation string to the InputParameters object that will be extr...
LinearFVAnisotropicDiffusion(const InputParameters &params)
Class constructor.
Base class for boundary conditions that are valid for advection diffusion problems.
static InputParameters validParams()
const FaceInfo * _current_face_info
Pointer to the face info we are operating on right now.
virtual Real computeNeighborRightHandSideContribution() override
Computes the right hand side contribution from the neighbor side on an internal face.
virtual Real computeElemRightHandSideContribution() override
Computes the right hand side contribution from the element side on an internal face.
const std::string & type() const
Get the type of this class.
Definition: MooseBase.h:89
virtual Real computeNeighborMatrixContribution() override
Computes the system matrix contribution from the neighbor side on an internal face.
const bool _use_nonorthogonal_correction_on_boundary
Switch to enable/disable nonorthogonal correction on boundary, this is mostly used to disable boundar...
const bool _use_nonorthogonal_correction
Switch to enable/disable nonorthogonal correction.
virtual Real computeBoundaryRHSContribution(const LinearFVBoundaryCondition &bc) override
Computes the right hand side contribution from a boundary face.
const Point & normal() const
Returns the unit normal vector for the face oriented outward from the face&#39;s elem element...
Definition: FaceInfo.h:68
Real dCNMag() const
Definition: FaceInfo.h:144
Real _flux_matrix_contribution
The cached matrix contribution.
bool _cached_rhs_contribution
If we already built the right hand side contribution.
virtual void initialSetup() override
Gets called at the beginning of the simulation before this object is asked to do its job...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const Point & eCN() const
Definition: FaceInfo.h:151
const std::unordered_map< BoundaryID, LinearFVBoundaryCondition * > & getBoundaryConditionMap()
Real computeFluxMatrixContribution()
Computes the matrix contribution from the diffusive face flux.
const VectorValue< Real > gradSln(const ElemInfo &elem_info) const
Get the variable gradient at a cell center.
IntRange< T > make_range(T beg, T end)
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
Definition: MooseBase.h:267
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump...
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object...
bool _cached_matrix_contribution
If we already built the matrix contribution.
Real _current_face_area
The current, coordinate system specific face area.
Moose::FaceArg makeCDFace(const FaceInfo &fi, const bool correct_skewness=false) const
Make a functor face argument with a central differencing limiter, e.g.
void computeCellGradients()
Switch to request cell gradient computations.
Real _flux_rhs_contribution
The cached right hand side contribution.
Real computeFluxRHSContribution()
Computes the right hand side contribution from the diffusive face flux.
const Point & dCN() const
Definition: FaceInfo.h:138