https://mooseframework.inl.gov
FVFluxKernel.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 "FVFluxKernel.h"
11 
12 #include "MooseVariableFV.h"
13 #include "SystemBase.h"
14 #include "MooseMesh.h"
15 #include "ADUtils.h"
16 #include "RelationshipManager.h"
17 
18 #include "libmesh/elem.h"
19 #include "libmesh/system.h"
20 
23 {
26  params.registerSystemAttributeName("FVFluxKernel");
27  params.addParam<bool>("force_boundary_execution",
28  false,
29  "Whether to force execution of this object on all external boundaries.");
30  params.addParam<std::vector<BoundaryName>>(
31  "boundaries_to_force",
32  std::vector<BoundaryName>(),
33  "The set of sidesets to force execution of this FVFluxKernel on. "
34  "Setting force_boundary_execution to true is equivalent to listing all external "
35  "mesh boundaries in this parameter.");
36  params.addParam<std::vector<BoundaryName>>(
37  "boundaries_to_avoid",
38  std::vector<BoundaryName>(),
39  "The set of sidesets to not execute this FVFluxKernel on. "
40  "This takes precedence over force_boundary_execution to restrict to less external boundaries."
41  " By default flux kernels are executed on all internal boundaries and Dirichlet boundary "
42  "conditions.");
43 
44  params.addParamNamesToGroup("force_boundary_execution boundaries_to_force boundaries_to_avoid",
45  "Boundary execution modification");
46  return params;
47 }
48 
50  : FVKernel(params),
51  TwoMaterialPropertyInterface(this, blockIDs(), {}),
55  this, false, false, /*is_fv=*/true),
56  _var(*mooseVariableFV()),
57  _force_boundary_execution(getParam<bool>("force_boundary_execution"))
58 {
59  addMooseVariableDependency(&_var);
60 
61  const auto & vec = getParam<std::vector<BoundaryName>>("boundaries_to_force");
62  for (const auto & name : vec)
63  _boundaries_to_force.insert(_mesh.getBoundaryID(name));
64 
65  const auto & avoid_vec = getParam<std::vector<BoundaryName>>("boundaries_to_avoid");
66  for (const auto & name : avoid_vec)
67  {
68  const auto bid = _mesh.getBoundaryID(name);
69  _boundaries_to_avoid.insert(bid);
70  if (_boundaries_to_force.find(bid) != _boundaries_to_force.end())
71  paramError(
72  "boundaries_to_avoid",
73  "A boundary may not be specified in both boundaries_to_avoid and boundaries_to_force");
74  }
75 }
76 
77 bool
79 {
80  return Moose::FV::onBoundary(*this, fi);
81 }
82 
83 // Note the lack of quadrature point loops in the residual/jacobian compute
84 // functions. This is because finite volumes currently only works with
85 // constant monomial elements. We only have one quadrature point regardless of
86 // problem dimension and just multiply by the face area.
87 
88 bool
90 {
91  // Boundaries to avoid come first, since they are always obeyed
92  if (avoidBoundary(fi))
93  return true;
94 
95  // We get this to check if we are on a kernel boundary or not
96  const bool on_boundary = onBoundary(fi);
97 
98  // We are either on a kernel boundary or on an internal sideset
99  // which is handled as a boundary
100  if (on_boundary || !fi.boundaryIDs().empty())
101  {
102  // Blanket forcing on boundary
104  return false;
105 
106  // Selected boundaries to force
107  for (const auto bnd_to_force : _boundaries_to_force)
108  if (fi.boundaryIDs().count(bnd_to_force))
109  return false;
110 
111  // If we have a flux boundary on this face, we skip. This
112  // should be relatively easy to check with the cached maps.
113  if (_var.getFluxBCs(fi).first)
114  return true;
115 
116  // If we have a dirichlet BC, we are not skipping
117  if (_var.getDirichletBC(fi).first)
118  return false;
119  }
120 
121  // The last question is: are we on the inside or on the outside? If we are on an internal
122  // face we dont skip, otherwise we assume a natural BC and skip
123  return on_boundary;
124 }
125 
126 void
128 {
129  if (skipForBoundary(fi))
130  return;
131 
132  _face_info = &fi;
133  _normal = fi.normal();
134  _face_type = fi.faceType(std::make_pair(_var.number(), _var.sys().number()));
136 
137  // residual contributions for a flux kernel go to both neighboring faces.
138  // They are equal in magnitude but opposite in direction due to the outward
139  // facing unit normals of the face for each neighboring elements being
140  // oriented oppositely. We calculate the residual contribution once using
141  // the lower-id-elem-oriented _normal and just use the resulting residual's
142  // negative for the contribution to the neighbor element.
143 
144  // The fancy face type if condition checks here are because we might
145  // currently be running on a face for which this kernel's variable is only
146  // defined on one side. If this is the case, we need to only calculate+add
147  // the residual contribution if there is a dirichlet bc for the active
148  // face+variable. We always need to add the residual contribution when the
149  // variable is defined on both sides of the face. If the variable is only
150  // defined on one side and there is NOT a dirichlet BC, then there is either
151  // a flux BC or a natural BC - in either of those cases we don't want to add
152  // any residual contributions from regular flux kernels.
155  {
156  // residual contribution of this kernel to the elem element
158  _local_re(0) = r;
160  }
163  {
164  // residual contribution of this kernel to the neighbor element
166  _local_re(0) = -r;
168  }
169 }
170 
171 void
173 {
174  if (skipForBoundary(fi))
175  return;
176 
177  _face_info = &fi;
178  _normal = fi.normal();
179  _face_type = fi.faceType(std::make_pair(_var.number(), _var.sys().number()));
180  const ADReal r = fi.faceArea() * fi.faceCoord() * computeQpResidual();
181 
182  // The fancy face type if condition checks here are because we might
183  // currently be running on a face for which this kernel's variable is only
184  // defined on one side. If this is the case, we need to only calculate+add
185  // the jacobian contribution if there is a dirichlet bc for the active
186  // face+variable. We always need to add the jacobian contribution when the
187  // variable is defined on both sides of the face. If the variable is only
188  // defined on one side and there is NOT a dirichlet BC, then there is either
189  // a flux BC or a natural BC - in either of those cases we don't want to add
190  // any jacobian contributions from regular flux kernels.
193  {
194  mooseAssert(_var.dofIndices().size() == 1, "We're currently built to use CONSTANT MONOMIALS");
195 
197  _assembly, std::array<ADReal, 1>{{r}}, _var.dofIndices(), _var.scalingFactor());
198  }
199 
202  {
204  (_var.dofIndices().size() == 0),
205  "If the variable is only defined on the neighbor hand side of the face, then that "
206  "means it should have no dof indices on the elem element. Conversely if "
207  "the variable is defined on both sides of the face, then it should have a non-zero "
208  "number of degrees of freedom on the elem element");
209 
210  // We switch the sign for the neighbor residual
211  ADReal neighbor_r = -r;
212 
213  mooseAssert(_var.dofIndicesNeighbor().size() == 1,
214  "We're currently built to use CONSTANT MONOMIALS");
215 
217  std::array<ADReal, 1>{{neighbor_r}},
219  _var.scalingFactor());
220  }
221 }
222 
223 void
225 {
226  computeJacobian(fi);
227 }
228 
229 ADReal
230 FVFluxKernel::gradUDotNormal(const Moose::StateArg & time, const bool correct_skewness) const
231 {
232  mooseAssert(_face_info, "the face info should be non-null");
233  return Moose::FV::gradUDotNormal(*_face_info, _var, time, correct_skewness);
234 }
235 
237 FVFluxKernel::elemArg(const bool correct_skewness) const
238 {
239  mooseAssert(_face_info, "the face info should be non-null");
240  return {_face_info->elemPtr(), correct_skewness};
241 }
242 
244 FVFluxKernel::neighborArg(const bool correct_skewness) const
245 {
246  mooseAssert(_face_info, "the face info should be non-null");
247  return {_face_info->neighborPtr(), correct_skewness};
248 }
249 
252  const Moose::FV::LimiterType limiter_type,
253  const bool correct_skewness,
254  const Moose::StateArg * state_limiter) const
255 {
256  if (!fi)
257  fi = _face_info;
258 
259  return makeFace(*fi, limiter_type, true, correct_skewness, state_limiter);
260 }
261 
262 bool
264 {
265  for (const auto bnd_id : fi.boundaryIDs())
266  if (_boundaries_to_avoid.count(bnd_id))
267  return true;
268  return false;
269 }
270 
271 void
273 {
274  mooseError("FVFluxKernel residual/Jacobian evaluation requires a face information object");
275 }
276 
277 void
279 {
280  mooseError("FVFluxKernel residual/Jacobian evaluation requires a face information object");
281 }
282 
283 void
285 {
286  mooseError("FVFluxKernel residual/Jacobian evaluation requires a face information object");
287 }
288 
289 bool
290 FVFluxKernel::hasFaceSide(const FaceInfo & fi, const bool fi_elem_side) const
291 {
292  if (fi_elem_side)
293  return hasBlocks(fi.elem().subdomain_id());
294  else
295  return fi.neighborPtr() && hasBlocks(fi.neighbor().subdomain_id());
296 }
virtual const std::vector< dof_id_type > & dofIndicesNeighbor() const final
Get neighbor DOF indices for currently selected element.
bool hasFaceSide(const FaceInfo &fi, const bool fi_elem_side) const override
Definition: FVFluxKernel.C:290
virtual ADReal gradUDotNormal(const Moose::StateArg &time, const bool correct_skewness) const
Calculates and returns "grad_u dot normal" on the face to be used for diffusive terms.
Definition: FVFluxKernel.C:230
void addResidualsAndJacobian(Assembly &assembly, const Residuals &residuals, const Indices &dof_indices, Real scaling_factor)
Add the provided incoming residuals and derivatives for the Jacobian, corresponding to the provided d...
std::unordered_set< BoundaryID > _boundaries_to_avoid
Which boundaries/sidesets to prevent the execution of flux kernels on.
Definition: FVFluxKernel.h:133
const std::set< BoundaryID > & boundaryIDs() const
Const getter for every associated boundary ID.
Definition: FaceInfo.h:124
void accumulateTaggedLocalResidual()
Local residual blocks will be appended by adding the current local kernel residual.
std::unordered_set< BoundaryID > _boundaries_to_force
Which boundaries/sidesets to force the execution of flux kernels on.
Definition: FVFluxKernel.h:126
Intermediate base class that ties together all the interfaces for getting MooseVariables with the Moo...
static InputParameters validParams()
Definition: FVKernel.C:15
Moose::ElemArg elemArg(bool correct_skewness=false) const
Definition: FVFluxKernel.C:237
unsigned int number() const
Get variable number coming from libMesh.
const Elem & elem() const
Definition: FaceInfo.h:85
void computeResidualAndJacobian() override
Compute this object&#39;s contribution to the residual and Jacobian simultaneously.
Definition: FVFluxKernel.C:284
const FaceInfo * _face_info
This is holds meta-data for geometric information relevant to the current face including elem+neighbo...
Definition: FVFluxKernel.h:84
auto raw_value(const Eigen::Map< T > &in)
Definition: EigenADReal.h:100
void registerSystemAttributeName(const std::string &value)
This method is used to define the MOOSE system name that is used by the TheWarehouse object for stori...
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
Real & faceCoord()
Sets/gets the coordinate transformation factor (for e.g.
Definition: FaceInfo.h:68
bool avoidBoundary(const FaceInfo &fi) const
Returns whether to avoid execution on a boundary.
Definition: FVFluxKernel.C:263
RealVectorValue _normal
This is the outward unit normal vector for the face the kernel is currently operating on...
Definition: FVFluxKernel.h:80
const bool _force_boundary_execution
Whether to force execution of flux kernels on all external boundaries.
Definition: FVFluxKernel.h:130
DualNumber< Real, DNDerivativeType, true > ADReal
Definition: ADRealForward.h:42
Real faceArea() const
Returns the face area of face id.
Definition: FaceInfo.h:64
std::pair< bool, std::vector< const FVFluxBC * > > getFluxBCs(const FaceInfo &fi) const
void computeJacobian() override
Compute this object&#39;s contribution to the diagonal Jacobian entries.
Definition: FVFluxKernel.C:278
FVFluxKernel(const InputParameters &params)
Definition: FVFluxKernel.C:49
virtual bool skipForBoundary(const FaceInfo &fi) const
Kernels are called even on boundaries in case one is for a variable with a dirichlet BC - in which ca...
Definition: FVFluxKernel.C:89
bool onBoundary(const FaceInfo &fi) const
Return whether the supplied face is on a boundary of this object&#39;s execution.
Definition: FVFluxKernel.C:78
Enhances MooseVariableInterface interface provide values from neighbor elements.
This data structure is used to store geometric and variable related metadata about each cell face in ...
Definition: FaceInfo.h:37
std::pair< bool, const FVDirichletBCBase * > getDirichletBC(const FaceInfo &fi) const
static InputParameters validParams()
Definition: FVFluxKernel.C:22
const Elem * neighborPtr() const
Definition: FaceInfo.h:88
A structure defining a "face" evaluation calling argument for Moose functors.
LimiterType
Definition: Limiter.h:26
const Elem & neighbor() const
Definition: FaceInfo.h:220
A structure that is used to evaluate Moose functors logically at an element/cell center.
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
unsigned int number() const
Gets the number of this system.
Definition: SystemBase.C:1158
FaceInfo::VarFaceNeighbors _face_type
The face type.
Definition: FVFluxKernel.h:87
Assembly & _assembly
Reference to this Kernel&#39;s assembly object.
const Elem * elemPtr() const
Definition: FaceInfo.h:86
FVKernel is a base class for all finite volume method kernels.
Definition: FVKernel.h:32
bool onBoundary(const SubdomainRestrictable &obj, const FaceInfo &fi)
Return whether the supplied face is on a boundary of the object&#39;s execution.
Definition: MathFVUtils.h:1174
virtual ADReal computeQpResidual()=0
This is the primary function that must be implemented for flux kernel terms.
void prepareVectorTagNeighbor(Assembly &assembly, unsigned int ivar)
Prepare data for computing element residual the according to active tags for DG and interface kernels...
Moose::ElemArg neighborArg(bool correct_skewness=false) const
Definition: FVFluxKernel.C:244
ADReal gradUDotNormal(const FaceInfo &face_info, const MooseVariableFV< Real > &fv_var, const Moose::StateArg &time, bool correct_skewness=false)
Calculates and returns "grad_u dot normal" on the face to be used for diffusive terms.
Definition: MathFVUtils.C:18
DenseVector< Number > _local_re
Holds local residual entries as they are accumulated by this Kernel.
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
This interface is designed for DGKernel, InternalSideUserObject, InterfaceUserObject, where material properties on a side of both its primary side (face) and its secondary side (neighbor) all required.
Moose::FaceArg singleSidedFaceArg(const FaceInfo *fi=nullptr, Moose::FV::LimiterType limiter_type=Moose::FV::LimiterType::CentralDifference, bool correct_skewness=false, const Moose::StateArg *state_limiter=nullptr) const
Determine the single sided face argument when evaluating a functor on a face.
Definition: FVFluxKernel.C:251
State argument for evaluating functors.
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...
MooseVariableFV< Real > & _var
Definition: FVFluxKernel.h:73
bool hasBlocks(const SubdomainName &name) const
Test if the supplied block name is valid for this object.
void prepareVectorTag(Assembly &assembly, unsigned int ivar)
Prepare data for computing element residual according to active tags.
void computeResidual() override
Compute this object&#39;s contribution to the residual.
Definition: FVFluxKernel.C:272
SystemBase & sys()
Get the system this variable is part of.
Moose::FaceArg makeFace(const FaceInfo &fi, const Moose::FV::LimiterType limiter_type, const bool elem_is_upwind, const bool correct_skewness=false, const Moose::StateArg *state_limiter=nullptr) const
Create a functor face argument from provided component arguments.
void scalingFactor(const std::vector< Real > &factor)
Set the scaling factor for this variable.
virtual const std::vector< dof_id_type > & dofIndices() const final
Get local DoF indices.
VarFaceNeighbors faceType(const std::pair< unsigned int, unsigned int > &var_sys) const
Returns which side(s) the given variable-system number pair is defined on for this face...
Definition: FaceInfo.h:229
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
This method takes a space delimited list of parameter names and adds them to the specified group name...