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 DoFValue & { return vectorTagDofValue(tag_id); };
331 
332  return const_cast<MooseVariableDataBase<OutputType> *>(this)->stateToTagHelper<DoFValue>(state,
333  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  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  auto & dof_values = _vector_tags_dof_u[_solution_tag];
413  if (isNodal())
414  {
415  for (unsigned int i = 0; i < _dof_indices.size(); ++i)
416  for (unsigned int j = 0; j < _count; ++j)
417  residual.set(_dof_indices[i] + j, dof_values[i](j));
418  }
419  else
420  {
421  unsigned int n = 0;
422  for (unsigned int j = 0; j < _count; ++j)
423  {
424  for (unsigned int i = 0; i < _dof_indices.size(); ++i)
425  residual.set(_dof_indices[i] + n, dof_values[i](j));
426  n += _dof_indices.size();
427  }
428  }
429  }
430 }
431 
432 template <typename OutputType>
433 void
435 {
436  if (_has_dof_values)
437  {
438  auto & dof_values = _vector_tags_dof_u[_solution_tag];
439  residual.add_vector(&dof_values[0], _dof_indices);
440  }
441 }
442 
443 template <>
444 void
446 {
447  if (_has_dof_values)
448  {
449  auto & dof_values = _vector_tags_dof_u[_solution_tag];
450  if (isNodal())
451  {
452  for (unsigned int i = 0; i < _dof_indices.size(); ++i)
453  for (unsigned int j = 0; j < _count; ++j)
454  residual.add(_dof_indices[i] + j, dof_values[i](j));
455  }
456  else
457  {
458  unsigned int n = 0;
459  for (unsigned int j = 0; j < _count; ++j)
460  {
461  for (unsigned int i = 0; i < _dof_indices.size(); ++i)
462  residual.add(_dof_indices[i] + n, dof_values[i](j));
463  n += _dof_indices.size();
464  }
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  if (_sys.hasVector(tag) /* && _sys.getVector(tag).closed()*/)
579  {
580  auto & vec = _sys.getVector(tag);
581  _vector_tags_dof_u[tag].resize(n);
582  vec.get(_dof_indices, &_vector_tags_dof_u[tag][0]);
583  }
584  }
585 
586  if (_subproblem.safeAccessTaggedMatrices())
587  {
588  auto & active_coupleable_matrix_tags =
589  _subproblem.getActiveFEVariableCoupleableMatrixTags(_tid);
590 
591  for (auto tag : active_coupleable_matrix_tags)
592  {
593  _matrix_tags_dof_u[tag].resize(n);
594  if (_need_matrix_tag_dof_u[tag] || _need_matrix_tag_u[tag])
595  if (_sys.hasMatrix(tag) && _sys.matrixTagActive(tag) && _sys.getMatrix(tag).closed())
596  {
597  auto & mat = _sys.getMatrix(tag);
598  for (unsigned i = 0; i < n; i++)
599  {
600  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
601  _matrix_tags_dof_u[tag][i] = mat(_dof_indices[i], _dof_indices[i]);
602  }
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  unsigned int n,
625  MooseArray<RealEigenVector> & dof_values) const
626 {
627  dof_values.resize(n);
628  if (isNodal())
629  {
630  for (unsigned int i = 0; i < n; ++i)
631  {
632  dof_values[i].resize(_count);
633  auto dof = _dof_indices[i];
634  for (unsigned int j = 0; j < _count; ++j)
635  dof_values[i](j) = sol(dof++);
636  }
637  }
638  else
639  {
640  for (unsigned int i = 0; i < n; ++i)
641  {
642  dof_values[i].resize(_count);
643  auto dof = _dof_indices[i];
644  for (unsigned int j = 0; j < _count; ++j)
645  {
646  dof_values[i](j) = sol(dof);
647  dof += n;
648  }
649  }
650  }
651 }
652 
653 template <>
654 void
656 {
657  bool is_transient = _subproblem.isTransient();
658 
659  auto n = _dof_indices.size();
660  libmesh_assert(n);
661 
662  if (is_transient)
663  {
664  if (_need_u_dot || _need_grad_dot || _need_dof_values_dot)
665  {
666  libmesh_assert(_sys.solutionUDot());
667  getArrayDoFValues(*_sys.solutionUDot(), n, _dof_values_dot);
668  }
669  if (_need_u_dotdot || _need_grad_dotdot || _need_dof_values_dotdot)
670  {
671  libmesh_assert(_sys.solutionUDotDot());
672  getArrayDoFValues(*_sys.solutionUDot(), n, _dof_values_dotdot);
673  }
674  if (_need_u_dot_old || _need_dof_values_dot_old)
675  {
676  libmesh_assert(_sys.solutionUDotOld());
677  getArrayDoFValues(*_sys.solutionUDotOld(), n, _dof_values_dot_old);
678  }
679  if (_need_u_dotdot_old || _need_dof_values_dotdot_old)
680  {
681  libmesh_assert(_sys.solutionUDotDotOld());
682  getArrayDoFValues(*_sys.solutionUDotDotOld(), n, _dof_values_dotdot_old);
683  }
684  }
685 
686  for (auto tag : _required_vector_tags)
687  if ((_subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_RESIDUAL &&
688  _subproblem.safeAccessTaggedVectors()) ||
689  _subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_SOLUTION)
690  // tag is defined on problem but may not be used by a system
691  if (_sys.hasVector(tag) && _sys.getVector(tag).closed())
692  getArrayDoFValues(_sys.getVector(tag), n, _vector_tags_dof_u[tag]);
693 
694  if (_subproblem.safeAccessTaggedMatrices())
695  {
696  auto & active_coupleable_matrix_tags =
697  _subproblem.getActiveFEVariableCoupleableMatrixTags(_tid);
698  for (auto tag : active_coupleable_matrix_tags)
699  {
700  _matrix_tags_dof_u[tag].resize(n);
701  if (_need_matrix_tag_dof_u[tag] || _need_matrix_tag_u[tag])
702  if (_sys.hasMatrix(tag) && _sys.matrixTagActive(tag) && _sys.getMatrix(tag).closed())
703  {
704  auto & mat = _sys.getMatrix(tag);
705  for (unsigned i = 0; i < n; i++)
706  {
707  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
708  for (unsigned j = 0; j < _count; j++)
709  _matrix_tags_dof_u[tag][i](j) = mat(_dof_indices[i] + j, _dof_indices[i] + j);
710  }
711  }
712  }
713  }
714 
715  if (_need_du_dot_du || _need_dof_du_dot_du)
716  {
717  _dof_du_dot_du.resize(n);
718  for (decltype(n) i = 0; i < n; ++i)
719  _dof_du_dot_du[i] = _sys.duDotDu(_var.number());
720  }
721  if (_need_du_dotdot_du || _need_dof_du_dotdot_du)
722  {
723  _dof_du_dotdot_du.resize(n);
724  for (decltype(n) i = 0; i < n; ++i)
725  _dof_du_dotdot_du[i] = _sys.duDotDotDu();
726  }
727 }
728 
729 template <typename OutputType>
730 void
732 {
733  if (_subproblem.isTransient())
734  {
735  _dof_values_dot.resize(0);
736  _dof_values_dotdot.resize(0);
737  _dof_values_dot_old.resize(0);
738  _dof_values_dotdot_old.resize(0);
739  _dof_du_dot_du.resize(0);
740  _dof_du_dotdot_du.resize(0);
741  }
742 
743  for (auto & dof_values : _vector_tags_dof_u)
744  dof_values.resize(0);
745 
746  _has_dof_values = false;
747 }
748 
749 template <typename OutputType>
750 void
752 {
753  bool is_transient = _subproblem.isTransient();
754 
755  libmesh_assert(_dof_indices.size());
756 
757  auto & dof_values = _vector_tags_dof_u[_solution_tag];
758  _nodal_value = dof_values[0];
759  _nodal_value_array[0] = _nodal_value;
760 
761  if (is_transient)
762  {
763  if (oldestSolutionStateRequested() >= 1)
764  {
765  _nodal_value_old = _vector_tags_dof_u[_old_solution_tag][0];
766  _nodal_value_old_array[0] = _nodal_value_old;
767  }
768  if (oldestSolutionStateRequested() >= 2)
769  {
770  _nodal_value_older = _vector_tags_dof_u[_older_solution_tag][0];
771  _nodal_value_older_array[0] = _nodal_value_older;
772  }
773  if (_need_dof_values_dot)
774  _nodal_value_dot = _dof_values_dot[0];
775  if (_need_dof_values_dotdot)
776  _nodal_value_dotdot = _dof_values_dotdot[0];
777  if (_need_dof_values_dot_old)
778  _nodal_value_dot_old = _dof_values_dot_old[0];
779  if (_need_dof_values_dotdot_old)
780  _nodal_value_dotdot_old = _dof_values_dotdot_old[0];
781  }
782  if (_previous_nl_solution_tag != Moose::INVALID_TAG_ID)
783  _nodal_value_previous_nl = _vector_tags_dof_u[_previous_nl_solution_tag][0];
784 }
785 
786 template <>
787 void
789 {
790  bool is_transient = _subproblem.isTransient();
791 
792  auto n = _dof_indices.size();
793  libmesh_assert(n);
794 
795  auto & dof_values = _vector_tags_dof_u[_solution_tag];
796  for (decltype(n) i = 0; i < n; ++i)
797  _nodal_value(i) = dof_values[i];
798  _nodal_value_array[0] = _nodal_value;
799 
800  if (is_transient)
801  {
802  if (oldestSolutionStateRequested() >= 1)
803  {
804  auto & dof_values_old = _vector_tags_dof_u[_old_solution_tag];
805  for (decltype(n) i = 0; i < n; ++i)
806  _nodal_value_old(i) = dof_values_old[i];
807  _nodal_value_old_array[0] = _nodal_value_old;
808  }
809  if (oldestSolutionStateRequested() >= 2)
810  {
811  auto & dof_values_older = _vector_tags_dof_u[_older_solution_tag];
812  for (decltype(n) i = 0; i < n; ++i)
813  _nodal_value_older(i) = dof_values_older[i];
814  _nodal_value_older_array[0] = _nodal_value_older;
815  }
816  if (_need_dof_values_dot)
817  for (decltype(n) i = 0; i < n; ++i)
818  _nodal_value_dot(i) = _dof_values_dot[i];
819  if (_need_dof_values_dotdot)
820  for (decltype(n) i = 0; i < n; ++i)
821  _nodal_value_dotdot(i) = _dof_values_dotdot[i];
822  if (_need_dof_values_dot_old)
823  for (decltype(n) i = 0; i < n; ++i)
824  _nodal_value_dot_old(i) = _dof_values_dot_old[i];
825  if (_need_dof_values_dotdot_old)
826  for (decltype(n) i = 0; i < n; ++i)
827  _nodal_value_dotdot_old(i) = _dof_values_dotdot_old[i];
828  }
829  if (_previous_nl_solution_tag != Moose::INVALID_TAG_ID)
830  {
831  auto & dof_values_previous_nl = _vector_tags_dof_u[_previous_nl_solution_tag];
832  for (decltype(n) i = 0; i < n; ++i)
833  _nodal_value_previous_nl(i) = dof_values_previous_nl[i];
834  }
835 }
836 
837 template class MooseVariableDataBase<Real>;
virtual TagID getVectorTagID(const TagName &tag_name) const
Get a TagID from a TagName.
Definition: SubProblem.C:203
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
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:333
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
const FieldVariableValue & vectorTagValue(TagID tag) const
const DoFValue & dofValuesPreviousNL() const
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)