https://mooseframework.inl.gov
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 
10 #include "MooseVariableDataBase.h"
11 #include "MooseError.h"
12 #include "MooseTypes.h"
13 #include "SystemBase.h"
14 #include "SubProblem.h"
15 #include "MooseVariableField.h"
16 
17 template <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 
83 template <typename OutputType>
84 void
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 
96 template <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
110  mooseError(
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 
119 template <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
136  mooseError(
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 
145 template <typename OutputType>
146 void
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 
177 template <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 
194 template <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 
211 template <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 
228 template <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 
248 template <typename OutputType>
249 unsigned int
251 {
252  return _max_state;
253 }
254 
255 template <typename OutputType>
256 void
258 {
259  if (state > _max_state)
260  {
261  _sys.needSolutionState(state);
262  _max_state = state;
263  }
264 }
265 
266 template <typename OutputType>
267 template <typename ReturnType, typename Functor>
268 const 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 
298  case Moose::PreviousNL:
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 
312 template <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 
325 template <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 
338 template <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 
350 template <typename OutputType>
353 {
354  return vectorTagDofValue(Moose::Current);
355 }
356 
357 template <typename OutputType>
360 {
361  return vectorTagDofValue(Moose::Old);
362 }
363 
364 template <typename OutputType>
367 {
368  return vectorTagDofValue(Moose::Older);
369 }
370 
371 template <typename OutputType>
374 {
375  return vectorTagDofValue(Moose::PreviousNL);
376 }
377 
378 template <typename OutputType>
379 void
380 MooseVariableDataBase<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 
394 template <>
395 void
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 
407 template <typename OutputType>
408 void
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 
420 template <>
421 void
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 
439 template <typename OutputType>
440 void
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 
450 template <>
451 void
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 
469 template <typename OutputType>
470 const 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 
488  case Moose::PreviousNL:
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 
503 template <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 
532 template <typename OutputType>
533 void
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  }
568 
569  for (auto tag : _required_vector_tags)
570  if (_need_vector_tag_u[tag] || _need_vector_tag_grad[tag] || _need_vector_tag_dof_u[tag])
571  if ((_subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_RESIDUAL &&
572  _subproblem.safeAccessTaggedVectors()) ||
573  _subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_SOLUTION)
574  {
575  // tag is defined on problem but may not be used by a system
576  // the grain tracker requires being able to read from solution vectors that we are also in
577  // the process of writing :-/
578  // Note: the extra vector tags are also still not closed when a TagVectorAux uses them
579  if (_sys.hasVector(tag) /* && _sys.getVector(tag).closed()*/)
580  {
581  auto & vec = _sys.getVector(tag);
582  _vector_tags_dof_u[tag].resize(n);
583  vec.get(_dof_indices, &_vector_tags_dof_u[tag][0]);
584  }
585  }
586 
587  if (_subproblem.safeAccessTaggedMatrices())
588  {
589  auto & active_coupleable_matrix_tags =
590  _subproblem.getActiveFEVariableCoupleableMatrixTags(_tid);
591 
592  for (auto tag : active_coupleable_matrix_tags)
593  {
594  _matrix_tags_dof_u[tag].resize(n);
595  if (_need_matrix_tag_dof_u[tag] || _need_matrix_tag_u[tag])
596  if (_sys.hasMatrix(tag) && _sys.matrixTagActive(tag))
597  {
598  mooseAssert(_sys.getMatrix(tag).closed(),
599  "Matrix with tag '" + std::to_string(tag) + "' should be closed");
600  auto & mat = _sys.getMatrix(tag);
601  for (unsigned i = 0; i < n; i++)
602  _matrix_tags_dof_u[tag][i] = mat(_dof_indices[i], _dof_indices[i]);
603  }
604  }
605  }
606 
607  if (_need_du_dot_du || _need_dof_du_dot_du)
608  {
609  _dof_du_dot_du.resize(n);
610  for (decltype(n) i = 0; i < n; ++i)
611  _dof_du_dot_du[i] = _sys.duDotDu(_var.number());
612  }
613  if (_need_du_dotdot_du || _need_dof_du_dotdot_du)
614  {
615  _dof_du_dotdot_du.resize(n);
616  for (decltype(n) i = 0; i < n; ++i)
617  _dof_du_dotdot_du[i] = _sys.duDotDotDu();
618  }
619 }
620 
621 template <typename OutputType>
622 void
624  const unsigned int nshapes,
625  MooseArray<RealEigenVector> & dof_values) const
626 {
627  dof_values.resize(nshapes);
628  for (const auto i : make_range(nshapes))
629  {
630  dof_values[i].resize(_count);
631  for (const auto j : make_range(_count))
632  dof_values[i](j) = sol(_dof_indices[j * nshapes + i]);
633  }
634 }
635 
636 template <>
637 void
639 {
640  bool is_transient = _subproblem.isTransient();
641 
642  auto n = _dof_indices.size() / _count;
643  libmesh_assert(n);
644 
645  if (is_transient)
646  {
647  if (_need_u_dot || _need_grad_dot || _need_dof_values_dot)
648  {
649  libmesh_assert(_sys.solutionUDot());
650  getArrayDofValues(*_sys.solutionUDot(), n, _dof_values_dot);
651  }
652  if (_need_u_dotdot || _need_grad_dotdot || _need_dof_values_dotdot)
653  {
654  libmesh_assert(_sys.solutionUDotDot());
655  getArrayDofValues(*_sys.solutionUDot(), n, _dof_values_dotdot);
656  }
657  if (_need_u_dot_old || _need_dof_values_dot_old)
658  {
659  libmesh_assert(_sys.solutionUDotOld());
660  getArrayDofValues(*_sys.solutionUDotOld(), n, _dof_values_dot_old);
661  }
662  if (_need_u_dotdot_old || _need_dof_values_dotdot_old)
663  {
664  libmesh_assert(_sys.solutionUDotDotOld());
665  getArrayDofValues(*_sys.solutionUDotDotOld(), n, _dof_values_dotdot_old);
666  }
667  }
668 
669  for (auto tag : _required_vector_tags)
670  if ((_subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_RESIDUAL &&
671  _subproblem.safeAccessTaggedVectors()) ||
672  _subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_SOLUTION)
673  // tag is defined on problem but may not be used by a system
674  if (_sys.hasVector(tag))
675  {
676  mooseAssert(_sys.getVector(tag).closed(),
677  "Vector with tag '" + std::to_string(tag) + "' should be closed");
678  getArrayDofValues(_sys.getVector(tag), n, _vector_tags_dof_u[tag]);
679  }
680 
681  if (_subproblem.safeAccessTaggedMatrices())
682  {
683  auto & active_coupleable_matrix_tags =
684  _subproblem.getActiveFEVariableCoupleableMatrixTags(_tid);
685  for (auto tag : active_coupleable_matrix_tags)
686  {
687  _matrix_tags_dof_u[tag].resize(n);
688  if (_need_matrix_tag_dof_u[tag] || _need_matrix_tag_u[tag])
689  if (_sys.hasMatrix(tag) && _sys.matrixTagActive(tag))
690  {
691  mooseAssert(_sys.getMatrix(tag).closed(),
692  "Matrix with tag '" + std::to_string(tag) + "' should be closed");
693  auto & mat = _sys.getMatrix(tag);
694  for (unsigned i = 0; i < n; i++)
695  for (unsigned j = 0; j < _count; j++)
696  _matrix_tags_dof_u[tag][i](j) = mat(_dof_indices[i] + j, _dof_indices[i] + j);
697  }
698  }
699  }
700 
701  if (_need_du_dot_du || _need_dof_du_dot_du)
702  {
703  _dof_du_dot_du.resize(n);
704  for (decltype(n) i = 0; i < n; ++i)
705  _dof_du_dot_du[i] = _sys.duDotDu(_var.number());
706  }
707  if (_need_du_dotdot_du || _need_dof_du_dotdot_du)
708  {
709  _dof_du_dotdot_du.resize(n);
710  for (decltype(n) i = 0; i < n; ++i)
711  _dof_du_dotdot_du[i] = _sys.duDotDotDu();
712  }
713 }
714 
715 template <typename OutputType>
716 void
718 {
719  if (_subproblem.isTransient())
720  {
721  _dof_values_dot.resize(0);
722  _dof_values_dotdot.resize(0);
723  _dof_values_dot_old.resize(0);
724  _dof_values_dotdot_old.resize(0);
725  _dof_du_dot_du.resize(0);
726  _dof_du_dotdot_du.resize(0);
727  }
728 
729  for (auto & dof_values : _vector_tags_dof_u)
730  dof_values.resize(0);
731 
732  _has_dof_values = false;
733 }
734 
735 template <typename OutputType>
736 void
738 {
739  bool is_transient = _subproblem.isTransient();
740  libmesh_assert(_dof_indices.size());
741 
742  auto & dof_values = _vector_tags_dof_u[_solution_tag];
743  _nodal_value = dof_values[0];
744  _nodal_value_array[0] = _nodal_value;
745 
746  if (is_transient)
747  {
748  if (oldestSolutionStateRequested() >= 1)
749  {
750  _nodal_value_old = _vector_tags_dof_u[_old_solution_tag][0];
751  _nodal_value_old_array[0] = _nodal_value_old;
752  }
753  if (oldestSolutionStateRequested() >= 2)
754  {
755  _nodal_value_older = _vector_tags_dof_u[_older_solution_tag][0];
756  _nodal_value_older_array[0] = _nodal_value_older;
757  }
758  if (_need_dof_values_dot)
759  _nodal_value_dot = _dof_values_dot[0];
760  if (_need_dof_values_dotdot)
761  _nodal_value_dotdot = _dof_values_dotdot[0];
762  if (_need_dof_values_dot_old)
763  _nodal_value_dot_old = _dof_values_dot_old[0];
764  if (_need_dof_values_dotdot_old)
765  _nodal_value_dotdot_old = _dof_values_dotdot_old[0];
766  }
767  if (_previous_nl_solution_tag != Moose::INVALID_TAG_ID)
768  _nodal_value_previous_nl = _vector_tags_dof_u[_previous_nl_solution_tag][0];
769 }
770 
771 template <>
772 void
774 {
775  bool is_transient = _subproblem.isTransient();
776 
777  auto n = _dof_indices.size();
778  libmesh_assert(n);
779 
780  auto & dof_values = _vector_tags_dof_u[_solution_tag];
781  for (decltype(n) i = 0; i < n; ++i)
782  _nodal_value(i) = dof_values[i];
783  _nodal_value_array[0] = _nodal_value;
784 
785  if (is_transient)
786  {
787  if (oldestSolutionStateRequested() >= 1)
788  {
789  auto & dof_values_old = _vector_tags_dof_u[_old_solution_tag];
790  for (decltype(n) i = 0; i < n; ++i)
791  _nodal_value_old(i) = dof_values_old[i];
792  _nodal_value_old_array[0] = _nodal_value_old;
793  }
794  if (oldestSolutionStateRequested() >= 2)
795  {
796  auto & dof_values_older = _vector_tags_dof_u[_older_solution_tag];
797  for (decltype(n) i = 0; i < n; ++i)
798  _nodal_value_older(i) = dof_values_older[i];
799  _nodal_value_older_array[0] = _nodal_value_older;
800  }
801  if (_need_dof_values_dot)
802  for (decltype(n) i = 0; i < n; ++i)
803  _nodal_value_dot(i) = _dof_values_dot[i];
804  if (_need_dof_values_dotdot)
805  for (decltype(n) i = 0; i < n; ++i)
806  _nodal_value_dotdot(i) = _dof_values_dotdot[i];
807  if (_need_dof_values_dot_old)
808  for (decltype(n) i = 0; i < n; ++i)
809  _nodal_value_dot_old(i) = _dof_values_dot_old[i];
810  if (_need_dof_values_dotdot_old)
811  for (decltype(n) i = 0; i < n; ++i)
812  _nodal_value_dotdot_old(i) = _dof_values_dotdot_old[i];
813  }
814  if (_previous_nl_solution_tag != Moose::INVALID_TAG_ID)
815  {
816  auto & dof_values_previous_nl = _vector_tags_dof_u[_previous_nl_solution_tag];
817  for (decltype(n) i = 0; i < n; ++i)
818  _nodal_value_previous_nl(i) = dof_values_previous_nl[i];
819  }
820 }
821 
822 template class MooseVariableDataBase<Real>;
virtual TagID getVectorTagID(const TagName &tag_name) const
Get a TagID from a TagName.
Definition: SubProblem.C:204
virtual void insert(const Number *v, const std::vector< numeric_index_type > &dof_indices)
unsigned int TagID
Definition: MooseTypes.h:238
void resizeVectorTagData(TagID tag)
resize the vector tag need flags and data containers to accomodate this tag index ...
const FieldVariableValue & matrixTagValue(TagID tag) const
Class for stuff related to variables.
const ReturnType & stateToTagHelper(Moose::SolutionState state, Functor functor)
Helper method that converts a SolutionState argument into a corresponding tag ID, potentially request...
void sizeMatrixTagData()
size matrix tag data
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:311
const FieldVariableGradient & vectorTagGradient(TagID tag) const
const TagName OLDER_SOLUTION_TAG
Definition: MooseTypes.C:27
virtual void add_vector(const Number *v, const std::vector< numeric_index_type > &dof_indices)
const DofValues & nodalVectorTagValue(TagID tag) const
const MooseArray< OutputType > & nodalValueArray(Moose::SolutionState state) const
std::vector< bool > _need_vector_tag_u
void getArrayDofValues(const libMesh::NumericVector< libMesh::Number > &sol, unsigned int n, MooseArray< RealEigenVector > &dof_values) const
const SubProblem & _subproblem
The subproblem which we can query for information related to tagged vectors and matrices.
Base class for a system (of equations)
Definition: SystemBase.h:85
std::vector< bool > _need_vector_tag_grad
const DofValues & vectorTagDofValue(TagID tag) const
std::vector< bool > _need_vector_tag_dof_u
void add(libMesh::NumericVector< libMesh::Number > &residual)
Add the current local DOF values to the input vector.
void setNodalValue(const OutputType &value, unsigned int idx=0)
Set nodal value.
void insert(libMesh::NumericVector< libMesh::Number > &residual)
Set the current local DOF values to the input vector.
const FieldVariableGradient & gradSln(Moose::SolutionState state) const
Local solution gradient getter.
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
FunctorEnvelope< T > Functor
const TagName OLD_SOLUTION_TAG
Definition: MooseTypes.C:26
MooseArray< OutputType > _nodal_value_array
Nodal values as MooseArrays for use with AuxKernels.
libmesh_assert(ctx)
const OutputType & nodalValue(Moose::SolutionState state) const
const DofValues & nodalMatrixTagValue(TagID tag) const
void insertSolutionTag(TagID tag_id)
insert a solution tag into our tag containers
std::vector< DofValues > _vector_tags_dof_u
MooseVariableDataBase(const MooseVariableField< OutputType > &var, SystemBase &sys, THREAD_ID tid)
const DofValues & dofValuesOlder() const
MooseArray< OutputType > _nodal_value_old_array
const FieldVariableValue & vectorTagValue(TagID tag) const
void fetchDofValues()
Helper methods for assigning dof values from their corresponding solution values. ...
const TagID INVALID_TAG_ID
Definition: MooseTypes.C:23
const DofValues & dofValuesPreviousNL() const
SolutionState
Definition: MooseTypes.h:261
std::vector< FieldVariableGradient > _vector_tag_grad
IntRange< T > make_range(T beg, T end)
void resize(unsigned int size)
Change the number of elements the array can store.
Definition: MooseArray.h:216
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
const FieldVariableValue & sln(Moose::SolutionState state) const
Local solution getter.
const TagName SOLUTION_TAG
Definition: MooseTypes.C:25
MooseArray< OutputType > _nodal_value_older_array
virtual void set(const numeric_index_type i, const Number value)=0
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
void needSolutionState(unsigned int state)
Request that we have at least state number of older solution states/vectors.
std::vector< FieldVariableValue > _vector_tag_u
virtual void add(const numeric_index_type i, const Number value)=0
const DofValues & dofValuesOld() const
const TagName PREVIOUS_NL_SOLUTION_TAG
Definition: MooseTypes.C:28
auto index_range(const T &sizable)
unsigned int oldestSolutionStateRequested() const
The oldest solution state that is requested for this variable (0 = current, 1 = old, 2 = older, etc).
unsigned int THREAD_ID
Definition: MooseTypes.h:237
unsigned int idx(const ElemType type, const unsigned int nx, const unsigned int i, const unsigned int j)
const DofValues & dofValues() const