17 #include "libmesh/quadrature.h" 24 if (std::is_same<T, Real>::value)
26 else if (std::is_same<T, RealVectorValue>::value)
29 ::mooseError(
"unsupported InterfaceKernelTempl specialization");
42 _var(*this->mooseVariable()),
43 _normals(_assembly.normals()),
44 _u(_is_implicit ? _var.sln() : _var.slnOld()),
45 _grad_u(_is_implicit ? _var.gradSln() : _var.gradSlnOld()),
46 _phi(_assembly.phiFace(_var)),
47 _grad_phi(_assembly.gradPhiFace(_var)),
48 _test(_var.phiFace()),
49 _grad_test(_var.gradPhiFace()),
51 _neighbor_value(_is_implicit ? _neighbor_var.slnNeighbor() : _neighbor_var.slnOldNeighbor()),
52 _grad_neighbor_value(_neighbor_var.gradSlnNeighbor()),
53 _phi_neighbor(_assembly.phiFaceNeighbor(_neighbor_var)),
54 _grad_phi_neighbor(_assembly.gradPhiFaceNeighbor(_neighbor_var)),
55 _test_neighbor(_neighbor_var.phiFaceNeighbor()),
56 _grad_test_neighbor(_neighbor_var.gradPhiFaceNeighbor())
63 "In order to use an interface kernel, you must specify a boundary where it will live.");
68 mooseError(
"save_in and save_in_var_side must be the same length");
77 " as a save_in variable in " +
name());
83 "Error in " +
name() +
84 ". There is a mismatch between the fe_type of the save-in Auxiliary variable " 85 "and the fe_type of the the primary side nonlinear " 86 "variable this interface kernel object is acting on.");
93 "Error in " +
name() +
94 ". There is a mismatch between the fe_type of the save-in Auxiliary variable " 95 "and the fe_type of the the secondary side nonlinear " 96 "variable this interface kernel object is acting on.");
112 mooseError(
"diag_save_in and diag_save_in_var_side must be the same length");
121 " as a save_in variable in " +
name());
127 "Error in " +
name() +
128 ". There is a mismatch between the fe_type of the save-in Auxiliary variable " 129 "and the fe_type of the the primary side nonlinear " 130 "variable this interface kernel object is acting on.");
137 "Error in " +
name() +
138 ". There is a mismatch between the fe_type of the save-in Auxiliary variable " 139 "and the fe_type of the the secondary side nonlinear " 140 "variable this interface kernel object is acting on.");
154 template <
typename T>
164 const TemplateVariableTestValue & test_space = is_elem ? _test : _test_neighbor;
167 prepareVectorTag(_assembly, _var.number());
169 prepareVectorTagNeighbor(_assembly, _neighbor_var.number());
171 for (_qp = 0; _qp < _qrule->n_points(); _qp++)
173 initQpResidual(type);
174 for (_i = 0; _i < test_space.size(); _i++)
175 _local_re(_i) += _JxW[_qp] * _coord[_qp] * computeQpResidual(type);
178 accumulateTaggedLocalResidual();
180 if (_has_primary_residuals_saved_in && is_elem)
182 Threads::spin_mutex::scoped_lock lock(_resid_vars_mutex);
183 for (
const auto & var : _primary_save_in_residual_variables)
185 var->sys().solution().add_vector(_local_re, var->dofIndices());
188 else if (_has_secondary_residuals_saved_in && !is_elem)
190 Threads::spin_mutex::scoped_lock lock(_resid_vars_mutex);
191 for (
const auto & var : _secondary_save_in_residual_variables)
192 var->sys().solution().add_vector(_local_re, var->dofIndicesNeighbor());
196 template <
typename T>
209 if (!_var.activeOnSubdomain(_current_elem->subdomain_id()) ||
210 !_neighbor_var.activeOnSubdomain(_neighbor_elem->subdomain_id()))
213 precalculateResidual();
222 template <
typename T>
226 const TemplateVariableTestValue & test_space =
228 const TemplateVariableTestValue & loc_phi =
231 unsigned int ivar, jvar;
236 ivar = jvar = _var.number();
239 ivar = _var.number(), jvar = _neighbor_var.number();
242 ivar = _neighbor_var.number(), jvar = _var.number();
245 ivar = _neighbor_var.number(), jvar = _neighbor_var.number();
252 prepareMatrixTag(_assembly, ivar, jvar);
254 prepareMatrixTagNeighbor(_assembly, ivar, jvar, type);
256 for (_qp = 0; _qp < _qrule->n_points(); _qp++)
258 initQpJacobian(type);
259 for (_i = 0; _i < test_space.size(); _i++)
260 for (_j = 0; _j < loc_phi.size(); _j++)
261 _local_ke(_i, _j) += _JxW[_qp] * _coord[_qp] * computeQpJacobian(type);
264 accumulateTaggedLocalMatrix();
268 auto rows = _local_ke.m();
270 for (decltype(rows) i = 0; i < rows; i++)
271 diag(i) = _local_ke(i, i);
273 Threads::spin_mutex::scoped_lock lock(_jacoby_vars_mutex);
274 for (
const auto & var : _primary_save_in_jacobian_variables)
275 var->sys().solution().add_vector(diag, var->dofIndices());
279 auto rows = _local_ke.m();
281 for (decltype(rows) i = 0; i < rows; i++)
282 diag(i) = _local_ke(i, i);
284 Threads::spin_mutex::scoped_lock lock(_jacoby_vars_mutex);
285 for (
const auto & var : _secondary_save_in_jacobian_variables)
286 var->sys().solution().add_vector(diag, var->dofIndicesNeighbor());
290 template <
typename T>
303 if (!_var.activeOnSubdomain(_current_elem->subdomain_id()) ||
304 !_neighbor_var.activeOnSubdomain(_neighbor_elem->subdomain_id()))
307 precalculateJacobian();
313 template <
typename T>
318 const TemplateVariableTestValue & test_space =
320 const TemplateVariableTestValue & loc_phi =
326 ivar = _var.number();
328 ivar = _neighbor_var.number();
331 prepareMatrixTag(_assembly, ivar, jvar);
333 prepareMatrixTagNeighbor(_assembly, ivar, jvar, type);
336 if ((_local_ke.m() == test_space.size()) && (_local_ke.n() == loc_phi.size()))
337 for (_qp = 0; _qp < _qrule->n_points(); _qp++)
339 initQpOffDiagJacobian(type, jvar);
340 for (_i = 0; _i < test_space.size(); _i++)
341 for (_j = 0; _j < loc_phi.size(); _j++)
342 _local_ke(_i, _j) += _JxW[_qp] * _coord[_qp] * computeQpOffDiagJacobian(type, jvar);
345 accumulateTaggedLocalMatrix();
348 template <
typename T>
361 if (!_var.activeOnSubdomain(_current_elem->subdomain_id()) ||
362 !_neighbor_var.activeOnSubdomain(_neighbor_elem->subdomain_id()))
365 bool is_jvar_not_interface_var =
true;
366 if (jvar == _var.number())
368 precalculateJacobian();
370 is_jvar_not_interface_var =
false;
372 if (jvar == _neighbor_var.number())
374 precalculateJacobian();
376 is_jvar_not_interface_var =
false;
379 if (is_jvar_not_interface_var)
381 precalculateOffDiagJacobian(jvar);
387 template <
typename T>
400 if (!_var.activeOnSubdomain(_current_elem->subdomain_id()) ||
401 !_neighbor_var.activeOnSubdomain(_neighbor_elem->subdomain_id()))
404 bool is_jvar_not_interface_var =
true;
405 if (jvar == _var.number())
407 precalculateJacobian();
409 is_jvar_not_interface_var =
false;
411 if (jvar == _neighbor_var.number())
413 precalculateJacobian();
415 is_jvar_not_interface_var =
false;
418 if (is_jvar_not_interface_var)
420 precalculateOffDiagJacobian(jvar);
426 template <
typename T>
435 for (
const auto & [ivariable, jvariable] : _fe_problem.couplingEntries(_tid, _sys.number()))
437 if (ivariable->isFV())
440 const unsigned int ivar = ivariable->number();
441 const unsigned int jvar = jvariable->number();
444 prepareNeighborShapes(jvar);
446 if (_var.number() == ivar)
447 computeElementOffDiagJacobian(jvar);
449 if (_neighbor_var.number() == ivar)
450 computeNeighborOffDiagJacobian(jvar);
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)
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...
virtual const std::string & name() const
Get the name of the class.
const FEType & feType() const
Get the type of finite element object.
bool _has_primary_jacobians_saved_in
Whether there are primary jacobian aux variables.
SystemBase & _sys
Reference to the EquationSystem object.
MooseVariableFE< T > * mooseVariable() const
Enhances MooseVariableInterface interface provide values from neighbor elements.
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.
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.
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
virtual void addVariableToZeroOnJacobian(std::string var_name)
Adds this variable to the list of variables to be zeroed during each Jacobian evaluation.
const InputParameters & parameters() const
Get the parameters of the object.
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.