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  _u_elem(_var.adSln()),
58  _u_neighbor(_var.adSlnNeighbor()),
59  _force_boundary_execution(getParam<bool>("force_boundary_execution"))
60 {
61  addMooseVariableDependency(&_var);
62 
63  const auto & vec = getParam<std::vector<BoundaryName>>("boundaries_to_force");
64  for (const auto & name : vec)
65  _boundaries_to_force.insert(_mesh.getBoundaryID(name));
66 
67  const auto & avoid_vec = getParam<std::vector<BoundaryName>>("boundaries_to_avoid");
68  for (const auto & name : avoid_vec)
69  {
70  const auto bid = _mesh.getBoundaryID(name);
71  _boundaries_to_avoid.insert(bid);
72  if (_boundaries_to_force.find(bid) != _boundaries_to_force.end())
73  paramError(
74  "boundaries_to_avoid",
75  "A boundary may not be specified in both boundaries_to_avoid and boundaries_to_force");
76  }
77 }
78 
79 bool
81 {
82  return Moose::FV::onBoundary(*this, fi);
83 }
84 
85 // Note the lack of quadrature point loops in the residual/jacobian compute
86 // functions. This is because finite volumes currently only works with
87 // constant monomial elements. We only have one quadrature point regardless of
88 // problem dimension and just multiply by the face area.
89 
90 bool
92 {
93  // Boundaries to avoid come first, since they are always obeyed
94  if (avoidBoundary(fi))
95  return true;
96 
97  // We get this to check if we are on a kernel boundary or not
98  const bool on_boundary = onBoundary(fi);
99 
100  // We are either on a kernel boundary or on an internal sideset
101  // which is handled as a boundary
102  if (on_boundary || !fi.boundaryIDs().empty())
103  {
104  // Blanket forcing on boundary
106  return false;
107 
108  // Selected boundaries to force
109  for (const auto bnd_to_force : _boundaries_to_force)
110  if (fi.boundaryIDs().count(bnd_to_force))
111  return false;
112 
113  // If we have a flux boundary on this face, we skip. This
114  // should be relatively easy to check with the cached maps.
115  if (_var.getFluxBCs(fi).first)
116  return true;
117 
118  // If we have a dirichlet BC, we are not skipping
119  if (_var.getDirichletBC(fi).first)
120  return false;
121  }
122 
123  // The last question is: are we on the inside or on the outside? If we are on an internal
124  // face we dont skip, otherwise we assume a natural BC and skip
125  return on_boundary;
126 }
127 
128 void
130 {
131  if (skipForBoundary(fi))
132  return;
133 
134  _face_info = &fi;
135  _normal = fi.normal();
136  _face_type = fi.faceType(std::make_pair(_var.number(), _var.sys().number()));
138 
139  // residual contributions for a flux kernel go to both neighboring faces.
140  // They are equal in magnitude but opposite in direction due to the outward
141  // facing unit normals of the face for each neighboring elements being
142  // oriented oppositely. We calculate the residual contribution once using
143  // the lower-id-elem-oriented _normal and just use the resulting residual's
144  // negative for the contribution to the neighbor element.
145 
146  // The fancy face type if condition checks here are because we might
147  // currently be running on a face for which this kernel's variable is only
148  // defined on one side. If this is the case, we need to only calculate+add
149  // the residual contribution if there is a dirichlet bc for the active
150  // face+variable. We always need to add the residual contribution when the
151  // variable is defined on both sides of the face. If the variable is only
152  // defined on one side and there is NOT a dirichlet BC, then there is either
153  // a flux BC or a natural BC - in either of those cases we don't want to add
154  // any residual contributions from regular flux kernels.
157  {
158  // residual contribution of this kernel to the elem element
160  _local_re(0) = r;
162  }
165  {
166  // residual contribution of this kernel to the neighbor element
168  _local_re(0) = -r;
170  }
171 }
172 
173 void
175 {
176  if (skipForBoundary(fi))
177  return;
178 
179  _face_info = &fi;
180  _normal = fi.normal();
181  _face_type = fi.faceType(std::make_pair(_var.number(), _var.sys().number()));
182  const ADReal r = fi.faceArea() * fi.faceCoord() * computeQpResidual();
183 
184  // The fancy face type if condition checks here are because we might
185  // currently be running on a face for which this kernel's variable is only
186  // defined on one side. If this is the case, we need to only calculate+add
187  // the jacobian contribution if there is a dirichlet bc for the active
188  // face+variable. We always need to add the jacobian contribution when the
189  // variable is defined on both sides of the face. If the variable is only
190  // defined on one side and there is NOT a dirichlet BC, then there is either
191  // a flux BC or a natural BC - in either of those cases we don't want to add
192  // any jacobian contributions from regular flux kernels.
195  {
196  mooseAssert(_var.dofIndices().size() == 1, "We're currently built to use CONSTANT MONOMIALS");
197 
199  _assembly, std::array<ADReal, 1>{{r}}, _var.dofIndices(), _var.scalingFactor());
200  }
201 
204  {
206  (_var.dofIndices().size() == 0),
207  "If the variable is only defined on the neighbor hand side of the face, then that "
208  "means it should have no dof indices on the elem element. Conversely if "
209  "the variable is defined on both sides of the face, then it should have a non-zero "
210  "number of degrees of freedom on the elem element");
211 
212  // We switch the sign for the neighbor residual
213  ADReal neighbor_r = -r;
214 
215  mooseAssert(_var.dofIndicesNeighbor().size() == 1,
216  "We're currently built to use CONSTANT MONOMIALS");
217 
219  std::array<ADReal, 1>{{neighbor_r}},
221  _var.scalingFactor());
222  }
223 }
224 
225 void
227 {
228  computeJacobian(fi);
229 }
230 
231 ADReal
232 FVFluxKernel::gradUDotNormal(const Moose::StateArg & time, const bool correct_skewness) const
233 {
234  mooseAssert(_face_info, "the face info should be non-null");
235  return Moose::FV::gradUDotNormal(*_face_info, _var, time, correct_skewness);
236 }
237 
239 FVFluxKernel::elemArg(const bool correct_skewness) const
240 {
241  mooseAssert(_face_info, "the face info should be non-null");
242  return {_face_info->elemPtr(), correct_skewness};
243 }
244 
246 FVFluxKernel::neighborArg(const bool correct_skewness) const
247 {
248  mooseAssert(_face_info, "the face info should be non-null");
249  return {_face_info->neighborPtr(), correct_skewness};
250 }
251 
254  const Moose::FV::LimiterType limiter_type,
255  const bool correct_skewness,
256  const Moose::StateArg * state_limiter) const
257 {
258  if (!fi)
259  fi = _face_info;
260 
261  return makeFace(*fi, limiter_type, true, correct_skewness, state_limiter);
262 }
263 
264 bool
266 {
267  for (const auto bnd_id : fi.boundaryIDs())
268  if (_boundaries_to_avoid.count(bnd_id))
269  return true;
270  return false;
271 }
272 
273 void
275 {
276  mooseError("FVFluxKernel residual/Jacobian evaluation requires a face information object");
277 }
278 
279 void
281 {
282  mooseError("FVFluxKernel residual/Jacobian evaluation requires a face information object");
283 }
284 
285 void
287 {
288  mooseError("FVFluxKernel residual/Jacobian evaluation requires a face information object");
289 }
290 
291 bool
292 FVFluxKernel::hasFaceSide(const FaceInfo & fi, const bool fi_elem_side) const
293 {
294  if (fi_elem_side)
295  return hasBlocks(fi.elem().subdomain_id());
296  else
297  return fi.neighborPtr() && hasBlocks(fi.neighbor().subdomain_id());
298 }
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:292
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:232
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:138
const std::set< BoundaryID > & boundaryIDs() const
Const getter for every associated boundary ID.
Definition: FaceInfo.h:120
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:131
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:239
unsigned int number() const
Get variable number coming from libMesh.
const Elem & elem() const
Definition: FaceInfo.h:81
void computeResidualAndJacobian() override
Compute this object&#39;s contribution to the residual and Jacobian simultaneously.
Definition: FVFluxKernel.C:286
const FaceInfo * _face_info
This is holds meta-data for geometric information relevant to the current face including elem+neighbo...
Definition: FVFluxKernel.h:89
auto raw_value(const Eigen::Map< T > &in)
Definition: EigenADReal.h:73
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:64
bool avoidBoundary(const FaceInfo &fi) const
Returns whether to avoid execution on a boundary.
Definition: FVFluxKernel.C:265
RealVectorValue _normal
This is the outward unit normal vector for the face the kernel is currently operating on...
Definition: FVFluxKernel.h:85
const bool _force_boundary_execution
Whether to force execution of flux kernels on all external boundaries.
Definition: FVFluxKernel.h:135
DualNumber< Real, DNDerivativeType, true > ADReal
Definition: ADRealForward.h:46
Real faceArea() const
Returns the face area of face id.
Definition: FaceInfo.h:60
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:280
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:91
bool onBoundary(const FaceInfo &fi) const
Return whether the supplied face is on a boundary of this object&#39;s execution.
Definition: FVFluxKernel.C:80
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:36
std::pair< bool, const FVDirichletBCBase * > getDirichletBC(const FaceInfo &fi) const
static InputParameters validParams()
Definition: FVFluxKernel.C:22
const Elem * neighborPtr() const
Definition: FaceInfo.h:84
A structure defining a "face" evaluation calling argument for Moose functors.
LimiterType
Definition: Limiter.h:26
const Elem & neighbor() const
Definition: FaceInfo.h:216
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:68
unsigned int number() const
Gets the number of this system.
Definition: SystemBase.C:1159
FaceInfo::VarFaceNeighbors _face_type
The face type.
Definition: FVFluxKernel.h:92
Assembly & _assembly
Reference to this Kernel&#39;s assembly object.
const Elem * elemPtr() const
Definition: FaceInfo.h:82
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:1169
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:246
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.
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:253
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:274
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:225
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...