20#include "libmesh/numeric_vector.h"
21#include "libmesh/dof_map.h"
22#include "libmesh/quadrature.h"
23#include "libmesh/boundary_info.h"
25template <
typename ComputeValueType>
41template <
typename ComputeValueType>
46 parameters.getCheckedPointerParam<
SystemBase *>(
"_sys")
47 ->getVariable(parameters.get<
THREAD_ID>(
"_tid"),
48 parameters.get<AuxVariableName>(
"variable"))
51 Moose::VarKindType::VAR_AUXILIARY,
52 std::is_same<Real, ComputeValueType>::value
53 ?
Moose::VarFieldType::VAR_FIELD_STANDARD
54 : (
std::is_same<RealVectorValue, ComputeValueType>::value
55 ?
Moose::VarFieldType::VAR_FIELD_VECTOR
56 :
Moose::VarFieldType::VAR_FIELD_ARRAY)),
58 _var(_aux_sys.getActualFieldVariable<ComputeValueType>(
59 _tid, parameters.get<AuxVariableName>(
"variable"))),
60 _nodal(_var.isNodal()),
61 _u(_nodal ? _var.nodalValueArray() : _var.sln()),
63 _test(_bnd ? _var.phiFace() : _var.phi()),
64 _q_point(_bnd ? _assembly.qPointsFace() : _assembly.qPoints()),
65 _qrule(_bnd ? _assembly.qRuleFace() : _assembly.qRule()),
66 _JxW(_bnd ? _assembly.JxWFace() : _assembly.JxW()),
67 _coord(_assembly.coordTransformation()),
69 _current_elem(_assembly.elem()),
70 _current_side(_assembly.side()),
71 _current_elem_volume(_assembly.elemVolume()),
72 _current_side_volume(_assembly.sideElemVolume()),
74 _current_node(_assembly.node()),
75 _current_boundary_id(_assembly.currentBoundaryID()),
76 _solution(_aux_sys.solution()),
78 _current_lower_d_elem(_assembly.lowerDElem())
83 _coincident_lower_d_calc =
false;
86template <
typename ComputeValueType>
90 auto var = getVar(var_name, comp);
94 ": Unable to couple time derivative of an auxiliary variable into the auxiliary system.");
99template <
typename ComputeValueType>
102 unsigned int comp)
const
104 auto var = getVar(var_name, comp);
108 ": Unable to couple time derivative of an auxiliary variable into the auxiliary system.");
117 mooseAssert(_n_shapes == 1,
118 "Should only be calling setDofValue if there is one dof for the aux var");
119 _var.setDofValue(value, 0);
129template <
typename ComputeValueType>
133 mooseAssert(_coincident_lower_d_calc.has_value(),
134 "We should have set _coincident_lower_d_calc by now");
135 if (_coincident_lower_d_calc.value())
136 _var.insertLower(_aux_sys.solution());
138 _var.insert(_aux_sys.solution());
141template <
typename ComputeValueType>
149 if (_var.isNodalDefined())
152 ComputeValueType value = computeValue();
154 _var.setNodalValue(value);
160 _coincident_lower_d_calc.value() ? _var.dofIndicesLower().size() : _var.numberOfDofs();
164 ComputeValueType value = 0;
165 for (_qp = 0; _qp < _qrule->n_points(); _qp++)
166 value += _JxW[_qp] * _coord[_qp] * computeValue();
167 value /= (_bnd ? _current_side_volume : _current_elem_volume);
169 setDofValueHelper(value);
175 if (_coincident_lower_d_calc.value())
177 _local_sol.resize(1);
178 if constexpr (std::is_same<Real, ComputeValueType>::value)
179 _local_sol(0) = value;
181 mooseAssert(
false,
"We should not enter the single dof branch with a vector variable");
182 _var.setLowerDofValues(_local_sol);
185 _var.setNodalValue(value);
190 _local_re.resize(_n_shapes);
192 _local_ke.resize(_n_shapes, _n_shapes);
195 const auto & test = _coincident_lower_d_calc.value() ? _var.phiLower() : _test;
198 for (
unsigned int i = 0; i < test.size(); i++)
199 for (_qp = 0; _qp < _qrule->n_points(); _qp++)
201 ComputeValueType t = _JxW[_qp] * _coord[_qp] * test[i][_qp];
202 _local_re(i) += t * computeValue();
203 for (
unsigned int j = 0; j < test.size(); j++)
204 _local_ke(i, j) += t * test[j][_qp];
207 _local_sol.resize(_n_shapes);
209 _local_ke.svd_solve(_local_re, _local_sol);
211 _local_ke.cholesky_solve(_local_re, _local_sol);
213 _coincident_lower_d_calc.value() ? _var.setLowerDofValues(_local_sol)
214 : _var.setDofValues(_local_sol);
227 if (_var.isNodalDefined())
230 RealEigenVector value = computeValue();
232 _var.setNodalValue(value);
238 _var.numberOfDofs() % _var.count() == 0,
239 "The number of degrees of freedom should be cleanly divisible by the variable count");
240 _n_shapes = _var.numberOfDofs() / _var.count();
243 RealEigenVector value = RealEigenVector::Zero(_var.count());
244 for (_qp = 0; _qp < _qrule->n_points(); _qp++)
245 value += _JxW[_qp] * _coord[_qp] * computeValue();
246 value /= (_bnd ? _current_side_volume : _current_elem_volume);
250 _var.setNodalValue(value);
254 _local_re.resize(_n_shapes);
255 for (
unsigned int i = 0; i < _local_re.size(); ++i)
256 _local_re(i) = RealEigenVector::Zero(_var.count());
257 _local_ke.resize(_n_shapes, _n_shapes);
261 for (
unsigned int i = 0; i < _test.size(); i++)
262 for (_qp = 0; _qp < _qrule->n_points(); _qp++)
264 Real t = _JxW[_qp] * _coord[_qp] * _test[i][_qp];
265 _local_re(i) += t * computeValue();
266 for (
unsigned int j = 0; j < _test.size(); j++)
267 _local_ke(i, j) += t * _test[j][_qp];
271 _local_sol.resize(_n_shapes);
272 for (
unsigned int i = 0; i < _local_re.size(); ++i)
273 _local_sol(i) = RealEigenVector::Zero(_var.count());
274 DenseVector<Number> re(_n_shapes);
275 DenseVector<Number> sol(_n_shapes);
276 for (
unsigned int i = 0; i < _var.count(); ++i)
278 for (
unsigned int j = 0; j < _n_shapes; ++j)
279 re(j) = _local_re(j)(i);
282 _local_ke.svd_solve(re, sol);
284 _local_ke.cholesky_solve(re, sol);
286 for (
unsigned int j = 0; j < _n_shapes; ++j)
287 _local_sol(j)(i) = sol(j);
290 _var.setDofValues(_local_sol);
295template <
typename ComputeValueType>
299 if (_sys.solutionStatesInitialized())
300 mooseError(
"The solution states have already been initialized when calling ",
303 "Make sure to call uOld() within the object constructor.");
305 return _nodal ? _var.nodalValueOldArray() : _var.slnOld();
308template <
typename ComputeValueType>
312 if (_sys.solutionStatesInitialized())
313 mooseError(
"The solution states have already been initialized when calling ",
316 "Make sure to call uOlder() within the object constructor.");
318 return _nodal ? _var.nodalValueOlderArray() : _var.slnOlder();
321template <
typename ComputeValueType>
328template <
typename ComputeValueType>
332 mooseAssert(_bnd && !isNodal(),
333 "We can never be a lower-dimensional calculation if we are not boundary restricted "
334 "or if we are a nodal auxiliary kernel");
342 _coincident_lower_d_calc = !_var.numberOfDofs();
344 if (_coincident_lower_d_calc.value())
346 static const std::string lower_error =
"Make sure that the lower-d variable lives on a "
347 "lower-d block that is a superset of the boundary";
348 if (!_current_lower_d_elem)
349 mooseError(
"No lower-dimensional element. ", lower_error);
350 if (!_var.dofIndicesLower().size())
351 mooseError(
"No degrees of freedom. ", lower_error);
355template <
typename ComputeValueType>
356std::set<MooseVariableFieldBase *>
358 const libMesh::Node & node,
const std::set<MooseVariableFieldBase *> & vars_to_check)
360 if (node.
n_dofs(_var.sys().number(), _var.number()))
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
OutputTools< Real >::VariableValue VariableValue
Base class for auxiliary kernels.
static InputParameters validParams()
Base class for creating new auxiliary kernels and auxiliary boundary conditions.
AuxKernelTempl(const InputParameters ¶meters)
void insert()
Insert the just computed values into the auxiliary solution vector.
const OutputTools< ComputeValueType >::VariableValue & uOld() const
Retrieves the old value of the variable that this AuxKernel operates on.
virtual void compute() override
Computes the value and stores it in the solution vector.
void determineWhetherCoincidentLowerDCalc()
Determines whether we're a coincident lower-d calculation.
virtual const VariableValue & coupledDotDu(const std::string &var_name, unsigned int comp=0) const override
Time derivative of a coupled variable with respect to the coefficients.
virtual const VariableValue & coupledDot(const std::string &var_name, unsigned int comp=0) const override
Time derivative of a coupled variable.
void setDofValueHelper(const ComputeValueType &dof_value)
Currently only used when the auxiliary variable is a finite volume variable, this helps call through ...
const OutputTools< ComputeValueType >::VariableValue & uOlder() const
Retrieves the older value of the variable that this AuxKernel operates on.
virtual std::set< MooseVariableFieldBase * > checkVariables(const libMesh::Node &node, const std::set< MooseVariableFieldBase * > &vars_to_check) override
Check whether all of the supplied variables have degree of freedom indices on the supplied node.
static InputParameters validParams()
virtual const VariableValue & coupledDot(const std::string &var_name, unsigned int comp=0) const
Time derivative of a coupled variable.
virtual const VariableValue & coupledDotDu(const std::string &var_name, unsigned int comp=0) const
Time derivative of a coupled variable with respect to the coefficients.
virtual std::set< MooseVariableFieldBase * > checkVariables(const libMesh::Node &node, const std::set< MooseVariableFieldBase * > &vars_to_check)
Check whether all of the supplied variables have degree of freedom indices on the supplied node.
Interface for objects that need to get values of MooseVariables.
Base class for creating new nodally-based mortar auxiliary kernels.
Base class for a system (of equations)
unsigned int n_dofs(const unsigned int s, const unsigned int var=libMesh::invalid_uint) const
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...