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  _need_vector_tag_u[tag] = true;
185 
186  if (_sys.hasVector(tag))
187  return _vector_tag_u[tag];
188  else
189  mooseError("Tag ", tag, " is not associated with any vector for variable ", _var.name());
190 }
191 
192 template <typename OutputType>
195 {
196  if (tag >= _need_vector_tag_dof_u.size())
197  const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
198 
199  _need_vector_tag_dof_u[tag] = true;
200 
201  if (_sys.hasVector(tag))
202  return _vector_tags_dof_u[tag];
203  else
204  mooseError("Tag ", tag, " is not associated with any vector for variable ", _var.name());
205 }
206 
207 template <typename OutputType>
210 {
211  if (tag >= _need_vector_tag_grad.size())
212  const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
213 
214  _need_vector_tag_grad[tag] = true;
215 
216  if (_sys.hasVector(tag))
217  return _vector_tag_grad[tag];
218  else
219  mooseError("Tag ", tag, " is not associated with any vector for variable ", _var.name());
220 }
221 
222 template <typename OutputType>
225 {
226  if (tag >= _matrix_tag_u.size())
227  {
228  _need_matrix_tag_u.resize(tag + 1, false);
229  const_cast<MooseVariableDataBase<OutputType> *>(this)->_matrix_tag_u.resize(tag + 1);
230  }
231 
232  _need_matrix_tag_u[tag] = true;
233 
234  if (_sys.hasMatrix(tag))
235  return _matrix_tag_u[tag];
236  else
237  mooseError("Tag ", tag, " is not associated with any matrix for variable ", _var.name());
238 }
239 
240 template <typename OutputType>
241 unsigned int
243 {
244  return _max_state;
245 }
246 
247 template <typename OutputType>
248 void
250 {
251  if (state > _max_state)
252  {
253  _sys.needSolutionState(state);
254  _max_state = state;
255  }
256 }
257 
258 template <typename OutputType>
259 template <typename ReturnType, typename Functor>
260 const ReturnType &
262  Functor functor)
263 {
264  if (state > 0)
265  {
266  // We need to request all states that are between current and the requested state
267  stateToTagHelper<ReturnType>(Moose::SolutionState(static_cast<int>(state) - 1), functor);
268  needSolutionState(cast_int<unsigned int>(state));
269  }
270 
271  switch (state)
272  {
273  case Moose::Current:
274  return functor(_subproblem.getVectorTagID(Moose::SOLUTION_TAG));
275 
276  case Moose::Old:
277  {
278  _old_solution_tag = _subproblem.getVectorTagID(Moose::OLD_SOLUTION_TAG);
279  insertSolutionTag(_old_solution_tag);
280  return functor(_old_solution_tag);
281  }
282 
283  case Moose::Older:
284  {
285  _older_solution_tag = _subproblem.getVectorTagID(Moose::OLDER_SOLUTION_TAG);
286  insertSolutionTag(_older_solution_tag);
287  return functor(_older_solution_tag);
288  }
289 
290  case Moose::PreviousNL:
291  {
292  _previous_nl_solution_tag = _subproblem.getVectorTagID(Moose::PREVIOUS_NL_SOLUTION_TAG);
293  insertSolutionTag(_previous_nl_solution_tag);
294  return functor(_previous_nl_solution_tag);
295  }
296 
297  default:
298  // We should never get here but gcc requires that we have a default. See
299  // htpps://stackoverflow.com/questions/18680378/after-defining-case-for-all-enum-values-compiler-still-says-control-reaches-e
300  mooseError("Unknown SolutionState!");
301  }
302 }
303 
304 template <typename OutputType>
307 {
308  auto functor = [this](TagID tag_id) -> const FieldVariableValue &
309  { return vectorTagValue(tag_id); };
310 
311  return const_cast<MooseVariableDataBase<OutputType> *>(this)
312  ->stateToTagHelper<FieldVariableValue>(state, functor);
313 }
314 
315 template <typename OutputType>
318 {
319  auto functor = [this](TagID tag_id) -> const FieldVariableGradient &
320  { return vectorTagGradient(tag_id); };
321 
322  return const_cast<MooseVariableDataBase<OutputType> *>(this)
323  ->stateToTagHelper<FieldVariableGradient>(state, functor);
324 }
325 
326 template <typename OutputType>
329 {
330  auto functor = [this](TagID tag_id) -> const DofValues & { return vectorTagDofValue(tag_id); };
331 
332  return const_cast<MooseVariableDataBase<OutputType> *>(this)->stateToTagHelper<DofValues>(
333  state, functor);
334 }
335 
336 template <typename OutputType>
339 {
340  return vectorTagDofValue(Moose::Current);
341 }
342 
343 template <typename OutputType>
346 {
347  return vectorTagDofValue(Moose::Old);
348 }
349 
350 template <typename OutputType>
353 {
354  return vectorTagDofValue(Moose::Older);
355 }
356 
357 template <typename OutputType>
360 {
361  return vectorTagDofValue(Moose::PreviousNL);
362 }
363 
364 template <typename OutputType>
365 void
366 MooseVariableDataBase<OutputType>::setNodalValue(const OutputType & value, unsigned int idx)
367 {
368  auto & dof_values = _vector_tags_dof_u[_solution_tag];
369  mooseAssert(idx < dof_values.size(), "idx is out of the bounds of degree of freedom values");
370  dof_values[idx] = value; // update variable nodal value
371  _has_dof_values = true;
372  _nodal_value = value;
373 
374  // Update the qp values as well
375  auto & u = _vector_tag_u[_solution_tag];
376  for (unsigned int qp = 0; qp < u.size(); qp++)
377  u[qp] = value;
378 }
379 
380 template <>
381 void
383  unsigned int idx)
384 {
385  auto & dof_values = _vector_tags_dof_u[_solution_tag];
386  for (decltype(idx) i = 0; i < dof_values.size(); ++i, ++idx)
387  dof_values[idx] = value(i);
388 
389  _has_dof_values = true;
390  _nodal_value = value;
391 }
392 
393 template <typename OutputType>
394 void
396 {
397  if (_has_dof_values)
398  {
399  const auto & dof_values = _vector_tags_dof_u[_solution_tag];
400  mooseAssert(dof_values.size() == _dof_indices.size(),
401  "Degree of freedom values size and degree of freedom indices sizes must match.");
402  residual.insert(&dof_values[0], _dof_indices);
403  }
404 }
405 
406 template <>
407 void
409 {
410  if (_has_dof_values)
411  {
412  const auto & dof_values = _vector_tags_dof_u[_solution_tag];
413  mooseAssert(_dof_indices.size() % _count == 0,
414  "Dof indices should be cleanly divisible by the variable count");
415  const auto n_shapes = _dof_indices.size() / _count;
416  for (const auto indx : index_range(_dof_indices))
417  {
418  const auto i = indx % n_shapes;
419  const auto j = indx / n_shapes;
420  residual.set(_dof_indices[indx], dof_values[i](j));
421  }
422  }
423 }
424 
425 template <typename OutputType>
426 void
428 {
429  if (_has_dof_values)
430  {
431  const auto & dof_values = _vector_tags_dof_u[_solution_tag];
432  residual.add_vector(&dof_values[0], _dof_indices);
433  }
434 }
435 
436 template <>
437 void
439 {
440  if (_has_dof_values)
441  {
442  const auto & dof_values = _vector_tags_dof_u[_solution_tag];
443  mooseAssert(_dof_indices.size() % _count == 0,
444  "Dof indices should be cleanly divisible by the variable count");
445  const auto n_shapes = _dof_indices.size() / _count;
446  for (const auto indx : index_range(_dof_indices))
447  {
448  const auto i = indx % n_shapes;
449  const auto j = indx / n_shapes;
450  residual.add(_dof_indices[indx], dof_values[i](j));
451  }
452  }
453 }
454 
455 template <typename OutputType>
456 const OutputType &
458 {
459  if (isNodal())
460  {
461  // Request the correct solution states and data members
462  vectorTagDofValue(state);
463  switch (state)
464  {
465  case Moose::Current:
466  return _nodal_value;
467 
468  case Moose::Old:
469  return _nodal_value_old;
470 
471  case Moose::Older:
472  return _nodal_value_older;
473 
474  case Moose::PreviousNL:
475  return _nodal_value_previous_nl;
476 
477  default:
478  // We should never get here but gcc requires that we have a default. See
479  // htpps://stackoverflow.com/questions/18680378/after-defining-case-for-all-enum-values-compiler-still-says-control-reaches-e
480  mooseError("Unknown SolutionState!");
481  }
482  }
483  else
484  mooseError("Nodal values can be requested only on nodal variables, variable '",
485  _var.name(),
486  "' is not nodal.");
487 }
488 
489 template <typename OutputType>
492 {
493  if (isNodal())
494  {
495  // Request the correct solution states and data members
496  vectorTagDofValue(state);
497  switch (state)
498  {
499  case Moose::Current:
500  return _nodal_value_array;
501 
502  case Moose::Old:
503  return _nodal_value_old_array;
504 
505  case Moose::Older:
506  return _nodal_value_older_array;
507 
508  default:
509  mooseError("No current support for PreviousNL for nodal value array");
510  }
511  }
512  else
513  mooseError("Nodal values can be requested only on nodal variables, variable '",
514  _var.name(),
515  "' is not nodal.");
516 }
517 
518 template <typename OutputType>
519 void
521 {
522  bool is_transient = _subproblem.isTransient();
523 
524  auto n = _dof_indices.size();
525  libmesh_assert(n);
526 
527  if (is_transient)
528  {
529  if (_need_u_dot || _need_grad_dot || _need_dof_values_dot)
530  {
531  libmesh_assert(_sys.solutionUDot());
532  _dof_values_dot.resize(n);
533  _sys.solutionUDot()->get(_dof_indices, &_dof_values_dot[0]);
534  }
535  if (_need_u_dotdot || _need_grad_dotdot || _need_dof_values_dotdot)
536  {
537  libmesh_assert(_sys.solutionUDotDot());
538  _dof_values_dotdot.resize(n);
539  _sys.solutionUDotDot()->get(_dof_indices, &_dof_values_dotdot[0]);
540  }
541  if (_need_u_dot_old || _need_dof_values_dot_old)
542  {
543  libmesh_assert(_sys.solutionUDotOld());
544  _dof_values_dot_old.resize(n);
545  _sys.solutionUDotOld()->get(_dof_indices, &_dof_values_dot_old[0]);
546  }
547  if (_need_u_dotdot_old || _need_dof_values_dotdot_old)
548  {
549  libmesh_assert(_sys.solutionUDotDotOld());
550  _dof_values_dotdot_old.resize(n);
551  _sys.solutionUDotDotOld()->get(_dof_indices, &_dof_values_dotdot_old[0]);
552  }
553  }
554 
555  for (auto tag : _required_vector_tags)
556  if (_need_vector_tag_u[tag] || _need_vector_tag_grad[tag] || _need_vector_tag_dof_u[tag])
557  if ((_subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_RESIDUAL &&
558  _subproblem.safeAccessTaggedVectors()) ||
559  _subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_SOLUTION)
560  {
561  // tag is defined on problem but may not be used by a system
562  // the grain tracker requires being able to read from solution vectors that we are also in
563  // the process of writing :-/
564  // Note: the extra vector tags are also still not closed when a TagVectorAux uses them
565  if (_sys.hasVector(tag) /* && _sys.getVector(tag).closed()*/)
566  {
567  auto & vec = _sys.getVector(tag);
568  _vector_tags_dof_u[tag].resize(n);
569  vec.get(_dof_indices, &_vector_tags_dof_u[tag][0]);
570  }
571  }
572 
573  if (_subproblem.safeAccessTaggedMatrices())
574  {
575  auto & active_coupleable_matrix_tags =
576  _subproblem.getActiveFEVariableCoupleableMatrixTags(_tid);
577 
578  for (auto tag : active_coupleable_matrix_tags)
579  {
580  _matrix_tags_dof_u[tag].resize(n);
581  if (_need_matrix_tag_dof_u[tag] || _need_matrix_tag_u[tag])
582  if (_sys.hasMatrix(tag) && _sys.matrixTagActive(tag))
583  {
584  mooseAssert(_sys.getMatrix(tag).closed(),
585  "Matrix with tag '" + std::to_string(tag) + "' should be closed");
586  auto & mat = _sys.getMatrix(tag);
587  for (unsigned i = 0; i < n; i++)
588  _matrix_tags_dof_u[tag][i] = mat(_dof_indices[i], _dof_indices[i]);
589  }
590  }
591  }
592 
593  if (_need_du_dot_du || _need_dof_du_dot_du)
594  {
595  _dof_du_dot_du.resize(n);
596  for (decltype(n) i = 0; i < n; ++i)
597  _dof_du_dot_du[i] = _sys.duDotDu(_var.number());
598  }
599  if (_need_du_dotdot_du || _need_dof_du_dotdot_du)
600  {
601  _dof_du_dotdot_du.resize(n);
602  for (decltype(n) i = 0; i < n; ++i)
603  _dof_du_dotdot_du[i] = _sys.duDotDotDu();
604  }
605 }
606 
607 template <typename OutputType>
608 void
610  const unsigned int nshapes,
611  MooseArray<RealEigenVector> & dof_values) const
612 {
613  dof_values.resize(nshapes);
614  for (const auto i : make_range(nshapes))
615  {
616  dof_values[i].resize(_count);
617  for (const auto j : make_range(_count))
618  dof_values[i](j) = sol(_dof_indices[j * nshapes + i]);
619  }
620 }
621 
622 template <>
623 void
625 {
626  bool is_transient = _subproblem.isTransient();
627 
628  auto n = _dof_indices.size() / _count;
629  libmesh_assert(n);
630 
631  if (is_transient)
632  {
633  if (_need_u_dot || _need_grad_dot || _need_dof_values_dot)
634  {
635  libmesh_assert(_sys.solutionUDot());
636  getArrayDofValues(*_sys.solutionUDot(), n, _dof_values_dot);
637  }
638  if (_need_u_dotdot || _need_grad_dotdot || _need_dof_values_dotdot)
639  {
640  libmesh_assert(_sys.solutionUDotDot());
641  getArrayDofValues(*_sys.solutionUDot(), n, _dof_values_dotdot);
642  }
643  if (_need_u_dot_old || _need_dof_values_dot_old)
644  {
645  libmesh_assert(_sys.solutionUDotOld());
646  getArrayDofValues(*_sys.solutionUDotOld(), n, _dof_values_dot_old);
647  }
648  if (_need_u_dotdot_old || _need_dof_values_dotdot_old)
649  {
650  libmesh_assert(_sys.solutionUDotDotOld());
651  getArrayDofValues(*_sys.solutionUDotDotOld(), n, _dof_values_dotdot_old);
652  }
653  }
654 
655  for (auto tag : _required_vector_tags)
656  if ((_subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_RESIDUAL &&
657  _subproblem.safeAccessTaggedVectors()) ||
658  _subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_SOLUTION)
659  // tag is defined on problem but may not be used by a system
660  if (_sys.hasVector(tag))
661  {
662  mooseAssert(_sys.getVector(tag).closed(),
663  "Vector with tag '" + std::to_string(tag) + "' should be closed");
664  getArrayDofValues(_sys.getVector(tag), n, _vector_tags_dof_u[tag]);
665  }
666 
667  if (_subproblem.safeAccessTaggedMatrices())
668  {
669  auto & active_coupleable_matrix_tags =
670  _subproblem.getActiveFEVariableCoupleableMatrixTags(_tid);
671  for (auto tag : active_coupleable_matrix_tags)
672  {
673  _matrix_tags_dof_u[tag].resize(n);
674  if (_need_matrix_tag_dof_u[tag] || _need_matrix_tag_u[tag])
675  if (_sys.hasMatrix(tag) && _sys.matrixTagActive(tag))
676  {
677  mooseAssert(_sys.getMatrix(tag).closed(),
678  "Matrix with tag '" + std::to_string(tag) + "' should be closed");
679  auto & mat = _sys.getMatrix(tag);
680  for (unsigned i = 0; i < n; i++)
681  for (unsigned j = 0; j < _count; j++)
682  _matrix_tags_dof_u[tag][i](j) = mat(_dof_indices[i] + j, _dof_indices[i] + j);
683  }
684  }
685  }
686 
687  if (_need_du_dot_du || _need_dof_du_dot_du)
688  {
689  _dof_du_dot_du.resize(n);
690  for (decltype(n) i = 0; i < n; ++i)
691  _dof_du_dot_du[i] = _sys.duDotDu(_var.number());
692  }
693  if (_need_du_dotdot_du || _need_dof_du_dotdot_du)
694  {
695  _dof_du_dotdot_du.resize(n);
696  for (decltype(n) i = 0; i < n; ++i)
697  _dof_du_dotdot_du[i] = _sys.duDotDotDu();
698  }
699 }
700 
701 template <typename OutputType>
702 void
704 {
705  if (_subproblem.isTransient())
706  {
707  _dof_values_dot.resize(0);
708  _dof_values_dotdot.resize(0);
709  _dof_values_dot_old.resize(0);
710  _dof_values_dotdot_old.resize(0);
711  _dof_du_dot_du.resize(0);
712  _dof_du_dotdot_du.resize(0);
713  }
714 
715  for (auto & dof_values : _vector_tags_dof_u)
716  dof_values.resize(0);
717 
718  _has_dof_values = false;
719 }
720 
721 template <typename OutputType>
722 void
724 {
725  bool is_transient = _subproblem.isTransient();
726  libmesh_assert(_dof_indices.size());
727 
728  auto & dof_values = _vector_tags_dof_u[_solution_tag];
729  _nodal_value = dof_values[0];
730  _nodal_value_array[0] = _nodal_value;
731 
732  if (is_transient)
733  {
734  if (oldestSolutionStateRequested() >= 1)
735  {
736  _nodal_value_old = _vector_tags_dof_u[_old_solution_tag][0];
737  _nodal_value_old_array[0] = _nodal_value_old;
738  }
739  if (oldestSolutionStateRequested() >= 2)
740  {
741  _nodal_value_older = _vector_tags_dof_u[_older_solution_tag][0];
742  _nodal_value_older_array[0] = _nodal_value_older;
743  }
744  if (_need_dof_values_dot)
745  _nodal_value_dot = _dof_values_dot[0];
746  if (_need_dof_values_dotdot)
747  _nodal_value_dotdot = _dof_values_dotdot[0];
748  if (_need_dof_values_dot_old)
749  _nodal_value_dot_old = _dof_values_dot_old[0];
750  if (_need_dof_values_dotdot_old)
751  _nodal_value_dotdot_old = _dof_values_dotdot_old[0];
752  }
753  if (_previous_nl_solution_tag != Moose::INVALID_TAG_ID)
754  _nodal_value_previous_nl = _vector_tags_dof_u[_previous_nl_solution_tag][0];
755 }
756 
757 template <>
758 void
760 {
761  bool is_transient = _subproblem.isTransient();
762 
763  auto n = _dof_indices.size();
764  libmesh_assert(n);
765 
766  auto & dof_values = _vector_tags_dof_u[_solution_tag];
767  for (decltype(n) i = 0; i < n; ++i)
768  _nodal_value(i) = dof_values[i];
769  _nodal_value_array[0] = _nodal_value;
770 
771  if (is_transient)
772  {
773  if (oldestSolutionStateRequested() >= 1)
774  {
775  auto & dof_values_old = _vector_tags_dof_u[_old_solution_tag];
776  for (decltype(n) i = 0; i < n; ++i)
777  _nodal_value_old(i) = dof_values_old[i];
778  _nodal_value_old_array[0] = _nodal_value_old;
779  }
780  if (oldestSolutionStateRequested() >= 2)
781  {
782  auto & dof_values_older = _vector_tags_dof_u[_older_solution_tag];
783  for (decltype(n) i = 0; i < n; ++i)
784  _nodal_value_older(i) = dof_values_older[i];
785  _nodal_value_older_array[0] = _nodal_value_older;
786  }
787  if (_need_dof_values_dot)
788  for (decltype(n) i = 0; i < n; ++i)
789  _nodal_value_dot(i) = _dof_values_dot[i];
790  if (_need_dof_values_dotdot)
791  for (decltype(n) i = 0; i < n; ++i)
792  _nodal_value_dotdot(i) = _dof_values_dotdot[i];
793  if (_need_dof_values_dot_old)
794  for (decltype(n) i = 0; i < n; ++i)
795  _nodal_value_dot_old(i) = _dof_values_dot_old[i];
796  if (_need_dof_values_dotdot_old)
797  for (decltype(n) i = 0; i < n; ++i)
798  _nodal_value_dotdot_old(i) = _dof_values_dotdot_old[i];
799  }
800  if (_previous_nl_solution_tag != Moose::INVALID_TAG_ID)
801  {
802  auto & dof_values_previous_nl = _vector_tags_dof_u[_previous_nl_solution_tag];
803  for (decltype(n) i = 0; i < n; ++i)
804  _nodal_value_previous_nl(i) = dof_values_previous_nl[i];
805  }
806 }
807 
808 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:323
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:84
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