https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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"
15
17
20{
22 params.addClassDescription("Represents the matrix and right hand side contributions of a "
23 "diffusion term in a partial differential equation.");
24 params.addParam<bool>(
25 "use_nonorthogonal_correction",
26 true,
27 "If the nonorthogonal correction should be used when computing the normal gradient.");
28 params.addParam<bool>(
29 "use_nonorthogonal_correction_on_boundary",
30 "If the nonorthogonal correction should be used when computing the normal gradient.");
31 params.addRequiredParam<MooseFunctorName>("diffusion_tensor",
32 "Functor describing a diagonal diffusion tensor.");
33 params.addParam<InterpolationMethodName>(
34 "coeff_interp_method",
35 "Optional finite volume interpolation method used to compute a face-centered diagonal "
36 "diffusion tensor. If omitted, the functor is evaluated directly on the face.");
37 return params;
38}
39
41 : LinearFVFluxKernel(params),
43 _diffusion_tensor(getFunctor<RealVectorValue>("diffusion_tensor")),
44 _coeff_interp_method(isParamValid("coeff_interp_method")
45 ? &getFVFaceInterpolationMethod(
46 getParam<InterpolationMethodName>("coeff_interp_method"))
47 : nullptr),
48 _use_nonorthogonal_correction(getParam<bool>("use_nonorthogonal_correction")),
49 _use_nonorthogonal_correction_on_boundary(
50 isParamValid("use_nonorthogonal_correction_on_boundary")
51 ? getParam<bool>("use_nonorthogonal_correction_on_boundary")
52 : _use_nonorthogonal_correction),
53 _gradient_field(_var.requestCellGradients()),
54 _flux_matrix_contribution(0.0),
55 _flux_rhs_contribution(0.0)
56{
57}
58
59void
61{
62 for (const auto bc : _var.getBoundaryConditionMap())
63 if (!dynamic_cast<const LinearFVAdvectionDiffusionBC *>(bc.second))
65 bc.second->type(), " is not a compatible boundary condition with ", this->type(), "!");
66}
67
68RealVectorValue
70{
71 const auto state = determineState();
72
75
77 "Face interpolation is only valid for two-sided internal faces.");
78
79 const auto elem_tensor = _diffusion_tensor(makeElemArg(_current_face_info->elemPtr()), state);
80 const auto neighbor_tensor =
82
83 RealVectorValue face_tensor;
84 for (const auto i : make_range(Moose::dim))
85 face_tensor(i) =
86 _coeff_interp_method->interpolate(*_current_face_info, elem_tensor(i), neighbor_tensor(i));
87
88 return face_tensor;
89}
90
91Real
96
97Real
102
103Real
108
109Real
114
115Real
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 auto scaled_diff_tensor = faceDiffusionTensor();
128
129 for (const auto i : make_range(Moose::dim))
130 scaled_diff_tensor(i) = _current_face_info->normal()(i) * scaled_diff_tensor(i);
131
132 auto normal_scaled_diff_tensor = scaled_diff_tensor * _current_face_info->normal();
133
134 // Cache the matrix contribution
135 _flux_matrix_contribution = normal_scaled_diff_tensor / d * _current_face_area;
137 }
138
140}
141
142Real
144{
145 // Cache the RHS contribution
147 {
148 // Get the gradients from the adjacent cells
149 const auto grad_elem = _gradient_field.gradient(*_current_face_info->elemInfo());
150 const auto grad_neighbor = _gradient_field.gradient(*_current_face_info->neighborInfo());
151
152 // Interpolate the two gradients to the face
153 const auto interp_coeffs =
155
156 const auto interpolated_gradient =
157 (interp_coeffs.first * grad_elem + interp_coeffs.second * grad_neighbor);
158
159 auto scaled_diff_tensor = faceDiffusionTensor();
160
161 for (const auto i : make_range(Moose::dim))
162 scaled_diff_tensor(i) = _current_face_info->normal()(i) * scaled_diff_tensor(i);
163
164 auto normal_scaled_diff_tensor = scaled_diff_tensor * _current_face_info->normal();
165
167 (scaled_diff_tensor - normal_scaled_diff_tensor * _current_face_info->normal()) *
168 interpolated_gradient;
169
171 {
172 // Compute correction vector. Potential optimization: this only depends on the geometry
173 // so we can cache it in FaceInfo at some point.
174 const auto correction_vector =
178
180 normal_scaled_diff_tensor * interpolated_gradient * correction_vector;
181 }
184 }
185
187}
188
189Real
191 const LinearFVBoundaryCondition & bc)
192{
193 const auto * const diff_bc = cast_ptr<const LinearFVAdvectionDiffusionBC *>(&bc);
194 mooseAssert(diff_bc, "This should be a valid BC!");
195
196 auto grad_contrib = diff_bc->computeBoundaryGradientMatrixContribution() * _current_face_area;
197 // If the boundary condition does not include the diffusivity contribution then
198 // add it here.
199 if (!diff_bc->includesMaterialPropertyMultiplier())
200 {
201 const auto face_arg = singleSidedFaceArg(_current_face_info);
202
203 auto scaled_diff_tensor = _diffusion_tensor(face_arg, determineState());
204
205 for (const auto i : make_range(Moose::dim))
206 scaled_diff_tensor(i) = _current_face_info->normal()(i) * scaled_diff_tensor(i);
207
208 auto normal_scaled_diff_tensor = scaled_diff_tensor * _current_face_info->normal();
209
210 grad_contrib *= normal_scaled_diff_tensor;
211 }
212
213 return grad_contrib;
214}
215
216Real
218{
219 const auto * const diff_bc = cast_ptr<const LinearFVAdvectionDiffusionBC *>(&bc);
220 mooseAssert(diff_bc, "This should be a valid BC!");
221
222 const auto face_arg = singleSidedFaceArg(_current_face_info);
223 const auto state_arg = determineState();
224 auto grad_contrib = diff_bc->computeBoundaryGradientRHSContribution();
225
226 auto scaled_diff_tensor = _diffusion_tensor(face_arg, state_arg);
227
228 for (const auto i : make_range(Moose::dim))
229 scaled_diff_tensor(i) = _current_face_info->normal()(i) * scaled_diff_tensor(i);
230
231 auto normal_scaled_diff_tensor = scaled_diff_tensor * _current_face_info->normal();
232 const auto elem_info = (_current_face_type == FaceInfo::VarFaceNeighbors::ELEM)
235 mooseAssert(elem_info, "We should always have an element info for the current face");
236
237 auto boundary_grad = _gradient_field.gradient(*elem_info);
238
239 // Apply the boundary-normal diffusivity when it is not already included by the BC.
240 if (!diff_bc->includesMaterialPropertyMultiplier())
241 grad_contrib *= normal_scaled_diff_tensor;
242
243 // We allow internal boundaries as well, in that case we have to make sure the normals point in
244 // the right direction.
245 const Real boundary_normal_multiplier =
247
248 // A complete prescribed flux already includes the anisotropic tangential contribution.
249 if (!diff_bc->providesCompleteBoundaryFlux())
250 grad_contrib += (scaled_diff_tensor - normal_scaled_diff_tensor * boundary_normal_multiplier *
252 boundary_grad;
253
254 if (diff_bc->needsBoundaryNonorthogonalCorrection() && _use_nonorthogonal_correction_on_boundary)
255 {
256 const auto e_Cf = _current_face_info->faceCentroid() - elem_info->centroid();
257 const auto correction_vector =
258 _current_face_info->normal() - 1 / (_current_face_info->normal() * e_Cf) * e_Cf;
259
260 grad_contrib +=
261 normal_scaled_diff_tensor * boundary_grad * boundary_normal_multiplier * correction_vector;
262 }
263
264 return grad_contrib * _current_face_area;
265}
registerMooseObject("MooseApp", LinearFVAnisotropicDiffusion)
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
virtual Real interpolate(const FaceInfo &face, Real elem_value, Real neighbor_value) const =0
Face interpolation operation for this method.
Helper interface for objects that need access to FVInterpolationMethod instances.
Moose::FaceArg makeCDFace(const FaceInfo &fi, const bool correct_skewness=false) const
Make a functor face argument with a central differencing limiter, e.g.
const Point & normal() const
Returns the unit normal vector for the face oriented outward from the face's elem element.
Definition FaceInfo.h:72
const Point & eCN() const
Definition FaceInfo.h:155
const Elem * neighborPtr() const
Definition FaceInfo.h:88
const ElemInfo * elemInfo() const
Definition FaceInfo.h:89
Real dCNMag() const
Definition FaceInfo.h:148
const ElemInfo * neighborInfo() const
Definition FaceInfo.h:90
const Elem * elemPtr() const
Definition FaceInfo.h:86
const Point & dCN() const
Definition FaceInfo.h:142
const Point & faceCentroid() const
Returns the coordinates of the face centroid.
Definition FaceInfo.h:75
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...
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
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.
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...
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.
Base class for boundary conditions that are valid for advection diffusion problems.
Kernel that adds contributions from an anisotropic diffusion term discretized using the finite volume...
Real computeFluxMatrixContribution()
Computes the matrix contribution from the diffusive face flux.
virtual Real computeBoundaryRHSContribution(const LinearFVBoundaryCondition &bc) override
Computes the right hand side contribution from a boundary face.
virtual Real computeNeighborRightHandSideContribution() override
Computes the right hand side 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 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.
RealVectorValue faceDiffusionTensor() const
Returns the diagonal diffusion tensor interpolated to the current face.
virtual void initialSetup() override
Gets called at the beginning of the simulation before this object is asked to do its job.
LinearFVAnisotropicDiffusion(const InputParameters &params)
Class constructor.
Real _flux_matrix_contribution
The cached matrix contribution.
const LinearFVGradientReader & _gradient_field
Gradient field used for internal and boundary anisotropic diffusion corrections.
Real _flux_rhs_contribution
The cached right hand side contribution.
const bool _use_nonorthogonal_correction
Switch to enable/disable nonorthogonal correction.
virtual Real computeNeighborMatrixContribution() override
Computes the system matrix 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 FVFaceInterpolationMethod * _coeff_interp_method
Optional interpolation method for the diagonal diffusion tensor components.
virtual Real computeBoundaryMatrixContribution(const LinearFVBoundaryCondition &bc) override
Computes the matrix contribution from a boundary face.
Real computeFluxRHSContribution()
Computes the right hand side contribution from the diffusive face flux.
Base class for boundary conditions for linear FV systems.
Finite volume kernel that contributes approximations of discretized face flux terms to the matrix and...
bool _cached_matrix_contribution
If we already built the matrix contribution.
bool _cached_rhs_contribution
If we already built the right hand side contribution.
FaceInfo::VarFaceNeighbors _current_face_type
Face ownership information for the current 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.
Real _current_face_area
The current, coordinate system specific face area.
const FaceInfo * _current_face_info
Pointer to the face info we are operating on right now.
static InputParameters validParams()
RealVectorValue gradient(const ElemInfo &elem_info) const
Read the full gradient at an element.
MooseLinearVariableFV< Real > & _var
Reference to the linear finite volume variable.
const std::string & type() const
Get the type of this class.
Definition MooseBase.h:93
const std::unordered_map< BoundaryID, LinearFVBoundaryCondition * > & getBoundaryConditionMap() const
Boundary-condition map keyed by boundary ID for this variable.
Moose::StateArg determineState() const
Create a functor state argument that corresponds to the implicit state of this object.
@ Average
gc*elem+(1-gc)*neighbor
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
Definition Moose.h:175