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  params.addParam<InterpolationMethodName>(
33  "coeff_interp_method",
34  "Optional finite volume interpolation method used to compute a face-centered diagonal "
35  "diffusion tensor. If omitted, the functor is evaluated directly on the face.");
36  return params;
37 }
38 
40  : LinearFVFluxKernel(params),
42  _diffusion_tensor(getFunctor<RealVectorValue>("diffusion_tensor")),
43  _coeff_interp_method(isParamValid("coeff_interp_method")
44  ? &getFVFaceInterpolationMethod(
45  getParam<InterpolationMethodName>("coeff_interp_method"))
46  : nullptr),
47  _use_nonorthogonal_correction(getParam<bool>("use_nonorthogonal_correction")),
48  _use_nonorthogonal_correction_on_boundary(
49  isParamValid("use_nonorthogonal_correction_on_boundary")
50  ? getParam<bool>("use_nonorthogonal_correction_on_boundary")
51  : _use_nonorthogonal_correction),
52  _flux_matrix_contribution(0.0),
53  _flux_rhs_contribution(0.0)
54 {
56 }
57 
58 void
60 {
61  for (const auto bc : _var.getBoundaryConditionMap())
62  if (!dynamic_cast<const LinearFVAdvectionDiffusionBC *>(bc.second))
63  mooseError(
64  bc.second->type(), " is not a compatible boundary condition with ", this->type(), "!");
65 }
66 
69 {
70  const auto state = determineState();
71 
74 
76  "Face interpolation is only valid for two-sided internal faces.");
77 
78  const auto elem_tensor = _diffusion_tensor(makeElemArg(_current_face_info->elemPtr()), state);
79  const auto neighbor_tensor =
81 
82  RealVectorValue face_tensor;
83  for (const auto i : make_range(Moose::dim))
84  face_tensor(i) =
85  _coeff_interp_method->interpolate(*_current_face_info, elem_tensor(i), neighbor_tensor(i));
86 
87  return face_tensor;
88 }
89 
90 Real
92 {
94 }
95 
96 Real
98 {
100 }
101 
102 Real
104 {
106 }
107 
108 Real
110 {
111  return -computeFluxRHSContribution();
112 }
113 
114 Real
116 {
117  // If we don't have the value yet, we compute it
119  {
120  // If we requested nonorthogonal correction, we use the normal component of the
121  // cell to face vector.
122  const auto d = _use_nonorthogonal_correction
125 
126  auto scaled_diff_tensor = faceDiffusionTensor();
127 
128  for (const auto i : make_range(Moose::dim))
129  scaled_diff_tensor(i) = _current_face_info->normal()(i) * scaled_diff_tensor(i);
130 
131  auto normal_scaled_diff_tensor = scaled_diff_tensor * _current_face_info->normal();
132 
133  // Cache the matrix contribution
134  _flux_matrix_contribution = normal_scaled_diff_tensor / d * _current_face_area;
136  }
137 
139 }
140 
141 Real
143 {
144  // Cache the RHS contribution
146  {
147  const auto state_arg = determineState();
148 
149  // Get the gradients from the adjacent cells
150  const auto grad_elem = _var.gradSln(*_current_face_info->elemInfo(), state_arg);
151  const auto grad_neighbor = _var.gradSln(*_current_face_info->neighborInfo(), state_arg);
152 
153  // Interpolate the two gradients to the face
154  const auto interp_coeffs =
156 
157  const auto interpolated_gradient =
158  (interp_coeffs.first * grad_elem + interp_coeffs.second * grad_neighbor);
159 
160  auto scaled_diff_tensor = faceDiffusionTensor();
161 
162  for (const auto i : make_range(Moose::dim))
163  scaled_diff_tensor(i) = _current_face_info->normal()(i) * scaled_diff_tensor(i);
164 
165  auto normal_scaled_diff_tensor = scaled_diff_tensor * _current_face_info->normal();
166 
168  (scaled_diff_tensor - normal_scaled_diff_tensor * _current_face_info->normal()) *
169  interpolated_gradient;
170 
172  {
173  // Compute correction vector. Potential optimization: this only depends on the geometry
174  // so we can cache it in FaceInfo at some point.
175  const auto correction_vector =
179 
181  normal_scaled_diff_tensor * interpolated_gradient * correction_vector;
182  }
185  }
186 
187  return _flux_rhs_contribution;
188 }
189 
190 Real
192  const LinearFVBoundaryCondition & bc)
193 {
194  const auto * const diff_bc = static_cast<const LinearFVAdvectionDiffusionBC *>(&bc);
195  mooseAssert(diff_bc, "This should be a valid BC!");
196 
197  auto grad_contrib = diff_bc->computeBoundaryGradientMatrixContribution() * _current_face_area;
198  // If the boundary condition does not include the diffusivity contribution then
199  // add it here.
200  if (!diff_bc->includesMaterialPropertyMultiplier())
201  {
202  const auto face_arg = singleSidedFaceArg(_current_face_info);
203 
204  auto scaled_diff_tensor = _diffusion_tensor(face_arg, determineState());
205 
206  for (const auto i : make_range(Moose::dim))
207  scaled_diff_tensor(i) = _current_face_info->normal()(i) * scaled_diff_tensor(i);
208 
209  auto normal_scaled_diff_tensor = scaled_diff_tensor * _current_face_info->normal();
210 
211  grad_contrib *= normal_scaled_diff_tensor;
212  }
213 
214  return grad_contrib;
215 }
216 
217 Real
219 {
220  const auto * const diff_bc = static_cast<const LinearFVAdvectionDiffusionBC *>(&bc);
221  mooseAssert(diff_bc, "This should be a valid BC!");
222 
223  const auto face_arg = singleSidedFaceArg(_current_face_info);
224  const auto state_arg = determineState();
225  auto grad_contrib = diff_bc->computeBoundaryGradientRHSContribution();
226 
227  auto scaled_diff_tensor = _diffusion_tensor(face_arg, state_arg);
228 
229  for (const auto i : make_range(Moose::dim))
230  scaled_diff_tensor(i) = _current_face_info->normal()(i) * scaled_diff_tensor(i);
231 
232  auto normal_scaled_diff_tensor = scaled_diff_tensor * _current_face_info->normal();
233  const auto elem_info = (_current_face_type == FaceInfo::VarFaceNeighbors::ELEM)
236  mooseAssert(elem_info, "We should always have an element info for the current face");
237 
238  auto boundary_grad = _var.gradSln(*elem_info, state_arg);
239 
240  // If the boundary condition does not include the diffusivity contribution then
241  // add it here.
242  if (!diff_bc->includesMaterialPropertyMultiplier())
243  grad_contrib *= normal_scaled_diff_tensor;
244 
245  // We allow internal boundaries as well, in that case we have to make sure the normals point in
246  // the right direction
247  const Real boundary_normal_multiplier =
249 
250  grad_contrib += (scaled_diff_tensor - normal_scaled_diff_tensor * boundary_normal_multiplier *
252  boundary_grad;
253 
254  // We add the nonorthogonal corrector for the face here. Potential idea: we could do
255  // this in the boundary condition too. For now, however, we keep it like this.
256  if (diff_bc->useBoundaryGradientExtrapolation() && _use_nonorthogonal_correction_on_boundary)
257  {
258  const auto e_Cf = _current_face_info->faceCentroid() - elem_info->centroid();
259  const auto correction_vector =
260  _current_face_info->normal() - 1 / (_current_face_info->normal() * e_Cf) * e_Cf;
261 
262  grad_contrib +=
263  normal_scaled_diff_tensor * boundary_grad * boundary_normal_multiplier * correction_vector;
264  }
265 
266  return grad_contrib * _current_face_area;
267 }
virtual Real interpolate(const FaceInfo &face, Real elem_value, Real neighbor_value) const =0
Face interpolation operation for this method.
MetaPhysicL::DualNumber< V, D, asd > abs(const MetaPhysicL::DualNumber< V, D, asd > &a)
Definition: EigenADReal.h:50
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:117
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:90
const Point & faceCentroid() const
Returns the coordinates of the face centroid.
Definition: FaceInfo.h:75
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:165
const ElemInfo * elemInfo() const
Definition: FaceInfo.h:89
RealVectorValue faceDiffusionTensor() const
Returns the diagonal diffusion tensor interpolated to the current face.
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...
VectorValue< Real > gradSln(const ElemInfo &elem_info, const StateArg &state) const
Get the variable gradient at a cell center.
Moose::ElemArg makeElemArg(const Elem *elem, bool correct_skewnewss=false) const
Helper method to create an elemental argument for a functor that includes whether to perform skewness...
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.
const Elem * neighborPtr() const
Definition: FaceInfo.h:88
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:93
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:72
Real dCNMag() const
Definition: FaceInfo.h:148
Real _flux_matrix_contribution
The cached matrix contribution.
const Elem * elemPtr() const
Definition: FaceInfo.h:86
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:155
Helper interface for objects that need access to FVInterpolationMethod instances. ...
const std::unordered_map< BoundaryID, LinearFVBoundaryCondition * > & getBoundaryConditionMap()
Real computeFluxMatrixContribution()
Computes the matrix contribution from the diffusive face flux.
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:271
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.
const FVFaceInterpolationMethod * _coeff_interp_method
Optional interpolation method for the diagonal diffusion tensor components.
Real computeFluxRHSContribution()
Computes the right hand side contribution from the diffusive face flux.
const Point & dCN() const
Definition: FaceInfo.h:142