https://mooseframework.inl.gov
FVInterfaceKernel.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 "FVInterfaceKernel.h"
11 #include "FEProblemBase.h"
12 #include "SystemBase.h"
13 #include "MooseVariableFV.h"
14 #include "Assembly.h"
15 
18 {
21  params += SetupInterface::validParams();
34 
35  params.addRequiredParam<std::vector<SubdomainName>>(
36  "subdomain1", "The subdomains on the 1st side of the boundary.");
37  params.addRequiredParam<std::vector<SubdomainName>>(
38  "subdomain2", "The subdomains on the 2nd side of the boundary.");
39  params.addRequiredParam<NonlinearVariableName>(
40  "variable1", "The name of the first variable that this interface kernel applies to");
41  params.addParam<NonlinearVariableName>(
42  "variable2",
43  "The name of the second variable that this interface kernel applies to. If not supplied, "
44  "variable1 will be used.");
45  params.addParam<bool>("use_displaced_mesh",
46  false,
47  "Whether or not this object should use the "
48  "displaced mesh for computation. Note that "
49  "in the case this is true but no "
50  "displacements are provided in the Mesh block "
51  "the undisplaced mesh will still be used.");
52 
53  params.addParam<unsigned short>("ghost_layers", 1, "The number of layers of elements to ghost.");
54  params.addParam<bool>("use_point_neighbors",
55  false,
56  "Whether to use point neighbors, which introduces additional ghosting to "
57  "that used for simple face neighbors.");
58  params.addParamNamesToGroup("ghost_layers use_point_neighbors", "Parallel ghosting");
59 
60  // FV Interface Kernels always need one layer of ghosting because the elements
61  // on each side of the interface may be on different MPI ranks, but we still
62  // need to access them as a pair to compute the numerical face flux.
64  "ElementSideNeighborLayers",
67  [](const InputParameters & obj_params, InputParameters & rm_params)
68  {
69  rm_params.set<unsigned short>("layers") = obj_params.get<unsigned short>("ghost_layers");
70  rm_params.set<bool>("use_point_neighbors") = obj_params.get<bool>("use_point_neighbors");
71  });
72 
73  params.addParamNamesToGroup("use_displaced_mesh", "Advanced");
74  params.addCoupledVar("displacements", "The displacements");
75  params.declareControllable("enable");
76  params.registerBase("FVInterfaceKernel");
77  params.registerSystemAttributeName("FVInterfaceKernel");
78  params.set<bool>("_residual_object") = true;
79  return params;
80 }
81 
83  : MooseObject(parameters),
84  BoundaryRestrictableRequired(this, false),
85  SetupInterface(this),
86  FunctionInterface(this),
88  UserObjectInterface(this),
89  TransientInterface(this),
93  MeshChangedInterface(parameters),
94  TaggingInterface(this),
96  this, /*nodal=*/false, /*neighbor_nodal=*/false, /*is_fv=*/true),
97  TwoMaterialPropertyInterface(this, Moose::EMPTY_BLOCK_IDS, boundaryIDs()),
98  ADFunctorInterface(this),
99  _tid(getParam<THREAD_ID>("_tid")),
100  _subproblem(*getCheckedPointerParam<SubProblem *>("_subproblem")),
101  _var1(_subproblem.getVariable(_tid, getParam<NonlinearVariableName>("variable1"))
102  .sys()
103  .getFVVariable<Real>(_tid, getParam<NonlinearVariableName>("variable1"))),
104  _var2(_subproblem
105  .getVariable(_tid,
106  isParamValid("variable2") ? getParam<NonlinearVariableName>("variable2")
107  : getParam<NonlinearVariableName>("variable1"))
108  .sys()
109  .getFVVariable<Real>(_tid,
110  isParamValid("variable2")
111  ? getParam<NonlinearVariableName>("variable2")
112  : getParam<NonlinearVariableName>("variable1"))),
113  _assembly(_subproblem.assembly(_tid, _var1.sys().number())),
114  _mesh(_subproblem.mesh())
115 {
116  if (getParam<bool>("use_displaced_mesh"))
117  paramError("use_displaced_mesh", "FV interface kernels do not yet support displaced mesh");
118 
122 
123  for (const auto & sub_name : getParam<std::vector<SubdomainName>>("subdomain1"))
124  _subdomain1.insert(_mesh.getSubdomainID(sub_name));
125  for (const auto & sub_name : getParam<std::vector<SubdomainName>>("subdomain2"))
126  _subdomain2.insert(_mesh.getSubdomainID(sub_name));
127 
129  paramError("variable1",
130  "variable1 does not exist on all the blocks specified by the subdomain1 parameter");
132  {
133  const bool var2_provided = isParamValid("variable2");
134  const std::string var_name = var2_provided ? "variable2" : "variable1";
135  paramError(var_name,
136  var_name,
137  " does not exist on all the blocks specified by the subdomain2 parameter",
138  var2_provided ? ""
139  : ".\nNote that you did not provide the variable2 parameter, "
140  "so variable1 was implicitly used on subdomain2");
141  }
142 }
143 
144 void
146 {
147  _face_info = &fi;
148  _normal = fi.normal();
149  _elem_is_one = _subdomain1.find(fi.elem().subdomain_id()) != _subdomain1.end();
150 
151 #ifndef NDEBUG
152  const auto ft1 = fi.faceType(std::make_pair(_var1.number(), _var1.sys().number()));
153  const auto ft2 = fi.faceType(std::make_pair(_var2.number(), _var2.sys().number()));
154  constexpr auto ft_both = FaceInfo::VarFaceNeighbors::BOTH;
155  constexpr auto ft_elem = FaceInfo::VarFaceNeighbors::ELEM;
156  constexpr auto ft_neigh = FaceInfo::VarFaceNeighbors::NEIGHBOR;
157  mooseAssert(
158  (_elem_is_one && (ft1 == ft_elem || ft1 == ft_both) && (ft2 == ft_neigh || ft2 == ft_both)) ||
159  (!_elem_is_one && (ft1 == ft_neigh || ft1 == ft_both) &&
160  (ft2 == ft_elem || ft2 == ft_both)),
161  "Face type was not recognized. Check that the specified boundaries are interfaces.");
162 #endif
163 }
164 
165 void
166 FVInterfaceKernel::addResidual(const Real resid, const unsigned int var_num, const bool neighbor)
167 {
168  neighbor ? prepareVectorTagNeighbor(_assembly, var_num) : prepareVectorTag(_assembly, var_num);
169  _local_re(0) = resid;
171 }
172 
173 void
175  const dof_id_type dof_index,
176  const Real scaling_factor)
177 {
179  std::array<ADReal, 1>{{resid}},
180  std::array<dof_id_type, 1>{{dof_index}},
181  scaling_factor);
182 }
183 
184 void
186 {
187  setupData(fi);
188 
189  const auto r = MetaPhysicL::raw_value(fi.faceArea() * fi.faceCoord() * computeQpResidual());
190 
191  // If the two variables belong to two different nonlinear systems, we only contribute to the one
192  // which is being assembled right now
193  mooseAssert(_var1.sys().number() == _subproblem.currentNlSysNum(),
194  "The interface kernel should contribute to the system which variable1 belongs to!");
195  addResidual(_elem_is_one ? r : -r, _var1.number(), _elem_is_one ? false : true);
196  if (_var1.sys().number() == _var2.sys().number())
197  addResidual(_elem_is_one ? -r : r, _var2.number(), _elem_is_one ? true : false);
198 }
199 
200 void
202 {
203  computeJacobian(fi);
204 }
205 
206 void
208 {
209  setupData(fi);
210 
211  const auto r = fi.faceArea() * fi.faceCoord() * computeQpResidual();
212 
213  // If the two variables belong to two different nonlinear systems, we only contribute to the one
214  // which is being assembled right now
215  mooseAssert(_var1.sys().number() == _subproblem.currentNlSysNum(),
216  "The interface kernel should contribute to the system which variable1 belongs to!");
218  std::array<ADReal, 1>{{_elem_is_one ? r : -r}},
220  _var1.scalingFactor());
221  if (_var1.sys().number() == _var2.sys().number())
223  std::array<ADReal, 1>{{_elem_is_one ? -r : r}},
225  _var2.scalingFactor());
226 }
227 
229 FVInterfaceKernel::elemArg(const bool correct_skewness) const
230 {
231  return {_face_info->elemPtr(), correct_skewness};
232 }
233 
235 FVInterfaceKernel::neighborArg(const bool correct_skewness) const
236 {
237  return {_face_info->neighborPtr(), correct_skewness};
238 }
239 
242  const FaceInfo * fi,
243  const Moose::FV::LimiterType limiter_type,
244  const bool correct_skewness,
245  const Moose::StateArg * state_limiter) const
246 {
247  if (!fi)
248  fi = _face_info;
249 
250  const bool defined_on_elem_side = variable.hasBlocks(fi->elem().subdomain_id());
251  bool defined_on_neighbor_side = false;
252  if (fi->neighborPtr())
253  defined_on_neighbor_side = variable.hasBlocks(fi->neighbor().subdomain_id());
254 
255  const Elem * const elem = defined_on_elem_side && defined_on_neighbor_side
256  ? nullptr
257  : (defined_on_elem_side ? fi->elemPtr() : fi->neighborPtr());
258 
259  return {fi, limiter_type, true, correct_skewness, elem, state_limiter};
260 }
261 
262 bool
264 {
265  // Our default interface kernel treats elem and neighbor sides equivalently so we will assume for
266  // now that we will happily consume functor evaluations on either side of a face and any
267  // interpolation between said evaluations
268  return true;
269 }
virtual const std::vector< dof_id_type > & dofIndicesNeighbor() const final
Get neighbor DOF indices for currently selected element.
MooseVariableFV< Real > & _var1
const FaceInfo * _face_info
The face that this object is currently operating on.
MooseVariableFV< Real > & _var2
A class for requiring an object to be boundary restricted.
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...
static InputParameters validParams()
void computeResidual(const FaceInfo &fi) override
Compute the residual on the supplied face.
virtual void haveADObjects(bool have_ad_objects)
Method for setting whether we have any ad objects.
Definition: SubProblem.h:767
void accumulateTaggedLocalResidual()
Local residual blocks will be appended by adding the current local kernel residual.
Intermediate base class that ties together all the interfaces for getting MooseVariables with the Moo...
unsigned int number() const
Get variable number coming from libMesh.
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
Combine two vector parameters into a single vector of pairs.
virtual unsigned int currentNlSysNum() const =0
std::set< SubdomainID > _subdomain1
const Elem & elem() const
Definition: FaceInfo.h:81
virtual ADReal computeQpResidual()=0
std::set< SubdomainID > _subdomain2
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
static InputParameters validParams()
MeshBase & mesh
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...
const MooseMesh & _mesh
Real & faceCoord()
Sets/gets the coordinate transformation factor (for e.g.
Definition: FaceInfo.h:64
static InputParameters validParams()
void addRelationshipManager(const std::string &name, Moose::RelationshipManagerType rm_type, Moose::RelationshipManagerInputParameterCallback input_parameter_callback=nullptr)
Tells MOOSE about a RelationshipManager that this object needs.
static InputParameters validParams()
static InputParameters validParams()
DualNumber< Real, DNDerivativeType, true > ADReal
Definition: ADRealForward.h:46
Real faceArea() const
Returns the face area of face id.
Definition: FaceInfo.h:60
static InputParameters validParams()
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...
bool _elem_is_one
Whether the current element is associated with variable/subdomain 1 or 2.
An interface for accessing Moose::Functors for systems that care about automatic differentiation, e.g.
Assembly & _assembly
The Assembly object.
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
void registerBase(const std::string &value)
This method must be called from every base "Moose System" to create linkage with the Action System...
Interface for objects that needs transient capabilities.
This data structure is used to store geometric and variable related metadata about each cell face in ...
Definition: FaceInfo.h:36
static InputParameters validParams()
const Elem * neighborPtr() const
Definition: FaceInfo.h:84
SubProblem & _subproblem
The SubProblem.
Interface for notifications that the mesh has changed.
void computeJacobian(const FaceInfo &fi) override
Compute the jacobian on the supplied face.
A structure defining a "face" evaluation calling argument for Moose functors.
Every object that can be built by the factory should be derived from this class.
Definition: MooseObject.h:28
Interface for objects that need to use distributions.
LimiterType
Definition: Limiter.h:26
void computeResidualAndJacobian(const FaceInfo &fi) override
Compute the residual and Jacobian on the supplied face.
const Elem & neighbor() const
Definition: FaceInfo.h:216
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
A structure that is used to evaluate Moose functors logically at an element/cell center.
Interface for objects that need to use UserObjects.
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
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
unsigned int number() const
Gets the number of this system.
Definition: SystemBase.C:1159
static InputParameters validParams()
ADRealVectorValue _normal
The normal.
void setupData(const FaceInfo &fi)
setup data useful for this object
const Elem * elemPtr() const
Definition: FaceInfo.h:82
void addCoupledVar(const std::string &name, const std::string &doc_string)
This method adds a coupled variable name pair.
static InputParameters validParams()
Moose::ElemArg neighborArg(bool correct_skenewss=false) const
void addMooseVariableDependency(MooseVariableFieldBase *var)
Call this function to add the passed in MooseVariableFieldBase as a variable that this object depends...
void prepareVectorTagNeighbor(Assembly &assembly, unsigned int ivar)
Prepare data for computing element residual the according to active tags for DG and interface kernels...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const std::set< SubdomainID > EMPTY_BLOCK_IDS
Definition: MooseTypes.h:683
Generic class for solving transient nonlinear problems.
Definition: SubProblem.h:78
bool hasBlocks(const SubdomainID id) const override
Returns whether the functor is defined on this block.
Moose::FaceArg singleSidedFaceArg(const MooseVariableFV< Real > &variable, 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.
DenseVector< Number > _local_re
Holds local residual entries as they are accumulated by this Kernel.
Moose::ElemArg elemArg(bool correct_skewness=false) const
bool hasFaceSide(const FaceInfo &fi, bool fi_elem_side) const override
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.
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...
void addJacobian(const ADReal &resid, dof_id_type dof_index, Real scaling_factor)
Process the derivatives for the provided residual and dof index.
FVInterfaceKernel(const InputParameters &parameters)
Class constructor.
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
static InputParameters validParams()
Definition: MooseObject.C:25
void prepareVectorTag(Assembly &assembly, unsigned int ivar)
Prepare data for computing element residual according to active tags.
void addResidual(Real resid, unsigned int var_num, bool neighbor)
Process the provided residual given var_num and whether this is on the neighbor side.
static InputParameters validParams()
static InputParameters validParams()
SystemBase & sys()
Get the system this variable is part of.
Interface for objects that need to use functions.
void declareControllable(const std::string &name, std::set< ExecFlagType > execute_flags={})
Declare the given parameters as controllable.
void scalingFactor(const std::vector< Real > &factor)
Set the scaling factor for this variable.
Interface class for classes which interact with Postprocessors.
virtual const std::vector< dof_id_type > & dofIndices() const final
Get local DoF indices.
unsigned int THREAD_ID
Definition: MooseTypes.h:209
uint8_t dof_id_type
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
SubdomainID getSubdomainID(const SubdomainName &subdomain_name) const
Get the associated subdomain ID for the subdomain name.
Definition: MooseMesh.C:1728
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...