19 #include "libmesh/quadrature.h" 26 if (std::is_same<T, Real>::value)
28 else if (std::is_same<T, RealVectorValue>::value)
31 ::mooseError(
"unsupported InterfaceKernelTempl specialization");
44 _var(*this->mooseVariable()),
45 _normals(_assembly.normals()),
46 _u(_is_implicit ? _var.sln() : _var.slnOld()),
47 _grad_u(_is_implicit ? _var.gradSln() : _var.gradSlnOld()),
48 _phi(_assembly.phiFace(_var)),
49 _grad_phi(_assembly.gradPhiFace(_var)),
50 _test(_var.phiFace()),
51 _grad_test(_var.gradPhiFace()),
53 _neighbor_value(_is_implicit ? _neighbor_var.slnNeighbor() : _neighbor_var.slnOldNeighbor()),
54 _grad_neighbor_value(_neighbor_var.gradSlnNeighbor()),
55 _phi_neighbor(_assembly.phiFaceNeighbor(_neighbor_var)),
56 _grad_phi_neighbor(_assembly.gradPhiFaceNeighbor(_neighbor_var)),
57 _test_neighbor(_neighbor_var.phiFaceNeighbor()),
58 _grad_test_neighbor(_neighbor_var.gradPhiFaceNeighbor()),
59 _same_system(_var.sys().number() == _neighbor_var.sys().number())
67 "In order to use an interface kernel, you must specify a boundary where it will live.");
72 mooseError(
"save_in and save_in_var_side must be the same length");
81 " as a save_in variable in " +
name());
87 "Error in " +
name() +
88 ". There is a mismatch between the fe_type of the save-in Auxiliary variable " 89 "and the fe_type of the the primary side nonlinear " 90 "variable this interface kernel object is acting on.");
97 "Error in " +
name() +
98 ". There is a mismatch between the fe_type of the save-in Auxiliary variable " 99 "and the fe_type of the the secondary side nonlinear " 100 "variable this interface kernel object is acting on.");
116 mooseError(
"diag_save_in and diag_save_in_var_side must be the same length");
125 " as a save_in variable in " +
name());
131 "Error in " +
name() +
132 ". There is a mismatch between the fe_type of the save-in Auxiliary variable " 133 "and the fe_type of the the primary side nonlinear " 134 "variable this interface kernel object is acting on.");
141 "Error in " +
name() +
142 ". There is a mismatch between the fe_type of the save-in Auxiliary variable " 143 "and the fe_type of the the secondary side nonlinear " 144 "variable this interface kernel object is acting on.");
158 template <
typename T>
168 const TemplateVariableTestValue & test_space = is_elem ? _test : _test_neighbor;
171 prepareVectorTag(_assembly, _var.number());
173 prepareVectorTagNeighbor(_assembly, _neighbor_var.number());
175 for (_qp = 0; _qp < _qrule->n_points(); _qp++)
177 initQpResidual(type);
178 for (_i = 0; _i < test_space.size(); _i++)
179 _local_re(_i) += _JxW[_qp] * _coord[_qp] * computeQpResidual(type);
182 accumulateTaggedLocalResidual();
185 if (_has_primary_residuals_saved_in && is_elem)
186 for (
const auto & var : _primary_save_in_residual_variables)
187 var->sys().solution().add_vector(_local_re, var->dofIndices());
188 else if (_has_secondary_residuals_saved_in && !is_elem)
189 for (
const auto & var : _secondary_save_in_residual_variables)
190 var->sys().solution().add_vector(_local_re, var->dofIndicesNeighbor());
193 template <
typename T>
206 if (!_var.activeOnSubdomain(_current_elem->subdomain_id()) ||
207 !_neighbor_var.activeOnSubdomain(_neighbor_elem->subdomain_id()))
210 precalculateResidual();
221 template <
typename T>
225 const TemplateVariableTestValue & test_space =
227 const TemplateVariableTestValue & loc_phi =
230 unsigned int ivar, jvar;
235 ivar = jvar = _var.number();
238 ivar = _var.number(), jvar = _neighbor_var.number();
241 ivar = _neighbor_var.number(), jvar = _var.number();
244 ivar = _neighbor_var.number(), jvar = _neighbor_var.number();
251 prepareMatrixTag(_assembly, ivar, jvar);
253 prepareMatrixTagNeighbor(_assembly, ivar, jvar, type);
255 for (_qp = 0; _qp < _qrule->n_points(); _qp++)
257 initQpJacobian(type);
258 for (_i = 0; _i < test_space.size(); _i++)
259 for (_j = 0; _j < loc_phi.size(); _j++)
260 _local_ke(_i, _j) += _JxW[_qp] * _coord[_qp] * computeQpJacobian(type);
263 accumulateTaggedLocalMatrix();
268 auto rows = _local_ke.m();
270 for (decltype(rows) i = 0; i < rows; i++)
271 diag(i) = _local_ke(i, i);
273 for (
const auto & var : _primary_save_in_jacobian_variables)
274 var->sys().solution().add_vector(diag, var->dofIndices());
278 auto rows = _local_ke.m();
280 for (decltype(rows) i = 0; i < rows; i++)
281 diag(i) = _local_ke(i, i);
283 for (
const auto & var : _secondary_save_in_jacobian_variables)
284 var->sys().solution().add_vector(diag, var->dofIndicesNeighbor());
288 template <
typename T>
301 if (!_var.activeOnSubdomain(_current_elem->subdomain_id()) ||
302 !_neighbor_var.activeOnSubdomain(_neighbor_elem->subdomain_id()))
305 precalculateJacobian();
312 template <
typename T>
317 const TemplateVariableTestValue & test_space =
319 const TemplateVariableTestValue & loc_phi =
325 ivar = _var.number();
327 ivar = _neighbor_var.number();
330 prepareMatrixTag(_assembly, ivar, jvar);
332 prepareMatrixTagNeighbor(_assembly, ivar, jvar, type);
335 if ((_local_ke.m() == test_space.size()) && (_local_ke.n() == loc_phi.size()))
336 for (_qp = 0; _qp < _qrule->n_points(); _qp++)
338 initQpOffDiagJacobian(type, jvar);
339 for (_i = 0; _i < test_space.size(); _i++)
340 for (_j = 0; _j < loc_phi.size(); _j++)
341 _local_ke(_i, _j) += _JxW[_qp] * _coord[_qp] * computeQpOffDiagJacobian(type, jvar);
344 accumulateTaggedLocalMatrix();
347 template <
typename T>
360 if (!_var.activeOnSubdomain(_current_elem->subdomain_id()) ||
361 !_neighbor_var.activeOnSubdomain(_neighbor_elem->subdomain_id()))
364 bool is_jvar_not_interface_var =
true;
365 if (jvar == _var.number())
367 precalculateJacobian();
369 is_jvar_not_interface_var =
false;
371 if (jvar == _neighbor_var.number() && _same_system)
373 precalculateJacobian();
375 is_jvar_not_interface_var =
false;
378 if (is_jvar_not_interface_var)
380 precalculateOffDiagJacobian(jvar);
386 template <
typename T>
399 if (!_var.activeOnSubdomain(_current_elem->subdomain_id()) ||
400 !_neighbor_var.activeOnSubdomain(_neighbor_elem->subdomain_id()))
408 bool is_jvar_not_interface_var =
true;
409 if (jvar == _var.number())
411 precalculateJacobian();
413 is_jvar_not_interface_var =
false;
415 if (jvar == _neighbor_var.number())
417 precalculateJacobian();
419 is_jvar_not_interface_var =
false;
422 if (is_jvar_not_interface_var)
424 precalculateOffDiagJacobian(jvar);
430 template <
typename T>
439 for (
const auto & [ivariable, jvariable] : _fe_problem.couplingEntries(_tid, _sys.number()))
441 if (ivariable->isFV())
444 const unsigned int ivar = ivariable->number();
445 const unsigned int jvar = jvariable->number();
448 prepareNeighborShapes(jvar);
450 if (_var.number() == ivar)
451 computeElementOffDiagJacobian(jvar);
454 if (_neighbor_var.number() == ivar)
455 computeNeighborOffDiagJacobian(jvar);
const libMesh::FEType & feType() const
Get the type of finite element object.
std::vector< MooseVariableFEBase * > _secondary_save_in_residual_variables
The aux variables to save the secondary contributions to.
static InputParameters validParams()
MultiMooseEnum _diag_save_in_var_side
MultiMooseEnum specifying whether jacobian save-in aux variables correspond to primary or secondary s...
Class for stuff related to variables.
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
InterfaceKernel and VectorInterfaceKernel is responsible for interfacing physics across subdomains...
InterfaceKernelTempl(const InputParameters ¶meters)
const InputParameters & parameters() const
Get the parameters of the object.
unsigned int size() const
Return the number of active items in the MultiMooseEnum.
std::vector< AuxVariableName > _diag_save_in_strings
The names of the aux variables that will be used to save-in jacobians (includes both primary and seco...
THREAD_ID _tid
The thread ID for this kernel.
MultiMooseEnum _save_in_var_side
MultiMooseEnum specifying whether residual save-in aux variables correspond to primary or secondary s...
bool _has_primary_jacobians_saved_in
Whether there are primary jacobian aux variables.
SystemBase & _sys
Reference to the EquationSystem object.
MooseVariableFE< T > * mooseVariable() const
Return the MooseVariableFE object that this interface acts on.
Enhances MooseVariableInterface interface provide values from neighbor elements.
const std::string & name() const
Get the name of the class.
const MooseVariableFE< T > & _neighbor_var
Coupled neighbor variable.
virtual void computeElementOffDiagJacobian(unsigned int jvar) override
Selects the correct Jacobian type and routine to call for the primary variable jacobian.
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
virtual void computeElemNeighResidual(Moose::DGResidualType type)
Using the passed DGResidual type, selects the correct test function space and residual block...
virtual void computeResidualAndJacobian() override
Computes the residual and Jacobian for the current side.
std::vector< MooseVariableFEBase * > _primary_save_in_jacobian_variables
The aux variables to save the diagonal Jacobian contributions of the primary variables to...
SubProblem & _subproblem
Reference to this kernel's SubProblem.
VarKindType
Framework-wide stuff.
virtual void computeOffDiagElemNeighJacobian(Moose::DGJacobianType type, unsigned int jvar)
Using the passed DGJacobian type, selects the correct test function and trial function spaces and jac...
virtual void computeJacobian() override
Computes the jacobian for the current side.
virtual MooseVariable & getStandardVariable(const THREAD_ID tid, const std::string &var_name)=0
Returns the variable reference for requested MooseVariable which may be in any system.
std::vector< MooseVariableFEBase * > _primary_save_in_residual_variables
The aux variables to save the primary residual contributions to.
virtual bool hasVariable(const std::string &var_name) const
Query a system for a variable.
virtual void computeElemNeighJacobian(Moose::DGJacobianType type)
Using the passed DGJacobian type, selects the correct test function and trial function spaces and jac...
void addMooseVariableDependency(MooseVariableFieldBase *var)
Call this function to add the passed in MooseVariableFieldBase as a variable that this object depends...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual void addVariableToZeroOnResidual(std::string var_name)
Adds this variable to the list of variables to be zeroed during each residual evaluation.
std::vector< MooseVariableFEBase * > _secondary_save_in_jacobian_variables
The aux variables to save the diagonal Jacobian contributions of the secondary variables to...
bool _has_secondary_residuals_saved_in
Whether there are secondary residual aux variables.
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...
std::vector< AuxVariableName > _save_in_strings
The names of the aux variables that will be used to save-in residuals (includes both primary and seco...
bool _has_primary_residuals_saved_in
Whether there are primary residual aux variables.
virtual void addVariableToZeroOnJacobian(std::string var_name)
Adds this variable to the list of variables to be zeroed during each Jacobian evaluation.
InterfaceKernelBase is the base class for all InterfaceKernel type classes.
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
bool _has_secondary_jacobians_saved_in
Whether there are secondary jacobian aux variables.
MooseVariableFE< T > & _var
The primary side MooseVariable.
SystemBase & sys()
Get the system this variable is part of.
virtual void computeResidual() override
Computes the residual for the current side.
static InputParameters validParams()
virtual void computeNeighborOffDiagJacobian(unsigned int jvar) override
Selects the correct Jacobian type and routine to call for the secondary variable jacobian.