https://mooseframework.inl.gov
Loading...
Searching...
No Matches
MooseVariableDataBase.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
11#include "MooseError.h"
12#include "MooseTypes.h"
13#include "SystemBase.h"
14#include "SubProblem.h"
15#include "MooseVariableField.h"
16
17template <typename OutputType>
19 SystemBase & sys,
20 THREAD_ID tid)
21 : _sys(sys),
22 _subproblem(_sys.subproblem()),
23 _tid(tid),
24 _dof_map(_sys.dofMap()),
25 _count(var.count()),
26 _has_dof_values(false),
27 _max_state(0),
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),
32 _need_u_dot(false),
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),
46 _var(var)
47{
48 auto num_vector_tags = _subproblem.numVectorTags();
49 // Additional solution tags corresponding to older-than-current solution states may be requested
50 // on-the-fly by consumer objects after variable construction. To accomodate this we should
51 // reserve the possibly requisite memory. As of now we only support old and older solution states
52 // but this could potentially increase in the future
53 const auto max_future_num_vector_tags = num_vector_tags + 2;
54
55 _vector_tags_dof_u.reserve(max_future_num_vector_tags);
56 _vector_tags_dof_u.resize(num_vector_tags);
57 _need_vector_tag_dof_u.reserve(max_future_num_vector_tags);
58 _need_vector_tag_dof_u.resize(num_vector_tags, false);
59
60 _need_vector_tag_u.reserve(max_future_num_vector_tags);
61 _need_vector_tag_u.resize(num_vector_tags, false);
62 _vector_tag_u.reserve(max_future_num_vector_tags);
63 _vector_tag_u.resize(num_vector_tags);
64
65 _need_vector_tag_grad.reserve(max_future_num_vector_tags);
66 _need_vector_tag_grad.resize(num_vector_tags, false);
67 _vector_tag_grad.reserve(max_future_num_vector_tags);
68 _vector_tag_grad.resize(num_vector_tags);
69
70 // Always fetch the dof values for the solution tag
71 const auto soln_tag = _subproblem.getVectorTagID(Moose::SOLUTION_TAG);
72 _need_vector_tag_dof_u[soln_tag] = true;
73 _need_vector_tag_u[soln_tag] = true;
74 insertSolutionTag(soln_tag);
75
76 // These MooseArray objects are used by AuxKernelBase for nodal AuxKernel objects, hence the size
77 // size is always 1 (i.e, nodal kernels work with _qp=0 only).
81}
82
83template <typename OutputType>
84void
86{
87 auto num_matrix_tags = _subproblem.numMatrixTags();
88
89 _matrix_tags_dof_u.resize(num_matrix_tags);
90 _need_matrix_tag_dof_u.resize(num_matrix_tags, false);
91
92 _need_matrix_tag_u.resize(num_matrix_tags, false);
93 _matrix_tag_u.resize(num_matrix_tags);
94}
95
96template <typename OutputType>
99{
100 if (isNodal())
101 {
102 if (tag >= _need_vector_tag_dof_u.size())
103 const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
104
105 _need_vector_tag_dof_u[tag] = true;
106
107 if (_sys.hasVector(tag))
108 return _vector_tags_dof_u[tag];
109 else
111 "Tag ", tag, " is not associated with any vector for nodal variable ", _var.name());
112 }
113 else
114 mooseError("Nodal values can be requested only on nodal variables, variable '",
115 _var.name(),
116 "' is not nodal.");
117}
118
119template <typename OutputType>
122{
123 if (isNodal())
124 {
125 if (tag >= _matrix_tags_dof_u.size())
126 {
127 _need_matrix_tag_dof_u.resize(tag + 1, false);
128 const_cast<MooseVariableDataBase<OutputType> *>(this)->_matrix_tags_dof_u.resize(tag + 1);
129 }
130
131 _need_matrix_tag_dof_u[tag] = true;
132
133 if (_sys.hasMatrix(tag))
134 return _matrix_tags_dof_u[tag];
135 else
137 "Tag ", tag, " is not associated with any matrix for nodal variable ", _var.name());
138 }
139 else
140 mooseError("Nodal values can be requested only on nodal variables, variable '",
141 _var.name(),
142 "' is not nodal.");
143}
144
145template <typename OutputType>
146void
148{
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.");
155
156 auto check_capacity = [tag](const auto & vector_to_check)
157 {
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.");
161 };
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);
168
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);
175}
176
177template <typename OutputType>
180{
181 if (tag >= _need_vector_tag_u.size())
182 const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
183
184 _var.requireQpComputations();
185
186 _need_vector_tag_u[tag] = true;
187
188 if (_sys.hasVector(tag))
189 return _vector_tag_u[tag];
190 else
191 mooseError("Tag ", tag, " is not associated with any vector for variable ", _var.name());
192}
193
194template <typename OutputType>
197{
198 if (tag >= _need_vector_tag_dof_u.size())
199 const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
200
201 _var.requireQpComputations();
202
203 _need_vector_tag_dof_u[tag] = true;
204
205 if (_sys.hasVector(tag))
206 return _vector_tags_dof_u[tag];
207 else
208 mooseError("Tag ", tag, " is not associated with any vector for variable ", _var.name());
209}
210
211template <typename OutputType>
214{
215 if (tag >= _need_vector_tag_grad.size())
216 const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
217
218 _var.requireQpComputations();
219
220 _need_vector_tag_grad[tag] = true;
221
222 if (_sys.hasVector(tag))
223 return _vector_tag_grad[tag];
224 else
225 mooseError("Tag ", tag, " is not associated with any vector for variable ", _var.name());
226}
227
228template <typename OutputType>
231{
232 if (tag >= _matrix_tag_u.size())
233 {
234 _need_matrix_tag_u.resize(tag + 1, false);
235 const_cast<MooseVariableDataBase<OutputType> *>(this)->_matrix_tag_u.resize(tag + 1);
236 }
237
238 _var.requireQpComputations();
239
240 _need_matrix_tag_u[tag] = true;
241
242 if (_sys.hasMatrix(tag))
243 return _matrix_tag_u[tag];
244 else
245 mooseError("Tag ", tag, " is not associated with any matrix for variable ", _var.name());
246}
247
248template <typename OutputType>
249unsigned int
254
255template <typename OutputType>
256void
258{
259 if (state > _max_state)
260 {
261 _sys.needSolutionState(state);
262 _max_state = state;
263 }
264}
265
266template <typename OutputType>
267template <typename ReturnType, typename Functor>
268const ReturnType &
270 Functor functor)
271{
272 if (state > 0)
273 {
274 // We need to request all states that are between current and the requested state
275 stateToTagHelper<ReturnType>(Moose::SolutionState(static_cast<int>(state) - 1), functor);
276 needSolutionState(cast_int<unsigned int>(state));
277 }
278
279 switch (state)
280 {
281 case Moose::Current:
282 return functor(_subproblem.getVectorTagID(Moose::SOLUTION_TAG));
283
284 case Moose::Old:
285 {
286 _old_solution_tag = _subproblem.getVectorTagID(Moose::OLD_SOLUTION_TAG);
287 insertSolutionTag(_old_solution_tag);
288 return functor(_old_solution_tag);
289 }
290
291 case Moose::Older:
292 {
293 _older_solution_tag = _subproblem.getVectorTagID(Moose::OLDER_SOLUTION_TAG);
294 insertSolutionTag(_older_solution_tag);
295 return functor(_older_solution_tag);
296 }
297
299 {
300 _previous_nl_solution_tag = _subproblem.getVectorTagID(Moose::PREVIOUS_NL_SOLUTION_TAG);
301 insertSolutionTag(_previous_nl_solution_tag);
302 return functor(_previous_nl_solution_tag);
303 }
304
305 default:
306 // We should never get here but gcc requires that we have a default. See
307 // htpps://stackoverflow.com/questions/18680378/after-defining-case-for-all-enum-values-compiler-still-says-control-reaches-e
308 mooseError("Unknown SolutionState!");
309 }
310}
311
312template <typename OutputType>
315{
316 auto functor = [this](TagID tag_id) -> const FieldVariableValue &
317 { return vectorTagValue(tag_id); };
318
319 _var.requireQpComputations();
320
321 return const_cast<MooseVariableDataBase<OutputType> *>(this)
322 ->stateToTagHelper<FieldVariableValue>(state, functor);
323}
324
325template <typename OutputType>
328{
329 auto functor = [this](TagID tag_id) -> const FieldVariableGradient &
330 { return vectorTagGradient(tag_id); };
331
332 _var.requireQpComputations();
333
334 return const_cast<MooseVariableDataBase<OutputType> *>(this)
335 ->stateToTagHelper<FieldVariableGradient>(state, functor);
336}
337
338template <typename OutputType>
341{
342 auto functor = [this](TagID tag_id) -> const DofValues & { return vectorTagDofValue(tag_id); };
343
344 _var.requireQpComputations();
345
346 return const_cast<MooseVariableDataBase<OutputType> *>(this)->stateToTagHelper<DofValues>(
347 state, functor);
348}
349
350template <typename OutputType>
353{
354 return vectorTagDofValue(Moose::Current);
355}
356
357template <typename OutputType>
360{
361 return vectorTagDofValue(Moose::Old);
362}
363
364template <typename OutputType>
367{
368 return vectorTagDofValue(Moose::Older);
369}
370
371template <typename OutputType>
374{
375 return vectorTagDofValue(Moose::PreviousNL);
376}
377
378template <typename OutputType>
379void
380MooseVariableDataBase<OutputType>::setNodalValue(const OutputType & value, unsigned int idx)
381{
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; // update variable nodal value
385 _has_dof_values = true;
386 _nodal_value = value;
387
388 // Update the qp values as well
389 auto & u = _vector_tag_u[_solution_tag];
390 for (unsigned int qp = 0; qp < u.size(); qp++)
391 u[qp] = value;
392}
393
394template <>
395void
397 unsigned int idx)
398{
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);
402
403 _has_dof_values = true;
404 _nodal_value = value;
405}
406
407template <typename OutputType>
408void
409MooseVariableDataBase<OutputType>::insert(NumericVector<Number> & residual)
410{
411 if (_has_dof_values)
412 {
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);
417 }
418}
419
420template <>
421void
422MooseVariableDataBase<RealEigenVector>::insert(NumericVector<Number> & residual)
423{
424 if (_has_dof_values)
425 {
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))
431 {
432 const auto i = indx % n_shapes;
433 const auto j = indx / n_shapes;
434 residual.set(_dof_indices[indx], dof_values[i](j));
435 }
436 }
437}
438
439template <typename OutputType>
440void
441MooseVariableDataBase<OutputType>::add(NumericVector<Number> & residual)
442{
443 if (_has_dof_values)
444 {
445 const auto & dof_values = _vector_tags_dof_u[_solution_tag];
446 residual.add_vector(&dof_values[0], _dof_indices);
447 }
448}
449
450template <>
451void
452MooseVariableDataBase<RealEigenVector>::add(NumericVector<Number> & residual)
453{
454 if (_has_dof_values)
455 {
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))
461 {
462 const auto i = indx % n_shapes;
463 const auto j = indx / n_shapes;
464 residual.add(_dof_indices[indx], dof_values[i](j));
465 }
466 }
467}
468
469template <typename OutputType>
470const OutputType &
472{
473 if (isNodal())
474 {
475 // Request the correct solution states and data members
476 vectorTagDofValue(state);
477 switch (state)
478 {
479 case Moose::Current:
480 return _nodal_value;
481
482 case Moose::Old:
483 return _nodal_value_old;
484
485 case Moose::Older:
486 return _nodal_value_older;
487
489 return _nodal_value_previous_nl;
490
491 default:
492 // We should never get here but gcc requires that we have a default. See
493 // htpps://stackoverflow.com/questions/18680378/after-defining-case-for-all-enum-values-compiler-still-says-control-reaches-e
494 mooseError("Unknown SolutionState!");
495 }
496 }
497 else
498 mooseError("Nodal values can be requested only on nodal variables, variable '",
499 _var.name(),
500 "' is not nodal.");
501}
502
503template <typename OutputType>
506{
507 if (isNodal())
508 {
509 // Request the correct solution states and data members
510 vectorTagDofValue(state);
511 switch (state)
512 {
513 case Moose::Current:
514 return _nodal_value_array;
515
516 case Moose::Old:
517 return _nodal_value_old_array;
518
519 case Moose::Older:
520 return _nodal_value_older_array;
521
522 default:
523 mooseError("No current support for PreviousNL for nodal value array");
524 }
525 }
526 else
527 mooseError("Nodal values can be requested only on nodal variables, variable '",
528 _var.name(),
529 "' is not nodal.");
530}
531
532template <typename OutputType>
533void
535{
536 bool is_transient = _subproblem.isTransient();
537
538 auto n = _dof_indices.size();
539 libmesh_assert(n);
540
541 if (is_transient)
542 {
543 if (_need_u_dot || _need_grad_dot || _need_dof_values_dot)
544 {
545 libmesh_assert(_sys.solutionUDot());
546 _dof_values_dot.resize(n);
547 _sys.solutionUDot()->get(_dof_indices, &_dof_values_dot[0]);
548 }
549 if (_need_u_dotdot || _need_grad_dotdot || _need_dof_values_dotdot)
550 {
551 libmesh_assert(_sys.solutionUDotDot());
552 _dof_values_dotdot.resize(n);
553 _sys.solutionUDotDot()->get(_dof_indices, &_dof_values_dotdot[0]);
554 }
555 if (_need_u_dot_old || _need_dof_values_dot_old)
556 {
557 libmesh_assert(_sys.solutionUDotOld());
558 _dof_values_dot_old.resize(n);
559 _sys.solutionUDotOld()->get(_dof_indices, &_dof_values_dot_old[0]);
560 }
561 if (_need_u_dotdot_old || _need_dof_values_dotdot_old)
562 {
563 libmesh_assert(_sys.solutionUDotDotOld());
564 _dof_values_dotdot_old.resize(n);
565 _sys.solutionUDotDotOld()->get(_dof_indices, &_dof_values_dotdot_old[0]);
566 }
567 if (_need_du_dot_du || _need_dof_du_dot_du)
568 {
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());
572 }
573 if (_need_du_dotdot_du || _need_dof_du_dotdot_du)
574 {
575 _dof_du_dotdot_du.resize(n);
576 for (decltype(n) i = 0; i < n; ++i)
577 _dof_du_dotdot_du[i] = _sys.duDotDotDu();
578 }
579 }
580
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])
583 if ((_subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_RESIDUAL &&
584 _subproblem.safeAccessTaggedVectors()) ||
585 _subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_SOLUTION)
586 {
587 // tag is defined on problem but may not be used by a system
588 // the grain tracker requires being able to read from solution vectors that we are also in
589 // the process of writing :-/
590 // Note: the extra vector tags are also still not closed when a TagVectorAux uses them
591 if (_sys.hasVector(tag) /* && _sys.getVector(tag).closed()*/)
592 {
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]);
596 }
597 }
598
599 if (_subproblem.safeAccessTaggedMatrices())
600 {
601 auto & active_coupleable_matrix_tags =
602 _subproblem.getActiveFEVariableCoupleableMatrixTags(_tid);
603
604 for (auto tag : active_coupleable_matrix_tags)
605 {
606 if (_need_matrix_tag_dof_u[tag] || _need_matrix_tag_u[tag])
607 if (_sys.hasMatrix(tag) && _sys.matrixTagActive(tag))
608 {
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]);
615 }
616 }
617 }
618}
619
620template <typename OutputType>
621void
623 const unsigned int nshapes,
624 MooseArray<RealEigenVector> & dof_values) const
625{
626 dof_values.resize(nshapes);
627 for (const auto i : make_range(nshapes))
628 {
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]);
632 }
633}
634
635template <>
636void
638{
639 bool is_transient = _subproblem.isTransient();
640
641 auto n = _dof_indices.size() / _count;
642 libmesh_assert(n);
643
644 if (is_transient)
645 {
646 if (_need_u_dot || _need_grad_dot || _need_dof_values_dot)
647 {
648 libmesh_assert(_sys.solutionUDot());
649 getArrayDofValues(*_sys.solutionUDot(), n, _dof_values_dot);
650 }
651 if (_need_u_dotdot || _need_grad_dotdot || _need_dof_values_dotdot)
652 {
653 libmesh_assert(_sys.solutionUDotDot());
654 getArrayDofValues(*_sys.solutionUDot(), n, _dof_values_dotdot);
655 }
656 if (_need_u_dot_old || _need_dof_values_dot_old)
657 {
658 libmesh_assert(_sys.solutionUDotOld());
659 getArrayDofValues(*_sys.solutionUDotOld(), n, _dof_values_dot_old);
660 }
661 if (_need_u_dotdot_old || _need_dof_values_dotdot_old)
662 {
663 libmesh_assert(_sys.solutionUDotDotOld());
664 getArrayDofValues(*_sys.solutionUDotDotOld(), n, _dof_values_dotdot_old);
665 }
666 }
667
668 for (auto tag : _required_vector_tags)
669 if ((_subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_RESIDUAL &&
670 _subproblem.safeAccessTaggedVectors()) ||
671 _subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_SOLUTION)
672 // tag is defined on problem but may not be used by a system
673 if (_sys.hasVector(tag))
674 {
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]);
678 }
679
680 if (_subproblem.safeAccessTaggedMatrices())
681 {
682 auto & active_coupleable_matrix_tags =
683 _subproblem.getActiveFEVariableCoupleableMatrixTags(_tid);
684 for (auto tag : active_coupleable_matrix_tags)
685 {
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))
689 {
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);
696 }
697 }
698 }
699
700 if (_need_du_dot_du || _need_dof_du_dot_du)
701 {
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());
705 }
706 if (_need_du_dotdot_du || _need_dof_du_dotdot_du)
707 {
708 _dof_du_dotdot_du.resize(n);
709 for (decltype(n) i = 0; i < n; ++i)
710 _dof_du_dotdot_du[i] = _sys.duDotDotDu();
711 }
712}
713
714template <typename OutputType>
715void
717{
718 if (_subproblem.isTransient())
719 {
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);
726 }
727
728 for (auto & dof_values : _vector_tags_dof_u)
729 dof_values.resize(0);
730
731 _has_dof_values = false;
732}
733
734template <typename OutputType>
735void
737{
738 bool is_transient = _subproblem.isTransient();
739 libmesh_assert(_dof_indices.size());
740
741 auto & dof_values = _vector_tags_dof_u[_solution_tag];
742 _nodal_value = dof_values[0];
743 _nodal_value_array[0] = _nodal_value;
744
745 if (is_transient)
746 {
747 if (oldestSolutionStateRequested() >= 1)
748 {
749 _nodal_value_old = _vector_tags_dof_u[_old_solution_tag][0];
750 _nodal_value_old_array[0] = _nodal_value_old;
751 }
752 if (oldestSolutionStateRequested() >= 2)
753 {
754 _nodal_value_older = _vector_tags_dof_u[_older_solution_tag][0];
755 _nodal_value_older_array[0] = _nodal_value_older;
756 }
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];
765 }
766 if (_previous_nl_solution_tag != Moose::INVALID_TAG_ID)
767 _nodal_value_previous_nl = _vector_tags_dof_u[_previous_nl_solution_tag][0];
768}
769
770template <>
771void
773{
774 bool is_transient = _subproblem.isTransient();
775
776 auto n = _dof_indices.size();
777 libmesh_assert(n);
778
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;
783
784 if (is_transient)
785 {
786 if (oldestSolutionStateRequested() >= 1)
787 {
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;
792 }
793 if (oldestSolutionStateRequested() >= 2)
794 {
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;
799 }
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];
812 }
813 if (_previous_nl_solution_tag != Moose::INVALID_TAG_ID)
814 {
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];
818 }
819}
820
821template class MooseVariableDataBase<Real>;
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
unsigned int TagID
Definition MooseTypes.h:238
unsigned int THREAD_ID
Definition MooseTypes.h:237
unsigned int count
Definition MortarUtils.C:53
void resize(unsigned int size)
Change the number of elements the array can store.
Definition MooseArray.h:216
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.
Definition SubProblem.C:204
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.
Definition SubProblem.C:196
Base class for a system (of equations)
Definition SystemBase.h:87
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
Definition MooseTypes.C:23
const TagName OLDER_SOLUTION_TAG
Definition MooseTypes.C:27
@ VECTOR_TAG_SOLUTION
@ VECTOR_TAG_RESIDUAL
const TagName PREVIOUS_NL_SOLUTION_TAG
Definition MooseTypes.C:28
SolutionState
Definition MooseTypes.h:262
@ Current
Definition MooseTypes.h:263
@ PreviousNL
Definition MooseTypes.h:266
const TagName OLD_SOLUTION_TAG
Definition MooseTypes.C:26
const TagName SOLUTION_TAG
Definition MooseTypes.C:25