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  auto num_matrix_tags = _subproblem.numMatrixTags();
71 
72  _matrix_tags_dof_u.resize(num_matrix_tags);
73  _need_matrix_tag_dof_u.resize(num_matrix_tags, false);
74 
75  _need_matrix_tag_u.resize(num_matrix_tags, false);
76  _matrix_tag_u.resize(num_matrix_tags);
77 
78  // Always fetch the dof values for the solution tag
79  const auto soln_tag = _subproblem.getVectorTagID(Moose::SOLUTION_TAG);
80  _need_vector_tag_dof_u[soln_tag] = true;
81  _need_vector_tag_u[soln_tag] = true;
82  insertSolutionTag(soln_tag);
83 
84  // These MooseArray objects are used by AuxKernelBase for nodal AuxKernel objects, hence the size
85  // size is always 1 (i.e, nodal kernels work with _qp=0 only).
89 }
90 
91 template <typename OutputType>
94 {
95  if (isNodal())
96  {
97  if (tag >= _need_vector_tag_dof_u.size())
99 
100  _need_vector_tag_dof_u[tag] = true;
101 
102  if (_sys.hasVector(tag))
103  return _vector_tags_dof_u[tag];
104  else
105  mooseError(
106  "Tag ", tag, " is not associated with any vector for nodal variable ", _var.name());
107  }
108  else
109  mooseError("Nodal values can be requested only on nodal variables, variable '",
110  _var.name(),
111  "' is not nodal.");
112 }
113 
114 template <typename OutputType>
117 {
118  if (isNodal())
119  {
120  if (tag >= _matrix_tags_dof_u.size())
121  {
122  _need_matrix_tag_dof_u.resize(tag + 1, false);
123  const_cast<MooseVariableDataBase<OutputType> *>(this)->_matrix_tags_dof_u.resize(tag + 1);
124  }
125 
126  _need_matrix_tag_dof_u[tag] = true;
127 
128  if (_sys.hasMatrix(tag))
129  return _matrix_tags_dof_u[tag];
130  else
131  mooseError(
132  "Tag ", tag, " is not associated with any matrix for nodal variable ", _var.name());
133  }
134  else
135  mooseError("Nodal values can be requested only on nodal variables, variable '",
136  _var.name(),
137  "' is not nodal.");
138 }
139 
140 template <typename OutputType>
141 void
143 {
144  mooseAssert(_need_vector_tag_dof_u.size() == _need_vector_tag_u.size() &&
145  _need_vector_tag_dof_u.size() == _need_vector_tag_grad.size() &&
146  _need_vector_tag_dof_u.size() == _vector_tags_dof_u.size() &&
147  _need_vector_tag_dof_u.size() == _vector_tag_u.size() &&
148  _need_vector_tag_dof_u.size() == _vector_tag_grad.size(),
149  "These sizes should be in sync.");
150 
151  auto check_capacity = [tag](const auto & vector_to_check)
152  {
153  if (tag + 1 > vector_to_check.capacity())
154  mooseError("New size greater than tag capacity. This will cause reallocation which will "
155  "invalidate any stored references.");
156  };
157  check_capacity(_need_vector_tag_dof_u);
158  check_capacity(_need_vector_tag_u);
159  check_capacity(_need_vector_tag_grad);
160  check_capacity(_vector_tags_dof_u);
161  check_capacity(_vector_tag_u);
162  check_capacity(_vector_tag_grad);
163 
164  _need_vector_tag_dof_u.resize(tag + 1, false);
165  _need_vector_tag_u.resize(tag + 1, false);
166  _need_vector_tag_grad.resize(tag + 1, false);
167  _vector_tags_dof_u.resize(tag + 1);
168  _vector_tag_u.resize(tag + 1);
169  _vector_tag_grad.resize(tag + 1);
170 }
171 
172 template <typename OutputType>
175 {
176  if (tag >= _need_vector_tag_u.size())
177  const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
178 
179  _need_vector_tag_u[tag] = true;
180 
181  if (_sys.hasVector(tag))
182  return _vector_tag_u[tag];
183  else
184  mooseError("Tag ", tag, " is not associated with any vector for variable ", _var.name());
185 }
186 
187 template <typename OutputType>
190 {
191  if (tag >= _need_vector_tag_dof_u.size())
192  const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
193 
194  _need_vector_tag_dof_u[tag] = true;
195 
196  if (_sys.hasVector(tag))
197  return _vector_tags_dof_u[tag];
198  else
199  mooseError("Tag ", tag, " is not associated with any vector for variable ", _var.name());
200 }
201 
202 template <typename OutputType>
205 {
206  if (tag >= _need_vector_tag_grad.size())
207  const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
208 
209  _need_vector_tag_grad[tag] = true;
210 
211  if (_sys.hasVector(tag))
212  return _vector_tag_grad[tag];
213  else
214  mooseError("Tag ", tag, " is not associated with any vector for variable ", _var.name());
215 }
216 
217 template <typename OutputType>
220 {
221  if (tag >= _matrix_tag_u.size())
222  {
223  _need_matrix_tag_u.resize(tag + 1, false);
224  const_cast<MooseVariableDataBase<OutputType> *>(this)->_matrix_tag_u.resize(tag + 1);
225  }
226 
227  _need_matrix_tag_u[tag] = true;
228 
229  if (_sys.hasMatrix(tag))
230  return _matrix_tag_u[tag];
231  else
232  mooseError("Tag ", tag, " is not associated with any matrix for variable ", _var.name());
233 }
234 
235 template <typename OutputType>
236 unsigned int
238 {
239  return _max_state;
240 }
241 
242 template <typename OutputType>
243 void
245 {
246  if (state > _max_state)
247  {
248  _sys.needSolutionState(state);
249  _max_state = state;
250  }
251 }
252 
253 template <typename OutputType>
254 template <typename ReturnType, typename Functor>
255 const ReturnType &
257  Functor functor)
258 {
259  if (state > 0)
260  {
261  // We need to request all states that are between current and the requested state
262  stateToTagHelper<ReturnType>(Moose::SolutionState(static_cast<int>(state) - 1), functor);
263  needSolutionState(cast_int<unsigned int>(state));
264  }
265 
266  switch (state)
267  {
268  case Moose::Current:
269  return functor(_subproblem.getVectorTagID(Moose::SOLUTION_TAG));
270 
271  case Moose::Old:
272  {
273  _old_solution_tag = _subproblem.getVectorTagID(Moose::OLD_SOLUTION_TAG);
274  insertSolutionTag(_old_solution_tag);
275  return functor(_old_solution_tag);
276  }
277 
278  case Moose::Older:
279  {
280  _older_solution_tag = _subproblem.getVectorTagID(Moose::OLDER_SOLUTION_TAG);
281  insertSolutionTag(_older_solution_tag);
282  return functor(_older_solution_tag);
283  }
284 
285  case Moose::PreviousNL:
286  {
287  _previous_nl_solution_tag = _subproblem.getVectorTagID(Moose::PREVIOUS_NL_SOLUTION_TAG);
288  insertSolutionTag(_previous_nl_solution_tag);
289  return functor(_previous_nl_solution_tag);
290  }
291 
292  default:
293  // We should never get here but gcc requires that we have a default. See
294  // htpps://stackoverflow.com/questions/18680378/after-defining-case-for-all-enum-values-compiler-still-says-control-reaches-e
295  mooseError("Unknown SolutionState!");
296  }
297 }
298 
299 template <typename OutputType>
302 {
303  auto functor = [this](TagID tag_id) -> const FieldVariableValue &
304  { return vectorTagValue(tag_id); };
305 
306  return const_cast<MooseVariableDataBase<OutputType> *>(this)
307  ->stateToTagHelper<FieldVariableValue>(state, functor);
308 }
309 
310 template <typename OutputType>
313 {
314  auto functor = [this](TagID tag_id) -> const FieldVariableGradient &
315  { return vectorTagGradient(tag_id); };
316 
317  return const_cast<MooseVariableDataBase<OutputType> *>(this)
318  ->stateToTagHelper<FieldVariableGradient>(state, functor);
319 }
320 
321 template <typename OutputType>
324 {
325  auto functor = [this](TagID tag_id) -> const DoFValue & { return vectorTagDofValue(tag_id); };
326 
327  return const_cast<MooseVariableDataBase<OutputType> *>(this)->stateToTagHelper<DoFValue>(state,
328  functor);
329 }
330 
331 template <typename OutputType>
334 {
335  return vectorTagDofValue(Moose::Current);
336 }
337 
338 template <typename OutputType>
341 {
342  return vectorTagDofValue(Moose::Old);
343 }
344 
345 template <typename OutputType>
348 {
349  return vectorTagDofValue(Moose::Older);
350 }
351 
352 template <typename OutputType>
355 {
356  return vectorTagDofValue(Moose::PreviousNL);
357 }
358 
359 template <typename OutputType>
360 void
361 MooseVariableDataBase<OutputType>::setNodalValue(const OutputType & value, unsigned int idx)
362 {
363  auto & dof_values = _vector_tags_dof_u[_solution_tag];
364  mooseAssert(idx < dof_values.size(), "idx is out of the bounds of degree of freedom values");
365  dof_values[idx] = value; // update variable nodal value
366  _has_dof_values = true;
367  _nodal_value = value;
368 
369  // Update the qp values as well
370  auto & u = _vector_tag_u[_solution_tag];
371  for (unsigned int qp = 0; qp < u.size(); qp++)
372  u[qp] = value;
373 }
374 
375 template <>
376 void
378  unsigned int idx)
379 {
380  auto & dof_values = _vector_tags_dof_u[_solution_tag];
381  for (decltype(idx) i = 0; i < dof_values.size(); ++i, ++idx)
382  dof_values[idx] = value(i);
383 
384  _has_dof_values = true;
385  _nodal_value = value;
386 }
387 
388 template <typename OutputType>
389 void
391 {
392  if (_has_dof_values)
393  {
394  auto & dof_values = _vector_tags_dof_u[_solution_tag];
395  mooseAssert(dof_values.size() == _dof_indices.size(),
396  "Degree of freedom values size and degree of freedom indices sizes must match.");
397  residual.insert(&dof_values[0], _dof_indices);
398  }
399 }
400 
401 template <>
402 void
404 {
405  if (_has_dof_values)
406  {
407  auto & dof_values = _vector_tags_dof_u[_solution_tag];
408  if (isNodal())
409  {
410  for (unsigned int i = 0; i < _dof_indices.size(); ++i)
411  for (unsigned int j = 0; j < _count; ++j)
412  residual.set(_dof_indices[i] + j, dof_values[i](j));
413  }
414  else
415  {
416  unsigned int n = 0;
417  for (unsigned int j = 0; j < _count; ++j)
418  {
419  for (unsigned int i = 0; i < _dof_indices.size(); ++i)
420  residual.set(_dof_indices[i] + n, dof_values[i](j));
421  n += _dof_indices.size();
422  }
423  }
424  }
425 }
426 
427 template <typename OutputType>
428 void
430 {
431  if (_has_dof_values)
432  {
433  auto & dof_values = _vector_tags_dof_u[_solution_tag];
434  residual.add_vector(&dof_values[0], _dof_indices);
435  }
436 }
437 
438 template <>
439 void
441 {
442  if (_has_dof_values)
443  {
444  auto & dof_values = _vector_tags_dof_u[_solution_tag];
445  if (isNodal())
446  {
447  for (unsigned int i = 0; i < _dof_indices.size(); ++i)
448  for (unsigned int j = 0; j < _count; ++j)
449  residual.add(_dof_indices[i] + j, dof_values[i](j));
450  }
451  else
452  {
453  unsigned int n = 0;
454  for (unsigned int j = 0; j < _count; ++j)
455  {
456  for (unsigned int i = 0; i < _dof_indices.size(); ++i)
457  residual.add(_dof_indices[i] + n, dof_values[i](j));
458  n += _dof_indices.size();
459  }
460  }
461  }
462 }
463 
464 template <typename OutputType>
465 const OutputType &
467 {
468  if (isNodal())
469  {
470  // Request the correct solution states and data members
471  vectorTagDofValue(state);
472  switch (state)
473  {
474  case Moose::Current:
475  return _nodal_value;
476 
477  case Moose::Old:
478  return _nodal_value_old;
479 
480  case Moose::Older:
481  return _nodal_value_older;
482 
483  case Moose::PreviousNL:
484  return _nodal_value_previous_nl;
485 
486  default:
487  // We should never get here but gcc requires that we have a default. See
488  // htpps://stackoverflow.com/questions/18680378/after-defining-case-for-all-enum-values-compiler-still-says-control-reaches-e
489  mooseError("Unknown SolutionState!");
490  }
491  }
492  else
493  mooseError("Nodal values can be requested only on nodal variables, variable '",
494  _var.name(),
495  "' is not nodal.");
496 }
497 
498 template <typename OutputType>
501 {
502  if (isNodal())
503  {
504  // Request the correct solution states and data members
505  vectorTagDofValue(state);
506  switch (state)
507  {
508  case Moose::Current:
509  return _nodal_value_array;
510 
511  case Moose::Old:
512  return _nodal_value_old_array;
513 
514  case Moose::Older:
515  return _nodal_value_older_array;
516 
517  default:
518  mooseError("No current support for PreviousNL for nodal value array");
519  }
520  }
521  else
522  mooseError("Nodal values can be requested only on nodal variables, variable '",
523  _var.name(),
524  "' is not nodal.");
525 }
526 
527 template <typename OutputType>
528 void
530 {
531  bool is_transient = _subproblem.isTransient();
532 
533  auto n = _dof_indices.size();
534  libmesh_assert(n);
535 
536  if (is_transient)
537  {
538  if (_need_u_dot || _need_grad_dot || _need_dof_values_dot)
539  {
540  libmesh_assert(_sys.solutionUDot());
541  _dof_values_dot.resize(n);
542  _sys.solutionUDot()->get(_dof_indices, &_dof_values_dot[0]);
543  }
544  if (_need_u_dotdot || _need_grad_dotdot || _need_dof_values_dotdot)
545  {
546  libmesh_assert(_sys.solutionUDotDot());
547  _dof_values_dotdot.resize(n);
548  _sys.solutionUDotDot()->get(_dof_indices, &_dof_values_dotdot[0]);
549  }
550  if (_need_u_dot_old || _need_dof_values_dot_old)
551  {
552  libmesh_assert(_sys.solutionUDotOld());
553  _dof_values_dot_old.resize(n);
554  _sys.solutionUDotOld()->get(_dof_indices, &_dof_values_dot_old[0]);
555  }
556  if (_need_u_dotdot_old || _need_dof_values_dotdot_old)
557  {
558  libmesh_assert(_sys.solutionUDotDotOld());
559  _dof_values_dotdot_old.resize(n);
560  _sys.solutionUDotDotOld()->get(_dof_indices, &_dof_values_dotdot_old[0]);
561  }
562  }
563 
564  for (auto tag : _required_vector_tags)
565  if (_need_vector_tag_u[tag] || _need_vector_tag_grad[tag] || _need_vector_tag_dof_u[tag])
566  if ((_subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_RESIDUAL &&
567  _subproblem.safeAccessTaggedVectors()) ||
568  _subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_SOLUTION)
569  {
570  // tag is defined on problem but may not be used by a system
571  // the grain tracker requires being able to read from solution vectors that we are also in
572  // the process of writing :-/
573  if (_sys.hasVector(tag) /* && _sys.getVector(tag).closed()*/)
574  {
575  auto & vec = _sys.getVector(tag);
576  _vector_tags_dof_u[tag].resize(n);
577  vec.get(_dof_indices, &_vector_tags_dof_u[tag][0]);
578  }
579  }
580 
581  if (_subproblem.safeAccessTaggedMatrices())
582  {
583  auto & active_coupleable_matrix_tags =
584  _subproblem.getActiveFEVariableCoupleableMatrixTags(_tid);
585 
586  for (auto tag : active_coupleable_matrix_tags)
587  {
588  _matrix_tags_dof_u[tag].resize(n);
589  if (_need_matrix_tag_dof_u[tag] || _need_matrix_tag_u[tag])
590  if (_sys.hasMatrix(tag) && _sys.matrixTagActive(tag) && _sys.getMatrix(tag).closed())
591  {
592  auto & mat = _sys.getMatrix(tag);
593  for (unsigned i = 0; i < n; i++)
594  {
595  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
596  _matrix_tags_dof_u[tag][i] = mat(_dof_indices[i], _dof_indices[i]);
597  }
598  }
599  }
600  }
601 
602  if (_need_du_dot_du || _need_dof_du_dot_du)
603  {
604  _dof_du_dot_du.resize(n);
605  for (decltype(n) i = 0; i < n; ++i)
606  _dof_du_dot_du[i] = _sys.duDotDu(_var.number());
607  }
608  if (_need_du_dotdot_du || _need_dof_du_dotdot_du)
609  {
610  _dof_du_dotdot_du.resize(n);
611  for (decltype(n) i = 0; i < n; ++i)
612  _dof_du_dotdot_du[i] = _sys.duDotDotDu();
613  }
614 }
615 
616 template <typename OutputType>
617 void
619  unsigned int n,
620  MooseArray<RealEigenVector> & dof_values) const
621 {
622  dof_values.resize(n);
623  if (isNodal())
624  {
625  for (unsigned int i = 0; i < n; ++i)
626  {
627  dof_values[i].resize(_count);
628  auto dof = _dof_indices[i];
629  for (unsigned int j = 0; j < _count; ++j)
630  dof_values[i](j) = sol(dof++);
631  }
632  }
633  else
634  {
635  for (unsigned int i = 0; i < n; ++i)
636  {
637  dof_values[i].resize(_count);
638  auto dof = _dof_indices[i];
639  for (unsigned int j = 0; j < _count; ++j)
640  {
641  dof_values[i](j) = sol(dof);
642  dof += n;
643  }
644  }
645  }
646 }
647 
648 template <>
649 void
651 {
652  bool is_transient = _subproblem.isTransient();
653 
654  auto n = _dof_indices.size();
655  libmesh_assert(n);
656 
657  if (is_transient)
658  {
659  if (_need_u_dot || _need_grad_dot || _need_dof_values_dot)
660  {
661  libmesh_assert(_sys.solutionUDot());
662  getArrayDoFValues(*_sys.solutionUDot(), n, _dof_values_dot);
663  }
664  if (_need_u_dotdot || _need_grad_dotdot || _need_dof_values_dotdot)
665  {
666  libmesh_assert(_sys.solutionUDotDot());
667  getArrayDoFValues(*_sys.solutionUDot(), n, _dof_values_dotdot);
668  }
669  if (_need_u_dot_old || _need_dof_values_dot_old)
670  {
671  libmesh_assert(_sys.solutionUDotOld());
672  getArrayDoFValues(*_sys.solutionUDotOld(), n, _dof_values_dot_old);
673  }
674  if (_need_u_dotdot_old || _need_dof_values_dotdot_old)
675  {
676  libmesh_assert(_sys.solutionUDotDotOld());
677  getArrayDoFValues(*_sys.solutionUDotDotOld(), n, _dof_values_dotdot_old);
678  }
679  }
680 
681  for (auto tag : _required_vector_tags)
682  if ((_subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_RESIDUAL &&
683  _subproblem.safeAccessTaggedVectors()) ||
684  _subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_SOLUTION)
685  // tag is defined on problem but may not be used by a system
686  if (_sys.hasVector(tag) && _sys.getVector(tag).closed())
687  getArrayDoFValues(_sys.getVector(tag), n, _vector_tags_dof_u[tag]);
688 
689  if (_subproblem.safeAccessTaggedMatrices())
690  {
691  auto & active_coupleable_matrix_tags =
692  _subproblem.getActiveFEVariableCoupleableMatrixTags(_tid);
693  for (auto tag : active_coupleable_matrix_tags)
694  {
695  _matrix_tags_dof_u[tag].resize(n);
696  if (_need_matrix_tag_dof_u[tag] || _need_matrix_tag_u[tag])
697  if (_sys.hasMatrix(tag) && _sys.matrixTagActive(tag) && _sys.getMatrix(tag).closed())
698  {
699  auto & mat = _sys.getMatrix(tag);
700  for (unsigned i = 0; i < n; i++)
701  {
702  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
703  for (unsigned j = 0; j < _count; j++)
704  _matrix_tags_dof_u[tag][i](j) = mat(_dof_indices[i] + j, _dof_indices[i] + j);
705  }
706  }
707  }
708  }
709 
710  if (_need_du_dot_du || _need_dof_du_dot_du)
711  {
712  _dof_du_dot_du.resize(n);
713  for (decltype(n) i = 0; i < n; ++i)
714  _dof_du_dot_du[i] = _sys.duDotDu(_var.number());
715  }
716  if (_need_du_dotdot_du || _need_dof_du_dotdot_du)
717  {
718  _dof_du_dotdot_du.resize(n);
719  for (decltype(n) i = 0; i < n; ++i)
720  _dof_du_dotdot_du[i] = _sys.duDotDotDu();
721  }
722 }
723 
724 template <typename OutputType>
725 void
727 {
728  if (_subproblem.isTransient())
729  {
730  _dof_values_dot.resize(0);
731  _dof_values_dotdot.resize(0);
732  _dof_values_dot_old.resize(0);
733  _dof_values_dotdot_old.resize(0);
734  _dof_du_dot_du.resize(0);
735  _dof_du_dotdot_du.resize(0);
736  }
737 
738  for (auto & dof_values : _vector_tags_dof_u)
739  dof_values.resize(0);
740 
741  _has_dof_values = false;
742 }
743 
744 template <typename OutputType>
745 void
747 {
748  bool is_transient = _subproblem.isTransient();
749 
750  libmesh_assert(_dof_indices.size());
751 
752  auto & dof_values = _vector_tags_dof_u[_solution_tag];
753  _nodal_value = dof_values[0];
754  _nodal_value_array[0] = _nodal_value;
755 
756  if (is_transient)
757  {
758  if (oldestSolutionStateRequested() >= 1)
759  {
760  _nodal_value_old = _vector_tags_dof_u[_old_solution_tag][0];
761  _nodal_value_old_array[0] = _nodal_value_old;
762  }
763  if (oldestSolutionStateRequested() >= 2)
764  {
765  _nodal_value_older = _vector_tags_dof_u[_older_solution_tag][0];
766  _nodal_value_older_array[0] = _nodal_value_older;
767  }
768  if (_need_dof_values_dot)
769  _nodal_value_dot = _dof_values_dot[0];
770  if (_need_dof_values_dotdot)
771  _nodal_value_dotdot = _dof_values_dotdot[0];
772  if (_need_dof_values_dot_old)
773  _nodal_value_dot_old = _dof_values_dot_old[0];
774  if (_need_dof_values_dotdot_old)
775  _nodal_value_dotdot_old = _dof_values_dotdot_old[0];
776  }
777  if (_previous_nl_solution_tag != Moose::INVALID_TAG_ID)
778  _nodal_value_previous_nl = _vector_tags_dof_u[_previous_nl_solution_tag][0];
779 }
780 
781 template <>
782 void
784 {
785  bool is_transient = _subproblem.isTransient();
786 
787  auto n = _dof_indices.size();
788  libmesh_assert(n);
789 
790  auto & dof_values = _vector_tags_dof_u[_solution_tag];
791  for (decltype(n) i = 0; i < n; ++i)
792  _nodal_value(i) = dof_values[i];
793  _nodal_value_array[0] = _nodal_value;
794 
795  if (is_transient)
796  {
797  if (oldestSolutionStateRequested() >= 1)
798  {
799  auto & dof_values_old = _vector_tags_dof_u[_old_solution_tag];
800  for (decltype(n) i = 0; i < n; ++i)
801  _nodal_value_old(i) = dof_values_old[i];
802  _nodal_value_old_array[0] = _nodal_value_old;
803  }
804  if (oldestSolutionStateRequested() >= 2)
805  {
806  auto & dof_values_older = _vector_tags_dof_u[_older_solution_tag];
807  for (decltype(n) i = 0; i < n; ++i)
808  _nodal_value_older(i) = dof_values_older[i];
809  _nodal_value_older_array[0] = _nodal_value_older;
810  }
811  if (_need_dof_values_dot)
812  for (decltype(n) i = 0; i < n; ++i)
813  _nodal_value_dot(i) = _dof_values_dot[i];
814  if (_need_dof_values_dotdot)
815  for (decltype(n) i = 0; i < n; ++i)
816  _nodal_value_dotdot(i) = _dof_values_dotdot[i];
817  if (_need_dof_values_dot_old)
818  for (decltype(n) i = 0; i < n; ++i)
819  _nodal_value_dot_old(i) = _dof_values_dot_old[i];
820  if (_need_dof_values_dotdot_old)
821  for (decltype(n) i = 0; i < n; ++i)
822  _nodal_value_dotdot_old(i) = _dof_values_dotdot_old[i];
823  }
824  if (_previous_nl_solution_tag != Moose::INVALID_TAG_ID)
825  {
826  auto & dof_values_previous_nl = _vector_tags_dof_u[_previous_nl_solution_tag];
827  for (decltype(n) i = 0; i < n; ++i)
828  _nodal_value_previous_nl(i) = dof_values_previous_nl[i];
829  }
830 }
831 
832 template class MooseVariableDataBase<Real>;
virtual TagID getVectorTagID(const TagName &tag_name) const
Get a TagID from a TagName.
Definition: SubProblem.C:203
std::vector< DoFValue > _matrix_tags_dof_u
virtual void insert(const Number *v, const std::vector< numeric_index_type > &dof_indices)
unsigned int TagID
Definition: MooseTypes.h:210
void resizeVectorTagData(TagID tag)
resize the vector tag need flags and data containers to accomodate this tag index ...
const FieldVariableValue & matrixTagValue(TagID tag) const
std::vector< FieldVariableValue > _matrix_tag_u
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 mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:302
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)
void fetchDoFValues()
Helper methods for assigning dof values from their corresponding solution values. ...
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:84
const DoFValue & nodalVectorTagValue(TagID tag) const
std::vector< bool > _need_vector_tag_grad
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.
const DoFValue & dofValues() const
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.
std::vector< DoFValue > _vector_tags_dof_u
libmesh_assert(ctx)
const OutputType & nodalValue(Moose::SolutionState state) const
void insertSolutionTag(TagID tag_id)
insert a solution tag into our tag containers
MooseVariableDataBase(const MooseVariableField< OutputType > &var, SystemBase &sys, THREAD_ID tid)
const DoFValue & dofValuesOlder() const
MooseArray< OutputType > _nodal_value_old_array
std::vector< bool > _need_matrix_tag_u
virtual unsigned int numMatrixTags() const
The total number of tags.
Definition: SubProblem.h:248
const FieldVariableValue & vectorTagValue(TagID tag) const
const DoFValue & dofValuesPreviousNL() const
std::vector< bool > _need_matrix_tag_dof_u
const TagID INVALID_TAG_ID
Definition: MooseTypes.C:23
const DoFValue & nodalMatrixTagValue(TagID tag) const
SolutionState
Definition: MooseTypes.h:233
std::vector< FieldVariableGradient > _vector_tag_grad
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:195
const FieldVariableValue & sln(Moose::SolutionState state) const
Local solution getter.
const DoFValue & dofValuesOld() const
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 TagName PREVIOUS_NL_SOLUTION_TAG
Definition: MooseTypes.C:28
unsigned int oldestSolutionStateRequested() const
The oldest solution state that is requested for this variable (0 = current, 1 = old, 2 = older, etc).
const DoFValue & vectorTagDofValue(TagID tag) const
unsigned int THREAD_ID
Definition: MooseTypes.h:209
unsigned int idx(const ElemType type, const unsigned int nx, const unsigned int i, const unsigned int j)