https://mooseframework.inl.gov
LinearFVDiffusion.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 
10 #include "LinearFVDiffusion.h"
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<MooseFunctorName>("diffusion_coeff", 1.0, "The diffusion coefficient.");
28  params.addParam<InterpolationMethodName>(
29  "coeff_interp_method",
30  "Optional finite volume interpolation method used to compute a face-centered diffusion "
31  "coefficient. If omitted, the functor is evaluated directly on the face.");
32  return params;
33 }
34 
36  : LinearFVFluxKernel(params),
38  _diffusion_coeff(getFunctor<Real>("diffusion_coeff")),
39  _coeff_interp_method(isParamValid("coeff_interp_method")
40  ? &getFVFaceInterpolationMethod(
41  getParam<InterpolationMethodName>("coeff_interp_method"))
42  : nullptr),
43  _use_nonorthogonal_correction(getParam<bool>("use_nonorthogonal_correction")),
44  _flux_matrix_contribution(0.0),
45  _flux_rhs_contribution(0.0),
46  _cached_face_diffusivity(false),
47  _face_diffusivity(0.0)
48 {
51 }
52 
53 Real
55 {
57  {
59  "faceDiffusivity() is only valid for two-sided internal faces.");
60 
61  const auto state = determineState();
62 
66  else
68 
70  }
71 
72  return _face_diffusivity;
73 }
74 
75 void
77 {
80 }
81 
82 void
84 {
85  for (const auto bc : _var.getBoundaryConditionMap())
86  if (!dynamic_cast<const LinearFVAdvectionDiffusionBC *>(bc.second))
87  mooseError(
88  bc.second->type(), " is not a compatible boundary condition with ", this->type(), "!");
89 }
90 
91 Real
93 {
95 }
96 
97 Real
99 {
101 }
102 
103 Real
105 {
107 }
108 
109 Real
111 {
112  return -computeFluxRHSContribution();
113 }
114 
115 Real
117 {
118  // If we don't have the value yet, we compute it
120  {
121  // If we requested nonorthogonal correction, we use the normal component of the
122  // cell to face vector.
123  const auto d = _use_nonorthogonal_correction
126 
127  // Cache the matrix contribution
130  }
131 
133 }
134 
135 Real
137 {
138  // We only have contributions on the right hand side from internal faces
139  // if the nonorthogonal correction is enabled.
141  {
142  const auto state = determineState();
143 
144  // Get the gradients from the adjacent cells
145  const auto grad_elem = _var.gradSln(*_current_face_info->elemInfo(), state);
146  const auto & grad_neighbor = _var.gradSln(*_current_face_info->neighborInfo(), state);
147 
148  // Interpolate the two gradients to the face
149  const auto interp_coeffs =
151 
152  // Compute correction vector. Potential optimization: this only depends on the geometry
153  // so we can cache it in FaceInfo at some point.
154  const auto correction_vector =
157 
158  // Cache the matrix contribution
160  faceDiffusivity() *
161  (interp_coeffs.first * grad_elem + interp_coeffs.second * grad_neighbor) *
162  correction_vector * _current_face_area;
164  }
165 
166  return _flux_rhs_contribution;
167 }
168 
169 Real
171 {
172  const auto * const diff_bc = static_cast<const LinearFVAdvectionDiffusionBC *>(&bc);
173  mooseAssert(diff_bc, "This should be a valid BC!");
174 
175  auto grad_contrib = diff_bc->computeBoundaryGradientMatrixContribution() * _current_face_area;
176  // If the boundary condition does not include the diffusivity contribution then
177  // add it here.
178  if (!diff_bc->includesMaterialPropertyMultiplier())
179  {
180  const auto face_arg = singleSidedFaceArg(_current_face_info);
181  grad_contrib *= _diffusion_coeff(face_arg, determineState());
182  }
183 
184  return grad_contrib;
185 }
186 
187 Real
189 {
190  const auto * const diff_bc = static_cast<const LinearFVAdvectionDiffusionBC *>(&bc);
191  mooseAssert(diff_bc, "This should be a valid BC!");
192 
193  const auto face_arg = singleSidedFaceArg(_current_face_info);
194  const auto state = determineState();
195  auto grad_contrib = diff_bc->computeBoundaryGradientRHSContribution() * _current_face_area;
196 
197  // If the boundary condition does not include the diffusivity contribution then
198  // add it here.
199  if (!diff_bc->includesMaterialPropertyMultiplier())
200  grad_contrib *= _diffusion_coeff(face_arg, state);
201 
202  // We add the nonorthogonal corrector for the face here. Potential idea: we could do
203  // this in the boundary condition too. For now, however, we keep it like this.
204  // This should only be used for BCs where the gradient of the value is computed and
205  // not prescribed.
206 
207  if (_use_nonorthogonal_correction && diff_bc->useBoundaryGradientExtrapolation())
208  {
209  // We support internal boundaries as well. In that case we have to decide on which side
210  // of the boundary we are on.
211  const auto elem_info = (_current_face_type == FaceInfo::VarFaceNeighbors::ELEM)
214  const Real boundary_normal_multiplier =
216 
217  // Unit vector to the boundary. Unfortunately, we have to recompute it because the value
218  // stored in the face info is only correct for external boundaries
219  const auto e_Cf = _current_face_info->faceCentroid() - elem_info->centroid();
220  const auto correction_vector =
221  _current_face_info->normal() - 1 / (_current_face_info->normal() * e_Cf) * e_Cf;
222 
223  grad_contrib += _diffusion_coeff(face_arg, state) * _var.gradSln(*elem_info, state) *
224  boundary_normal_multiplier * correction_vector * _current_face_area;
225  }
226 
227  return grad_contrib;
228 }
virtual Real computeElemMatrixContribution() override
Computes the system matrix contribution from an element side on an internal face. ...
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.
Kernel that adds contributions from a diffusion term discretized using the finite volume method to a ...
const Moose::Functor< Real > & _diffusion_coeff
The functor for the diffusion coefficient.
virtual Real computeElemRightHandSideContribution() override
Computes the right hand side contribution from the element side on an internal face.
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
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.
Moose::StateArg determineState() const
Create a functor state argument that corresponds to the implicit state of this object.
Real _flux_rhs_contribution
The cached right hand side contribution.
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...
Real faceDiffusivity() const
Returns the diffusion coefficient interpolated to the current face.
MooseLinearVariableFV< Real > & _var
Reference to the linear finite volume variable.
virtual void setupFaceData(const FaceInfo *face_info)
Set the current FaceInfo object.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
const ElemInfo * elemInfo() const
Definition: FaceInfo.h:89
Real computeFluxMatrixContribution()
Computes the matrix contribution from the diffusive face flux.
FaceInfo::VarFaceNeighbors _current_face_type
Face ownership information for the current face.
bool _cached_face_diffusivity
Cache for interpolated diffusion coefficient.
VectorValue< Real > gradSln(const ElemInfo &elem_info, const StateArg &state) const
Get the variable gradient at a cell center.
static InputParameters validParams()
This data structure is used to store geometric and variable related metadata about each cell face in ...
Definition: FaceInfo.h:37
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 void setupFaceData(const FaceInfo *face_info) override
Set the current FaceInfo object.
LinearFVDiffusion(const InputParameters &params)
Class constructor.
virtual Real computeBoundaryRHSContribution(const LinearFVBoundaryCondition &bc) override
Computes the right hand side contribution from a boundary face.
Real _flux_matrix_contribution
The cached matrix contribution.
const std::string & type() const
Get the type of this class.
Definition: MooseBase.h:93
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
virtual void initialSetup() override
Gets called at the beginning of the simulation before this object is asked to do its job...
bool _cached_rhs_contribution
If we already built the right hand side contribution.
virtual Real computeBoundaryMatrixContribution(const LinearFVBoundaryCondition &bc) override
Computes the matrix contribution from a boundary face.
registerMooseObject("MooseApp", LinearFVDiffusion)
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 FVFaceInterpolationMethod * _coeff_interp_method
Optional interpolation method for the diffusion coefficient.
const std::unordered_map< BoundaryID, LinearFVBoundaryCondition * > & getBoundaryConditionMap()
virtual Real computeNeighborMatrixContribution() override
Computes the system matrix contribution from the neighbor side on an internal face.
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:281
Real computeFluxRHSContribution()
Computes the right hand side contribution from the diffusive face flux.
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.
const Point & dCN() const
Definition: FaceInfo.h:142
const bool _use_nonorthogonal_correction
Switch to enable/disable nonorthogonal correction.