17template <
typename OutputType>
22 _subproblem(_sys.subproblem()),
24 _dof_map(_sys.dofMap()),
26 _has_dof_values(false),
28 _solution_tag(_subproblem.getVectorTagID(
Moose::SOLUTION_TAG)),
29 _old_solution_tag(
Moose::INVALID_TAG_ID),
30 _older_solution_tag(
Moose::INVALID_TAG_ID),
31 _previous_nl_solution_tag(
Moose::INVALID_TAG_ID),
33 _need_u_dotdot(false),
34 _need_u_dot_old(false),
35 _need_u_dotdot_old(false),
36 _need_du_dot_du(false),
37 _need_du_dotdot_du(false),
38 _need_grad_dot(false),
39 _need_grad_dotdot(false),
40 _need_dof_values_dot(false),
41 _need_dof_values_dotdot(false),
42 _need_dof_values_dot_old(false),
43 _need_dof_values_dotdot_old(false),
44 _need_dof_du_dot_du(false),
45 _need_dof_du_dotdot_du(false),
53 const auto max_future_num_vector_tags = num_vector_tags + 2;
83template <
typename OutputType>
87 auto num_matrix_tags = _subproblem.numMatrixTags();
89 _matrix_tags_dof_u.resize(num_matrix_tags);
90 _need_matrix_tag_dof_u.resize(num_matrix_tags,
false);
92 _need_matrix_tag_u.resize(num_matrix_tags,
false);
93 _matrix_tag_u.resize(num_matrix_tags);
96template <
typename OutputType>
102 if (tag >= _need_vector_tag_dof_u.size())
105 _need_vector_tag_dof_u[tag] =
true;
107 if (_sys.hasVector(tag))
108 return _vector_tags_dof_u[tag];
111 "Tag ", tag,
" is not associated with any vector for nodal variable ", _var.name());
114 mooseError(
"Nodal values can be requested only on nodal variables, variable '",
119template <
typename OutputType>
125 if (tag >= _matrix_tags_dof_u.size())
127 _need_matrix_tag_dof_u.
resize(tag + 1,
false);
131 _need_matrix_tag_dof_u[tag] =
true;
133 if (_sys.hasMatrix(tag))
134 return _matrix_tags_dof_u[tag];
137 "Tag ", tag,
" is not associated with any matrix for nodal variable ", _var.name());
140 mooseError(
"Nodal values can be requested only on nodal variables, variable '",
145template <
typename OutputType>
149 mooseAssert(_need_vector_tag_dof_u.size() == _need_vector_tag_u.size() &&
150 _need_vector_tag_dof_u.size() == _need_vector_tag_grad.size() &&
151 _need_vector_tag_dof_u.size() == _vector_tags_dof_u.size() &&
152 _need_vector_tag_dof_u.size() == _vector_tag_u.size() &&
153 _need_vector_tag_dof_u.size() == _vector_tag_grad.size(),
154 "These sizes should be in sync.");
156 auto check_capacity = [tag](
const auto & vector_to_check)
158 if (tag + 1 > vector_to_check.capacity())
159 mooseError(
"New size greater than tag capacity. This will cause reallocation which will "
160 "invalidate any stored references.");
162 check_capacity(_need_vector_tag_dof_u);
163 check_capacity(_need_vector_tag_u);
164 check_capacity(_need_vector_tag_grad);
165 check_capacity(_vector_tags_dof_u);
166 check_capacity(_vector_tag_u);
167 check_capacity(_vector_tag_grad);
169 _need_vector_tag_dof_u.resize(tag + 1,
false);
170 _need_vector_tag_u.resize(tag + 1,
false);
171 _need_vector_tag_grad.resize(tag + 1,
false);
172 _vector_tags_dof_u.resize(tag + 1);
173 _vector_tag_u.resize(tag + 1);
174 _vector_tag_grad.resize(tag + 1);
177template <
typename OutputType>
181 if (tag >= _need_vector_tag_u.size())
184 _var.requireQpComputations();
186 _need_vector_tag_u[tag] =
true;
188 if (_sys.hasVector(tag))
189 return _vector_tag_u[tag];
191 mooseError(
"Tag ", tag,
" is not associated with any vector for variable ", _var.name());
194template <
typename OutputType>
198 if (tag >= _need_vector_tag_dof_u.size())
201 _var.requireQpComputations();
203 _need_vector_tag_dof_u[tag] =
true;
205 if (_sys.hasVector(tag))
206 return _vector_tags_dof_u[tag];
208 mooseError(
"Tag ", tag,
" is not associated with any vector for variable ", _var.name());
211template <
typename OutputType>
215 if (tag >= _need_vector_tag_grad.size())
218 _var.requireQpComputations();
220 _need_vector_tag_grad[tag] =
true;
222 if (_sys.hasVector(tag))
223 return _vector_tag_grad[tag];
225 mooseError(
"Tag ", tag,
" is not associated with any vector for variable ", _var.name());
228template <
typename OutputType>
232 if (tag >= _matrix_tag_u.size())
234 _need_matrix_tag_u.
resize(tag + 1,
false);
238 _var.requireQpComputations();
240 _need_matrix_tag_u[tag] =
true;
242 if (_sys.hasMatrix(tag))
243 return _matrix_tag_u[tag];
245 mooseError(
"Tag ", tag,
" is not associated with any matrix for variable ", _var.name());
248template <
typename OutputType>
255template <
typename OutputType>
259 if (state > _max_state)
261 _sys.needSolutionState(state);
266template <
typename OutputType>
267template <
typename ReturnType,
typename Functor>
276 needSolutionState(cast_int<unsigned int>(state));
287 insertSolutionTag(_old_solution_tag);
288 return functor(_old_solution_tag);
294 insertSolutionTag(_older_solution_tag);
295 return functor(_older_solution_tag);
301 insertSolutionTag(_previous_nl_solution_tag);
302 return functor(_previous_nl_solution_tag);
312template <
typename OutputType>
317 {
return vectorTagValue(tag_id); };
319 _var.requireQpComputations();
322 ->stateToTagHelper<FieldVariableValue>(state, functor);
325template <
typename OutputType>
330 {
return vectorTagGradient(tag_id); };
332 _var.requireQpComputations();
335 ->stateToTagHelper<FieldVariableGradient>(state, functor);
338template <
typename OutputType>
342 auto functor = [
this](
TagID tag_id) ->
const DofValues & {
return vectorTagDofValue(tag_id); };
344 _var.requireQpComputations();
350template <
typename OutputType>
357template <
typename OutputType>
364template <
typename OutputType>
371template <
typename OutputType>
378template <
typename OutputType>
382 auto & dof_values = _vector_tags_dof_u[_solution_tag];
383 mooseAssert(idx < dof_values.size(),
"idx is out of the bounds of degree of freedom values");
384 dof_values[idx] = value;
385 _has_dof_values =
true;
386 _nodal_value = value;
389 auto & u = _vector_tag_u[_solution_tag];
390 for (
unsigned int qp = 0; qp < u.size(); qp++)
399 auto & dof_values = _vector_tags_dof_u[_solution_tag];
400 for (
decltype(idx) i = 0; i < dof_values.size(); ++i, ++idx)
401 dof_values[idx] = value(i);
403 _has_dof_values =
true;
404 _nodal_value = value;
407template <
typename OutputType>
413 const auto & dof_values = _vector_tags_dof_u[_solution_tag];
414 mooseAssert(dof_values.size() == _dof_indices.size(),
415 "Degree of freedom values size and degree of freedom indices sizes must match.");
416 residual.insert(&dof_values[0], _dof_indices);
426 const auto & dof_values = _vector_tags_dof_u[_solution_tag];
427 mooseAssert(_dof_indices.size() % _count == 0,
428 "Dof indices should be cleanly divisible by the variable count");
429 const auto n_shapes = _dof_indices.size() / _count;
430 for (
const auto indx : index_range(_dof_indices))
432 const auto i = indx % n_shapes;
433 const auto j = indx / n_shapes;
434 residual.set(_dof_indices[indx], dof_values[i](j));
439template <
typename OutputType>
445 const auto & dof_values = _vector_tags_dof_u[_solution_tag];
446 residual.add_vector(&dof_values[0], _dof_indices);
456 const auto & dof_values = _vector_tags_dof_u[_solution_tag];
457 mooseAssert(_dof_indices.size() % _count == 0,
458 "Dof indices should be cleanly divisible by the variable count");
459 const auto n_shapes = _dof_indices.size() / _count;
460 for (
const auto indx : index_range(_dof_indices))
462 const auto i = indx % n_shapes;
463 const auto j = indx / n_shapes;
464 residual.add(_dof_indices[indx], dof_values[i](j));
469template <
typename OutputType>
476 vectorTagDofValue(state);
483 return _nodal_value_old;
486 return _nodal_value_older;
489 return _nodal_value_previous_nl;
498 mooseError(
"Nodal values can be requested only on nodal variables, variable '",
503template <
typename OutputType>
510 vectorTagDofValue(state);
514 return _nodal_value_array;
517 return _nodal_value_old_array;
520 return _nodal_value_older_array;
523 mooseError(
"No current support for PreviousNL for nodal value array");
527 mooseError(
"Nodal values can be requested only on nodal variables, variable '",
532template <
typename OutputType>
536 bool is_transient = _subproblem.isTransient();
538 auto n = _dof_indices.size();
543 if (_need_u_dot || _need_grad_dot || _need_dof_values_dot)
545 libmesh_assert(_sys.solutionUDot());
546 _dof_values_dot.resize(n);
547 _sys.solutionUDot()->get(_dof_indices, &_dof_values_dot[0]);
549 if (_need_u_dotdot || _need_grad_dotdot || _need_dof_values_dotdot)
551 libmesh_assert(_sys.solutionUDotDot());
552 _dof_values_dotdot.resize(n);
553 _sys.solutionUDotDot()->get(_dof_indices, &_dof_values_dotdot[0]);
555 if (_need_u_dot_old || _need_dof_values_dot_old)
557 libmesh_assert(_sys.solutionUDotOld());
558 _dof_values_dot_old.resize(n);
559 _sys.solutionUDotOld()->get(_dof_indices, &_dof_values_dot_old[0]);
561 if (_need_u_dotdot_old || _need_dof_values_dotdot_old)
563 libmesh_assert(_sys.solutionUDotDotOld());
564 _dof_values_dotdot_old.resize(n);
565 _sys.solutionUDotDotOld()->get(_dof_indices, &_dof_values_dotdot_old[0]);
567 if (_need_du_dot_du || _need_dof_du_dot_du)
569 _dof_du_dot_du.resize(n);
570 for (
decltype(n) i = 0; i < n; ++i)
571 _dof_du_dot_du[i] = _sys.duDotDu(_var.number());
573 if (_need_du_dotdot_du || _need_dof_du_dotdot_du)
575 _dof_du_dotdot_du.resize(n);
576 for (
decltype(n) i = 0; i < n; ++i)
577 _dof_du_dotdot_du[i] = _sys.duDotDotDu();
581 for (
auto tag : _required_vector_tags)
582 if (_need_vector_tag_u[tag] || _need_vector_tag_grad[tag] || _need_vector_tag_dof_u[tag])
584 _subproblem.safeAccessTaggedVectors()) ||
591 if (_sys.hasVector(tag) )
593 auto & vec = _sys.getVector(tag);
594 _vector_tags_dof_u[tag].resize(n);
595 vec.get(_dof_indices, &_vector_tags_dof_u[tag][0]);
599 if (_subproblem.safeAccessTaggedMatrices())
601 auto & active_coupleable_matrix_tags =
602 _subproblem.getActiveFEVariableCoupleableMatrixTags(_tid);
604 for (
auto tag : active_coupleable_matrix_tags)
606 if (_need_matrix_tag_dof_u[tag] || _need_matrix_tag_u[tag])
607 if (_sys.hasMatrix(tag) && _sys.matrixTagActive(tag))
609 mooseAssert(_sys.getMatrix(tag).closed(),
610 "Matrix with tag '" + std::to_string(tag) +
"' should be closed");
611 auto & mat = _sys.getMatrix(tag);
612 _matrix_tags_dof_u[tag].resize(n);
613 for (
unsigned i = 0; i < n; i++)
614 _matrix_tags_dof_u[tag][i] = mat(_dof_indices[i], _dof_indices[i]);
620template <
typename OutputType>
623 const unsigned int nshapes,
626 dof_values.
resize(nshapes);
627 for (
const auto i : make_range(nshapes))
629 dof_values[i].
resize(_count);
630 for (
const auto j : make_range(_count))
631 dof_values[i](j) = sol(_dof_indices[j * nshapes + i]);
639 bool is_transient = _subproblem.isTransient();
641 auto n = _dof_indices.size() / _count;
646 if (_need_u_dot || _need_grad_dot || _need_dof_values_dot)
648 libmesh_assert(_sys.solutionUDot());
649 getArrayDofValues(*_sys.solutionUDot(), n, _dof_values_dot);
651 if (_need_u_dotdot || _need_grad_dotdot || _need_dof_values_dotdot)
653 libmesh_assert(_sys.solutionUDotDot());
654 getArrayDofValues(*_sys.solutionUDot(), n, _dof_values_dotdot);
656 if (_need_u_dot_old || _need_dof_values_dot_old)
658 libmesh_assert(_sys.solutionUDotOld());
659 getArrayDofValues(*_sys.solutionUDotOld(), n, _dof_values_dot_old);
661 if (_need_u_dotdot_old || _need_dof_values_dotdot_old)
663 libmesh_assert(_sys.solutionUDotDotOld());
664 getArrayDofValues(*_sys.solutionUDotDotOld(), n, _dof_values_dotdot_old);
668 for (
auto tag : _required_vector_tags)
670 _subproblem.safeAccessTaggedVectors()) ||
673 if (_sys.hasVector(tag))
675 mooseAssert(_sys.getVector(tag).closed(),
676 "Vector with tag '" + std::to_string(tag) +
"' should be closed");
677 getArrayDofValues(_sys.getVector(tag), n, _vector_tags_dof_u[tag]);
680 if (_subproblem.safeAccessTaggedMatrices())
682 auto & active_coupleable_matrix_tags =
683 _subproblem.getActiveFEVariableCoupleableMatrixTags(_tid);
684 for (
auto tag : active_coupleable_matrix_tags)
686 _matrix_tags_dof_u[tag].resize(n);
687 if (_need_matrix_tag_dof_u[tag] || _need_matrix_tag_u[tag])
688 if (_sys.hasMatrix(tag) && _sys.matrixTagActive(tag))
690 mooseAssert(_sys.getMatrix(tag).closed(),
691 "Matrix with tag '" + std::to_string(tag) +
"' should be closed");
692 auto & mat = _sys.getMatrix(tag);
693 for (
unsigned i = 0; i < n; i++)
694 for (
unsigned j = 0; j < _count; j++)
695 _matrix_tags_dof_u[tag][i](j) = mat(_dof_indices[i] + j, _dof_indices[i] + j);
700 if (_need_du_dot_du || _need_dof_du_dot_du)
702 _dof_du_dot_du.resize(n);
703 for (
decltype(n) i = 0; i < n; ++i)
704 _dof_du_dot_du[i] = _sys.duDotDu(_var.number());
706 if (_need_du_dotdot_du || _need_dof_du_dotdot_du)
708 _dof_du_dotdot_du.resize(n);
709 for (
decltype(n) i = 0; i < n; ++i)
710 _dof_du_dotdot_du[i] = _sys.duDotDotDu();
714template <
typename OutputType>
718 if (_subproblem.isTransient())
720 _dof_values_dot.resize(0);
721 _dof_values_dotdot.resize(0);
722 _dof_values_dot_old.resize(0);
723 _dof_values_dotdot_old.resize(0);
724 _dof_du_dot_du.resize(0);
725 _dof_du_dotdot_du.resize(0);
728 for (
auto & dof_values : _vector_tags_dof_u)
729 dof_values.resize(0);
731 _has_dof_values =
false;
734template <
typename OutputType>
738 bool is_transient = _subproblem.isTransient();
739 libmesh_assert(_dof_indices.size());
741 auto & dof_values = _vector_tags_dof_u[_solution_tag];
742 _nodal_value = dof_values[0];
743 _nodal_value_array[0] = _nodal_value;
747 if (oldestSolutionStateRequested() >= 1)
749 _nodal_value_old = _vector_tags_dof_u[_old_solution_tag][0];
750 _nodal_value_old_array[0] = _nodal_value_old;
752 if (oldestSolutionStateRequested() >= 2)
754 _nodal_value_older = _vector_tags_dof_u[_older_solution_tag][0];
755 _nodal_value_older_array[0] = _nodal_value_older;
757 if (_need_dof_values_dot)
758 _nodal_value_dot = _dof_values_dot[0];
759 if (_need_dof_values_dotdot)
760 _nodal_value_dotdot = _dof_values_dotdot[0];
761 if (_need_dof_values_dot_old)
762 _nodal_value_dot_old = _dof_values_dot_old[0];
763 if (_need_dof_values_dotdot_old)
764 _nodal_value_dotdot_old = _dof_values_dotdot_old[0];
767 _nodal_value_previous_nl = _vector_tags_dof_u[_previous_nl_solution_tag][0];
774 bool is_transient = _subproblem.isTransient();
776 auto n = _dof_indices.size();
779 auto & dof_values = _vector_tags_dof_u[_solution_tag];
780 for (
decltype(n) i = 0; i < n; ++i)
781 _nodal_value(i) = dof_values[i];
782 _nodal_value_array[0] = _nodal_value;
786 if (oldestSolutionStateRequested() >= 1)
788 auto & dof_values_old = _vector_tags_dof_u[_old_solution_tag];
789 for (
decltype(n) i = 0; i < n; ++i)
790 _nodal_value_old(i) = dof_values_old[i];
791 _nodal_value_old_array[0] = _nodal_value_old;
793 if (oldestSolutionStateRequested() >= 2)
795 auto & dof_values_older = _vector_tags_dof_u[_older_solution_tag];
796 for (
decltype(n) i = 0; i < n; ++i)
797 _nodal_value_older(i) = dof_values_older[i];
798 _nodal_value_older_array[0] = _nodal_value_older;
800 if (_need_dof_values_dot)
801 for (
decltype(n) i = 0; i < n; ++i)
802 _nodal_value_dot(i) = _dof_values_dot[i];
803 if (_need_dof_values_dotdot)
804 for (
decltype(n) i = 0; i < n; ++i)
805 _nodal_value_dotdot(i) = _dof_values_dotdot[i];
806 if (_need_dof_values_dot_old)
807 for (
decltype(n) i = 0; i < n; ++i)
808 _nodal_value_dot_old(i) = _dof_values_dot_old[i];
809 if (_need_dof_values_dotdot_old)
810 for (
decltype(n) i = 0; i < n; ++i)
811 _nodal_value_dotdot_old(i) = _dof_values_dotdot_old[i];
815 auto & dof_values_previous_nl = _vector_tags_dof_u[_previous_nl_solution_tag];
816 for (
decltype(n) i = 0; i < n; ++i)
817 _nodal_value_previous_nl(i) = dof_values_previous_nl[i];
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
void resize(unsigned int size)
Change the number of elements the array can store.
MooseVariableDataBase(const MooseVariableField< OutputType > &var, SystemBase &sys, THREAD_ID tid)
void resizeVectorTagData(TagID tag)
resize the vector tag need flags and data containers to accomodate this tag index
std::vector< FieldVariableValue > _vector_tag_u
const FieldVariableValue & vectorTagValue(TagID tag) const
void insert(libMesh::NumericVector< libMesh::Number > &residual)
Set the current local DOF values to the input vector.
const DofValues & nodalMatrixTagValue(TagID tag) const
const DofValues & dofValuesOlder() const
void fetchDofValues()
Helper methods for assigning dof values from their corresponding solution values.
unsigned int oldestSolutionStateRequested() const
The oldest solution state that is requested for this variable (0 = current, 1 = old,...
const OutputType & nodalValue(Moose::SolutionState state) const
std::vector< DofValues > _vector_tags_dof_u
const MooseArray< OutputType > & nodalValueArray(Moose::SolutionState state) const
const FieldVariableValue & sln(Moose::SolutionState state) const
Local solution getter.
const DofValues & nodalVectorTagValue(TagID tag) const
void setNodalValue(const OutputType &value, unsigned int idx=0)
Set nodal value.
const DofValues & dofValuesPreviousNL() const
const FieldVariableGradient & gradSln(Moose::SolutionState state) const
Local solution gradient getter.
std::vector< bool > _need_vector_tag_u
const FieldVariableGradient & vectorTagGradient(TagID tag) const
MooseArray< OutputType > _nodal_value_old_array
std::vector< FieldVariableGradient > _vector_tag_grad
const DofValues & vectorTagDofValue(TagID tag) const
const DofValues & dofValuesOld() const
void getArrayDofValues(const libMesh::NumericVector< libMesh::Number > &sol, unsigned int n, MooseArray< RealEigenVector > &dof_values) const
void insertSolutionTag(TagID tag_id)
insert a solution tag into our tag containers
MooseArray< OutputType > _nodal_value_array
Nodal values as MooseArrays for use with AuxKernels.
void needSolutionState(unsigned int state)
Request that we have at least state number of older solution states/vectors.
const DofValues & dofValues() const
void sizeMatrixTagData()
size matrix tag data
std::vector< bool > _need_vector_tag_dof_u
const FieldVariableValue & matrixTagValue(TagID tag) const
const SubProblem & _subproblem
The subproblem which we can query for information related to tagged vectors and matrices.
MooseArray< OutputType > _nodal_value_older_array
void add(libMesh::NumericVector< libMesh::Number > &residual)
Add the current local DOF values to the input vector.
const ReturnType & stateToTagHelper(Moose::SolutionState state, Functor functor)
Helper method that converts a SolutionState argument into a corresponding tag ID, potentially request...
std::vector< bool > _need_vector_tag_grad
Class for stuff related to variables.
virtual TagID getVectorTagID(const TagName &tag_name) const
Get a TagID from a TagName.
virtual unsigned int numVectorTags(const Moose::VectorTagType type=Moose::VECTOR_TAG_ANY) const
The total number of tags, which can be limited to the tag type.
Base class for a system (of equations)
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
const TagID INVALID_TAG_ID
const TagName OLDER_SOLUTION_TAG
const TagName PREVIOUS_NL_SOLUTION_TAG
const TagName OLD_SOLUTION_TAG
const TagName SOLUTION_TAG