24 _fe_problem(*getCheckedPointerParam<
FEProblemBase *>(
"_fe_problem_base")),
26 _t(_fe_problem.time()),
27 _var(_sys.getActualFieldVariable<T>(parameters.get<
THREAD_ID>(
"_tid"),
28 parameters.get<VariableName>(
"variable"))),
31 _fe_problem.assembly(_tid, _var.kind() ==
Moose::VAR_SOLVER ? _var.sys().number() : 0)),
32 _coord_sys(_assembly.coordSystem()),
33 _current_elem(_var.currentElem()),
34 _current_elem_volume(_assembly.elemVolume()),
35 _current_node(nullptr),
37 _fe_type(_var.feType()),
38 _dof_indices(_var.dofIndices())
59 _dim = _current_elem->dim();
61 const unsigned int n_nodes = _current_elem->n_nodes();
69 std::unique_ptr<FEBaseType> fe(FEBaseType::build(_dim, _fe_type));
72 std::unique_ptr<QBase> qrule(_fe_type.default_quadrature_rule(_dim));
73 std::unique_ptr<QBase> qedgerule(_fe_type.default_quadrature_rule(1));
74 std::unique_ptr<QBase> qsiderule(_fe_type.default_quadrature_rule(_dim - 1));
77 _phi = &fe->get_phi();
82 _cont = fe->get_continuity();
86 const std::vector<std::vector<GradientShapeType>> & ref_dphi = fe->get_dphi();
91 _JxW = &fe->get_JxW();
93 _xyz_values = &fe->get_xyz();
99 const unsigned int n_dofs = _dof_indices.size() / _var.count();
100 mooseAssert(_dof_indices.size() % _var.count() == 0,
101 "The number of degrees of freedom should be cleanly divisible by the variable count");
107 _dof_is_fixed.clear();
108 _dof_is_fixed.resize(n_dofs,
false);
110 _free_dof.resize(n_dofs, 0);
128 auto & dof_map = _var.dofMap();
129 const bool add_p_level =
130 dof_map.should_p_refine(dof_map.var_group_from_var_number(_var.number()));
132 for (_n = 0; _n !=
n_nodes; ++_n)
138 auto curr_node = _current_elem->node_ptr(_n);
139 const auto & block_ids = _sys.mesh().getNodeBlockIds(*curr_node);
141 auto priority_block = *(block_ids.begin());
142 for (
auto id : block_ids)
143 if (_var.hasBlocks(
id))
149 if (!hasBlocks(priority_block) && _var.isNodal())
151 for (
decltype(_nc) i = 0; i < _nc; ++i)
153 mask(_current_dof) =
false;
159 if (!_current_elem->is_vertex(_n))
169 else if (_fe_type.family ==
HERMITE)
170 setHermiteVertices();
171 else if (_cont ==
C_ONE)
172 setOtherCOneVertices();
180 _current_node =
nullptr;
184 for (
unsigned int e = 0; e != _current_elem->n_edges(); ++e)
191 for (
unsigned int i = 0; i != _side_dofs.size(); ++i)
192 if (!_dof_is_fixed[_side_dofs[i]])
193 _free_dof[_free_dofs++] = i;
200 fe->attach_quadrature_rule(qedgerule.get());
201 fe->edge_reinit(_current_elem, e);
202 _n_qp = qedgerule->n_points();
204 choleskySolve(
false);
209 for (
unsigned int s = 0; s != _current_elem->n_sides(); ++s)
216 for (
unsigned int i = 0; i != _side_dofs.size(); ++i)
217 if (!_dof_is_fixed[_side_dofs[i]])
218 _free_dof[_free_dofs++] = i;
225 fe->attach_quadrature_rule(qsiderule.get());
226 fe->reinit(_current_elem, s);
227 _n_qp = qsiderule->n_points();
229 choleskySolve(
false);
237 for (
unsigned int i = 0; i != n_dofs; ++i)
238 if (!_dof_is_fixed[i])
239 _free_dof[_free_dofs++] = i;
245 fe->attach_quadrature_rule(qrule.get());
246 fe->reinit(_current_elem);
247 _n_qp = qrule->n_points();
253 for (
unsigned int i = 0; i != n_dofs; ++i)
256 for (
size_t i = 0; i < mask.
size(); i++)
258 _var.setDofValue(_Ue(i), i);
317 _current_node = _current_elem->node_ptr(_n);
318 _Ue(_current_dof) = value(*_current_node);
319 _dof_is_fixed[_current_dof] =
true;
323 _Ue(_current_dof) = gradientComponent(grad, 0);
324 _dof_is_fixed[_current_dof] =
true;
329 Point nxminus = _current_elem->point(_n), nxplus = _current_elem->point(_n);
335 _Ue(_current_dof) = gradientComponent(grad, 1);
336 _dof_is_fixed[_current_dof] =
true;
340 (gradientComponent(gxplus, 1) - gradientComponent(gxminus, 1)) / 2. /
TOLERANCE;
341 _dof_is_fixed[_current_dof] =
true;
347 _Ue(_current_dof) = gradientComponent(grad, 2);
348 _dof_is_fixed[_current_dof] =
true;
352 (gradientComponent(gxplus, 2) - gradientComponent(gxminus, 2)) / 2. /
TOLERANCE;
353 _dof_is_fixed[_current_dof] =
true;
356 Point nyminus = _current_elem->point(_n), nyplus = _current_elem->point(_n);
363 (gradientComponent(gyplus, 2) - gradientComponent(gyminus, 2)) / 2. /
TOLERANCE;
364 _dof_is_fixed[_current_dof] =
true;
367 Point nxmym = _current_elem->point(_n), nxmyp = _current_elem->point(_n),
368 nxpym = _current_elem->point(_n), nxpyp = _current_elem->point(_n);
382 (gradientComponent(gxpyp, 2) - gradientComponent(gxmyp, 2)) / 2. /
TOLERANCE;
384 (gradientComponent(gxpym, 2) - gradientComponent(gxmym, 2)) / 2. /
TOLERANCE;
386 _Ue(_current_dof) = (gxzplus - gxzminus) / 2. /
TOLERANCE;
387 _dof_is_fixed[_current_dof] =
true;
431 for (_qp = 0; _qp < _n_qp; _qp++)
434 auto fineval = value((*_xyz_values)[_qp]);
438 finegrad = gradient((*_xyz_values)[_qp]);
440 auto dofs_size = is_volume ? (_dof_indices.size() / _var.count()) : _side_dofs.size();
443 for (
decltype(dofs_size) geomi = 0, freei = 0; geomi != dofs_size; ++geomi)
445 auto i = is_volume ? geomi : _side_dofs[geomi];
448 if (_dof_is_fixed[i])
450 for (
decltype(dofs_size) geomj = 0, freej = 0; geomj != dofs_size; ++geomj)
452 auto j = is_volume ? geomj : _side_dofs[geomj];
453 if (_dof_is_fixed[j])
454 _Fe(freei) -= (*_phi)[i][_qp] * (*_phi)[j][_qp] * (*_JxW)[_qp] * _Ue(j);
456 _Ke(freei, freej) += (*_phi)[i][_qp] * (*_phi)[j][_qp] * (*_JxW)[_qp];
459 if (_dof_is_fixed[j])
460 _Fe(freei) -= dotHelper((*_dphi)[i][_qp], (*_dphi)[j][_qp]) * (*_JxW)[_qp] * _Ue(j);
462 _Ke(freei, freej) += dotHelper((*_dphi)[i][_qp], (*_dphi)[j][_qp]) * (*_JxW)[_qp];
464 if (!_dof_is_fixed[j])
467 _Fe(freei) += (*_phi)[i][_qp] * fineval * (*_JxW)[_qp];
469 _Fe(freei) += dotHelper(finegrad, (*_dphi)[i][_qp]) * (*_JxW)[_qp];
506 _Ke.resize(_free_dofs, _free_dofs);
508 _Fe.resize(_free_dofs);
509 for (
unsigned int i = 0; i < _free_dofs; ++i)
510 _Fe(i).setZero(_var.count());
512 choleskyAssembly(is_volume);
517 for (
unsigned int i = 0; i < _var.count(); ++i)
520 for (
unsigned int j = 0; j < _free_dofs; ++j)
523 _Ke.cholesky_solve(v, x);
525 for (
unsigned int j = 0; j < _free_dofs; ++j)
530 for (
unsigned int i = 0; i != _free_dofs; ++i)
532 auto the_dof = is_volume ? _free_dof[i] : _side_dofs[_free_dof[i]];
536 _dof_is_fixed[the_dof] =
true;