Line data Source code
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>
18 540940 : MooseVariableDataBase<OutputType>::MooseVariableDataBase(const MooseVariableField<OutputType> & var,
19 : SystemBase & sys,
20 : THREAD_ID tid)
21 540940 : : _sys(sys),
22 1081880 : _subproblem(_sys.subproblem()),
23 540940 : _tid(tid),
24 540940 : _dof_map(_sys.dofMap()),
25 540940 : _count(var.count()),
26 540940 : _has_dof_values(false),
27 540940 : _max_state(0),
28 540940 : _solution_tag(_subproblem.getVectorTagID(Moose::SOLUTION_TAG)),
29 540940 : _old_solution_tag(Moose::INVALID_TAG_ID),
30 540940 : _older_solution_tag(Moose::INVALID_TAG_ID),
31 540940 : _previous_nl_solution_tag(Moose::INVALID_TAG_ID),
32 540940 : _need_u_dot(false),
33 540940 : _need_u_dotdot(false),
34 540940 : _need_u_dot_old(false),
35 540940 : _need_u_dotdot_old(false),
36 540940 : _need_du_dot_du(false),
37 540940 : _need_du_dotdot_du(false),
38 540940 : _need_grad_dot(false),
39 540940 : _need_grad_dotdot(false),
40 540940 : _need_dof_values_dot(false),
41 540940 : _need_dof_values_dotdot(false),
42 540940 : _need_dof_values_dot_old(false),
43 540940 : _need_dof_values_dotdot_old(false),
44 540940 : _need_dof_du_dot_du(false),
45 540940 : _need_dof_du_dotdot_du(false),
46 1081880 : _var(var)
47 : {
48 540940 : 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 540940 : const auto max_future_num_vector_tags = num_vector_tags + 2;
54 :
55 540940 : _vector_tags_dof_u.reserve(max_future_num_vector_tags);
56 540940 : _vector_tags_dof_u.resize(num_vector_tags);
57 540940 : _need_vector_tag_dof_u.reserve(max_future_num_vector_tags);
58 540940 : _need_vector_tag_dof_u.resize(num_vector_tags, false);
59 :
60 540940 : _need_vector_tag_u.reserve(max_future_num_vector_tags);
61 540940 : _need_vector_tag_u.resize(num_vector_tags, false);
62 540940 : _vector_tag_u.reserve(max_future_num_vector_tags);
63 540940 : _vector_tag_u.resize(num_vector_tags);
64 :
65 540940 : _need_vector_tag_grad.reserve(max_future_num_vector_tags);
66 540940 : _need_vector_tag_grad.resize(num_vector_tags, false);
67 540940 : _vector_tag_grad.reserve(max_future_num_vector_tags);
68 540940 : _vector_tag_grad.resize(num_vector_tags);
69 :
70 : // Always fetch the dof values for the solution tag
71 540940 : const auto soln_tag = _subproblem.getVectorTagID(Moose::SOLUTION_TAG);
72 540940 : _need_vector_tag_dof_u[soln_tag] = true;
73 540940 : _need_vector_tag_u[soln_tag] = true;
74 540940 : 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).
78 540940 : _nodal_value_array.resize(1);
79 540940 : _nodal_value_old_array.resize(1);
80 540940 : _nodal_value_older_array.resize(1);
81 540940 : }
82 :
83 : template <typename OutputType>
84 : void
85 391333 : MooseVariableDataBase<OutputType>::sizeMatrixTagData()
86 : {
87 391333 : auto num_matrix_tags = _subproblem.numMatrixTags();
88 :
89 391333 : _matrix_tags_dof_u.resize(num_matrix_tags);
90 391333 : _need_matrix_tag_dof_u.resize(num_matrix_tags, false);
91 :
92 391333 : _need_matrix_tag_u.resize(num_matrix_tags, false);
93 391333 : _matrix_tag_u.resize(num_matrix_tags);
94 391333 : }
95 :
96 : template <typename OutputType>
97 : const typename MooseVariableDataBase<OutputType>::DofValues &
98 433 : MooseVariableDataBase<OutputType>::nodalVectorTagValue(TagID tag) const
99 : {
100 433 : if (isNodal())
101 : {
102 433 : if (tag >= _need_vector_tag_dof_u.size())
103 0 : const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
104 :
105 433 : _need_vector_tag_dof_u[tag] = true;
106 :
107 433 : if (_sys.hasVector(tag))
108 433 : return _vector_tags_dof_u[tag];
109 : else
110 0 : mooseError(
111 0 : "Tag ", tag, " is not associated with any vector for nodal variable ", _var.name());
112 : }
113 : else
114 0 : mooseError("Nodal values can be requested only on nodal variables, variable '",
115 0 : _var.name(),
116 : "' is not nodal.");
117 : }
118 :
119 : template <typename OutputType>
120 : const typename MooseVariableDataBase<OutputType>::DofValues &
121 225 : MooseVariableDataBase<OutputType>::nodalMatrixTagValue(TagID tag) const
122 : {
123 225 : if (isNodal())
124 : {
125 225 : if (tag >= _matrix_tags_dof_u.size())
126 : {
127 0 : _need_matrix_tag_dof_u.resize(tag + 1, false);
128 0 : const_cast<MooseVariableDataBase<OutputType> *>(this)->_matrix_tags_dof_u.resize(tag + 1);
129 : }
130 :
131 225 : _need_matrix_tag_dof_u[tag] = true;
132 :
133 225 : if (_sys.hasMatrix(tag))
134 225 : return _matrix_tags_dof_u[tag];
135 : else
136 0 : mooseError(
137 0 : "Tag ", tag, " is not associated with any matrix for nodal variable ", _var.name());
138 : }
139 : else
140 0 : mooseError("Nodal values can be requested only on nodal variables, variable '",
141 0 : _var.name(),
142 : "' is not nodal.");
143 : }
144 :
145 : template <typename OutputType>
146 : void
147 490 : MooseVariableDataBase<OutputType>::resizeVectorTagData(TagID tag)
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 6370 : auto check_capacity = [tag](const auto & vector_to_check)
157 : {
158 2940 : if (tag + 1 > vector_to_check.capacity())
159 0 : mooseError("New size greater than tag capacity. This will cause reallocation which will "
160 : "invalidate any stored references.");
161 : };
162 490 : check_capacity(_need_vector_tag_dof_u);
163 490 : check_capacity(_need_vector_tag_u);
164 490 : check_capacity(_need_vector_tag_grad);
165 490 : check_capacity(_vector_tags_dof_u);
166 490 : check_capacity(_vector_tag_u);
167 490 : check_capacity(_vector_tag_grad);
168 :
169 490 : _need_vector_tag_dof_u.resize(tag + 1, false);
170 490 : _need_vector_tag_u.resize(tag + 1, false);
171 490 : _need_vector_tag_grad.resize(tag + 1, false);
172 490 : _vector_tags_dof_u.resize(tag + 1);
173 490 : _vector_tag_u.resize(tag + 1);
174 490 : _vector_tag_grad.resize(tag + 1);
175 490 : }
176 :
177 : template <typename OutputType>
178 : const typename MooseVariableDataBase<OutputType>::FieldVariableValue &
179 293915 : MooseVariableDataBase<OutputType>::vectorTagValue(TagID tag) const
180 : {
181 293915 : if (tag >= _need_vector_tag_u.size())
182 117 : const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
183 :
184 293915 : _var.requireQpComputations();
185 :
186 293915 : _need_vector_tag_u[tag] = true;
187 :
188 293915 : if (_sys.hasVector(tag))
189 293915 : return _vector_tag_u[tag];
190 : else
191 0 : mooseError("Tag ", tag, " is not associated with any vector for variable ", _var.name());
192 : }
193 :
194 : template <typename OutputType>
195 : const typename MooseVariableDataBase<OutputType>::DofValues &
196 917225 : MooseVariableDataBase<OutputType>::vectorTagDofValue(TagID tag) const
197 : {
198 917225 : if (tag >= _need_vector_tag_dof_u.size())
199 156 : const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
200 :
201 917225 : _var.requireQpComputations();
202 :
203 917225 : _need_vector_tag_dof_u[tag] = true;
204 :
205 917225 : if (_sys.hasVector(tag))
206 917225 : return _vector_tags_dof_u[tag];
207 : else
208 0 : mooseError("Tag ", tag, " is not associated with any vector for variable ", _var.name());
209 : }
210 :
211 : template <typename OutputType>
212 : const typename MooseVariableDataBase<OutputType>::FieldVariableGradient &
213 128898 : MooseVariableDataBase<OutputType>::vectorTagGradient(TagID tag) const
214 : {
215 128898 : if (tag >= _need_vector_tag_grad.size())
216 13 : const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
217 :
218 128898 : _var.requireQpComputations();
219 :
220 128898 : _need_vector_tag_grad[tag] = true;
221 :
222 128898 : if (_sys.hasVector(tag))
223 128898 : return _vector_tag_grad[tag];
224 : else
225 0 : mooseError("Tag ", tag, " is not associated with any vector for variable ", _var.name());
226 : }
227 :
228 : template <typename OutputType>
229 : const typename MooseVariableDataBase<OutputType>::FieldVariableValue &
230 48 : MooseVariableDataBase<OutputType>::matrixTagValue(TagID tag) const
231 : {
232 48 : if (tag >= _matrix_tag_u.size())
233 : {
234 0 : _need_matrix_tag_u.resize(tag + 1, false);
235 0 : const_cast<MooseVariableDataBase<OutputType> *>(this)->_matrix_tag_u.resize(tag + 1);
236 : }
237 :
238 48 : _var.requireQpComputations();
239 :
240 48 : _need_matrix_tag_u[tag] = true;
241 :
242 48 : if (_sys.hasMatrix(tag))
243 48 : return _matrix_tag_u[tag];
244 : else
245 0 : mooseError("Tag ", tag, " is not associated with any matrix for variable ", _var.name());
246 : }
247 :
248 : template <typename OutputType>
249 : unsigned int
250 441120040 : MooseVariableDataBase<OutputType>::oldestSolutionStateRequested() const
251 : {
252 441120040 : return _max_state;
253 : }
254 :
255 : template <typename OutputType>
256 : void
257 35944 : MooseVariableDataBase<OutputType>::needSolutionState(const unsigned int state)
258 : {
259 35944 : if (state > _max_state)
260 : {
261 15750 : _sys.needSolutionState(state);
262 15750 : _max_state = state;
263 : }
264 35944 : }
265 :
266 : template <typename OutputType>
267 : template <typename ReturnType, typename Functor>
268 : const ReturnType &
269 1339172 : MooseVariableDataBase<OutputType>::stateToTagHelper(const Moose::SolutionState state,
270 : Functor functor)
271 : {
272 1339172 : if (state > 0)
273 : {
274 : // We need to request all states that are between current and the requested state
275 35944 : stateToTagHelper<ReturnType>(Moose::SolutionState(static_cast<int>(state) - 1), functor);
276 35944 : needSolutionState(cast_int<unsigned int>(state));
277 : }
278 :
279 1339172 : switch (state)
280 : {
281 1303152 : case Moose::Current:
282 1303152 : return functor(_subproblem.getVectorTagID(Moose::SOLUTION_TAG));
283 :
284 24777 : case Moose::Old:
285 : {
286 24777 : _old_solution_tag = _subproblem.getVectorTagID(Moose::OLD_SOLUTION_TAG);
287 24777 : insertSolutionTag(_old_solution_tag);
288 24777 : return functor(_old_solution_tag);
289 : }
290 :
291 11167 : case Moose::Older:
292 : {
293 11167 : _older_solution_tag = _subproblem.getVectorTagID(Moose::OLDER_SOLUTION_TAG);
294 11167 : insertSolutionTag(_older_solution_tag);
295 11167 : return functor(_older_solution_tag);
296 : }
297 :
298 76 : case Moose::PreviousNL:
299 : {
300 76 : _previous_nl_solution_tag = _subproblem.getVectorTagID(Moose::PREVIOUS_NL_SOLUTION_TAG);
301 76 : insertSolutionTag(_previous_nl_solution_tag);
302 76 : return functor(_previous_nl_solution_tag);
303 : }
304 :
305 0 : 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 0 : mooseError("Unknown SolutionState!");
309 : }
310 : }
311 :
312 : template <typename OutputType>
313 : const typename MooseVariableDataBase<OutputType>::FieldVariableValue &
314 258580 : MooseVariableDataBase<OutputType>::sln(Moose::SolutionState state) const
315 : {
316 551786 : auto functor = [this](TagID tag_id) -> const FieldVariableValue &
317 293206 : { return vectorTagValue(tag_id); };
318 :
319 258580 : _var.requireQpComputations();
320 :
321 : return const_cast<MooseVariableDataBase<OutputType> *>(this)
322 517160 : ->stateToTagHelper<FieldVariableValue>(state, functor);
323 : }
324 :
325 : template <typename OutputType>
326 : const typename MooseVariableDataBase<OutputType>::FieldVariableGradient &
327 127942 : MooseVariableDataBase<OutputType>::gradSln(Moose::SolutionState state) const
328 : {
329 256814 : auto functor = [this](TagID tag_id) -> const FieldVariableGradient &
330 128872 : { return vectorTagGradient(tag_id); };
331 :
332 127942 : _var.requireQpComputations();
333 :
334 : return const_cast<MooseVariableDataBase<OutputType> *>(this)
335 255884 : ->stateToTagHelper<FieldVariableGradient>(state, functor);
336 : }
337 :
338 : template <typename OutputType>
339 : const typename MooseVariableDataBase<OutputType>::DofValues &
340 916706 : MooseVariableDataBase<OutputType>::vectorTagDofValue(Moose::SolutionState state) const
341 : {
342 1833800 : auto functor = [this](TagID tag_id) -> const DofValues & { return vectorTagDofValue(tag_id); };
343 :
344 916706 : _var.requireQpComputations();
345 :
346 916706 : return const_cast<MooseVariableDataBase<OutputType> *>(this)->stateToTagHelper<DofValues>(
347 1833412 : state, functor);
348 : }
349 :
350 : template <typename OutputType>
351 : const typename MooseVariableDataBase<OutputType>::DofValues &
352 892065 : MooseVariableDataBase<OutputType>::dofValues() const
353 : {
354 892065 : return vectorTagDofValue(Moose::Current);
355 : }
356 :
357 : template <typename OutputType>
358 : const typename MooseVariableDataBase<OutputType>::DofValues &
359 128 : MooseVariableDataBase<OutputType>::dofValuesOld() const
360 : {
361 128 : return vectorTagDofValue(Moose::Old);
362 : }
363 :
364 : template <typename OutputType>
365 : const typename MooseVariableDataBase<OutputType>::DofValues &
366 52 : MooseVariableDataBase<OutputType>::dofValuesOlder() const
367 : {
368 52 : return vectorTagDofValue(Moose::Older);
369 : }
370 :
371 : template <typename OutputType>
372 : const typename MooseVariableDataBase<OutputType>::DofValues &
373 0 : MooseVariableDataBase<OutputType>::dofValuesPreviousNL() const
374 : {
375 0 : return vectorTagDofValue(Moose::PreviousNL);
376 : }
377 :
378 : template <typename OutputType>
379 : void
380 46037359 : MooseVariableDataBase<OutputType>::setNodalValue(const OutputType & value, unsigned int idx)
381 : {
382 46037359 : 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 46037359 : dof_values[idx] = value; // update variable nodal value
385 46037359 : _has_dof_values = true;
386 46037359 : _nodal_value = value;
387 :
388 : // Update the qp values as well
389 46037359 : auto & u = _vector_tag_u[_solution_tag];
390 229006231 : for (unsigned int qp = 0; qp < u.size(); qp++)
391 182968872 : u[qp] = value;
392 46037359 : }
393 :
394 : template <>
395 : void
396 8315 : MooseVariableDataBase<RealVectorValue>::setNodalValue(const RealVectorValue & value,
397 : unsigned int idx)
398 : {
399 8315 : auto & dof_values = _vector_tags_dof_u[_solution_tag];
400 28449 : for (decltype(idx) i = 0; i < dof_values.size(); ++i, ++idx)
401 20134 : dof_values[idx] = value(i);
402 :
403 8315 : _has_dof_values = true;
404 8315 : _nodal_value = value;
405 8315 : }
406 :
407 : template <typename OutputType>
408 : void
409 49784430 : MooseVariableDataBase<OutputType>::insert(NumericVector<Number> & residual)
410 : {
411 49784430 : if (_has_dof_values)
412 : {
413 48677467 : 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 48677467 : residual.insert(&dof_values[0], _dof_indices);
417 : }
418 49784430 : }
419 :
420 : template <>
421 : void
422 635442 : MooseVariableDataBase<RealEigenVector>::insert(NumericVector<Number> & residual)
423 : {
424 635442 : if (_has_dof_values)
425 : {
426 635442 : 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 635442 : const auto n_shapes = _dof_indices.size() / _count;
430 2467820 : for (const auto indx : index_range(_dof_indices))
431 : {
432 1832378 : const auto i = indx % n_shapes;
433 1832378 : const auto j = indx / n_shapes;
434 1832378 : residual.set(_dof_indices[indx], dof_values[i](j));
435 : }
436 : }
437 635442 : }
438 :
439 : template <typename OutputType>
440 : void
441 1959703 : MooseVariableDataBase<OutputType>::add(NumericVector<Number> & residual)
442 : {
443 1959703 : if (_has_dof_values)
444 : {
445 33256 : const auto & dof_values = _vector_tags_dof_u[_solution_tag];
446 33256 : residual.add_vector(&dof_values[0], _dof_indices);
447 : }
448 1959703 : }
449 :
450 : template <>
451 : void
452 0 : MooseVariableDataBase<RealEigenVector>::add(NumericVector<Number> & residual)
453 : {
454 0 : if (_has_dof_values)
455 : {
456 0 : 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 0 : const auto n_shapes = _dof_indices.size() / _count;
460 0 : for (const auto indx : index_range(_dof_indices))
461 : {
462 0 : const auto i = indx % n_shapes;
463 0 : const auto j = indx / n_shapes;
464 0 : residual.add(_dof_indices[indx], dof_values[i](j));
465 : }
466 : }
467 0 : }
468 :
469 : template <typename OutputType>
470 : const OutputType &
471 1239 : MooseVariableDataBase<OutputType>::nodalValue(Moose::SolutionState state) const
472 : {
473 1239 : if (isNodal())
474 : {
475 : // Request the correct solution states and data members
476 1239 : vectorTagDofValue(state);
477 1239 : switch (state)
478 : {
479 1239 : case Moose::Current:
480 1239 : return _nodal_value;
481 :
482 0 : case Moose::Old:
483 0 : return _nodal_value_old;
484 :
485 0 : case Moose::Older:
486 0 : return _nodal_value_older;
487 :
488 0 : case Moose::PreviousNL:
489 0 : return _nodal_value_previous_nl;
490 :
491 0 : 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 0 : mooseError("Unknown SolutionState!");
495 : }
496 : }
497 : else
498 0 : mooseError("Nodal values can be requested only on nodal variables, variable '",
499 0 : _var.name(),
500 : "' is not nodal.");
501 : }
502 :
503 : template <typename OutputType>
504 : const MooseArray<OutputType> &
505 23222 : MooseVariableDataBase<OutputType>::nodalValueArray(Moose::SolutionState state) const
506 : {
507 23222 : if (isNodal())
508 : {
509 : // Request the correct solution states and data members
510 23222 : vectorTagDofValue(state);
511 23222 : switch (state)
512 : {
513 23079 : case Moose::Current:
514 23079 : return _nodal_value_array;
515 :
516 130 : case Moose::Old:
517 130 : return _nodal_value_old_array;
518 :
519 13 : case Moose::Older:
520 13 : return _nodal_value_older_array;
521 :
522 0 : default:
523 0 : mooseError("No current support for PreviousNL for nodal value array");
524 : }
525 : }
526 : else
527 0 : mooseError("Nodal values can be requested only on nodal variables, variable '",
528 0 : _var.name(),
529 : "' is not nodal.");
530 : }
531 :
532 : template <typename OutputType>
533 : void
534 1041979612 : MooseVariableDataBase<OutputType>::fetchDofValues()
535 : {
536 1041979612 : bool is_transient = _subproblem.isTransient();
537 :
538 1041979612 : auto n = _dof_indices.size();
539 : libmesh_assert(n);
540 :
541 1041979612 : if (is_transient)
542 : {
543 823098706 : if (_need_u_dot || _need_grad_dot || _need_dof_values_dot)
544 : {
545 : libmesh_assert(_sys.solutionUDot());
546 305784376 : _dof_values_dot.resize(n);
547 305784376 : _sys.solutionUDot()->get(_dof_indices, &_dof_values_dot[0]);
548 : }
549 823098706 : if (_need_u_dotdot || _need_grad_dotdot || _need_dof_values_dotdot)
550 : {
551 : libmesh_assert(_sys.solutionUDotDot());
552 13246 : _dof_values_dotdot.resize(n);
553 13246 : _sys.solutionUDotDot()->get(_dof_indices, &_dof_values_dotdot[0]);
554 : }
555 823098706 : if (_need_u_dot_old || _need_dof_values_dot_old)
556 : {
557 : libmesh_assert(_sys.solutionUDotOld());
558 0 : _dof_values_dot_old.resize(n);
559 0 : _sys.solutionUDotOld()->get(_dof_indices, &_dof_values_dot_old[0]);
560 : }
561 823098706 : if (_need_u_dotdot_old || _need_dof_values_dotdot_old)
562 : {
563 : libmesh_assert(_sys.solutionUDotDotOld());
564 0 : _dof_values_dotdot_old.resize(n);
565 0 : _sys.solutionUDotDotOld()->get(_dof_indices, &_dof_values_dotdot_old[0]);
566 : }
567 : }
568 :
569 2096127175 : for (auto tag : _required_vector_tags)
570 1054147563 : if (_need_vector_tag_u[tag] || _need_vector_tag_grad[tag] || _need_vector_tag_dof_u[tag])
571 1053645364 : if ((_subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_RESIDUAL &&
572 2107211199 : _subproblem.safeAccessTaggedVectors()) ||
573 1053565835 : _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 1053645364 : if (_sys.hasVector(tag) /* && _sys.getVector(tag).closed()*/)
580 : {
581 1053645364 : auto & vec = _sys.getVector(tag);
582 1053645364 : _vector_tags_dof_u[tag].resize(n);
583 1053645364 : vec.get(_dof_indices, &_vector_tags_dof_u[tag][0]);
584 : }
585 : }
586 :
587 1041979612 : if (_subproblem.safeAccessTaggedMatrices())
588 : {
589 : auto & active_coupleable_matrix_tags =
590 831441846 : _subproblem.getActiveFEVariableCoupleableMatrixTags(_tid);
591 :
592 831717473 : for (auto tag : active_coupleable_matrix_tags)
593 : {
594 275627 : _matrix_tags_dof_u[tag].resize(n);
595 275627 : if (_need_matrix_tag_dof_u[tag] || _need_matrix_tag_u[tag])
596 69085 : 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 69085 : auto & mat = _sys.getMatrix(tag);
601 138426 : for (unsigned i = 0; i < n; i++)
602 69341 : _matrix_tags_dof_u[tag][i] = mat(_dof_indices[i], _dof_indices[i]);
603 : }
604 : }
605 : }
606 :
607 1041979612 : if (_need_du_dot_du || _need_dof_du_dot_du)
608 : {
609 305778864 : _dof_du_dot_du.resize(n);
610 1408915212 : for (decltype(n) i = 0; i < n; ++i)
611 1103136348 : _dof_du_dot_du[i] = _sys.duDotDu(_var.number());
612 : }
613 1041979612 : if (_need_du_dotdot_du || _need_dof_du_dotdot_du)
614 : {
615 9646 : _dof_du_dotdot_du.resize(n);
616 56942 : for (decltype(n) i = 0; i < n; ++i)
617 47296 : _dof_du_dotdot_du[i] = _sys.duDotDotDu();
618 : }
619 1041979612 : }
620 :
621 : template <typename OutputType>
622 : void
623 8725458 : MooseVariableDataBase<OutputType>::getArrayDofValues(const NumericVector<Number> & sol,
624 : const unsigned int nshapes,
625 : MooseArray<RealEigenVector> & dof_values) const
626 : {
627 8725458 : dof_values.resize(nshapes);
628 36868658 : for (const auto i : make_range(nshapes))
629 : {
630 28143200 : dof_values[i].resize(_count);
631 94909877 : for (const auto j : make_range(_count))
632 66766677 : dof_values[i](j) = sol(_dof_indices[j * nshapes + i]);
633 : }
634 8725458 : }
635 :
636 : template <>
637 : void
638 5904054 : MooseVariableDataBase<RealEigenVector>::fetchDofValues()
639 : {
640 5904054 : bool is_transient = _subproblem.isTransient();
641 :
642 5904054 : auto n = _dof_indices.size() / _count;
643 : libmesh_assert(n);
644 :
645 5904054 : if (is_transient)
646 : {
647 5551188 : if (_need_u_dot || _need_grad_dot || _need_dof_values_dot)
648 : {
649 : libmesh_assert(_sys.solutionUDot());
650 2820826 : getArrayDofValues(*_sys.solutionUDot(), n, _dof_values_dot);
651 : }
652 5551188 : if (_need_u_dotdot || _need_grad_dotdot || _need_dof_values_dotdot)
653 : {
654 : libmesh_assert(_sys.solutionUDotDot());
655 0 : getArrayDofValues(*_sys.solutionUDot(), n, _dof_values_dotdot);
656 : }
657 5551188 : if (_need_u_dot_old || _need_dof_values_dot_old)
658 : {
659 : libmesh_assert(_sys.solutionUDotOld());
660 0 : getArrayDofValues(*_sys.solutionUDotOld(), n, _dof_values_dot_old);
661 : }
662 5551188 : if (_need_u_dotdot_old || _need_dof_values_dotdot_old)
663 : {
664 : libmesh_assert(_sys.solutionUDotDotOld());
665 0 : getArrayDofValues(*_sys.solutionUDotDotOld(), n, _dof_values_dotdot_old);
666 : }
667 : }
668 :
669 11809648 : for (auto tag : _required_vector_tags)
670 5905594 : if ((_subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_RESIDUAL &&
671 11809648 : _subproblem.safeAccessTaggedVectors()) ||
672 5904054 : _subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_SOLUTION)
673 : // tag is defined on problem but may not be used by a system
674 5905594 : if (_sys.hasVector(tag))
675 : {
676 : mooseAssert(_sys.getVector(tag).closed(),
677 : "Vector with tag '" + std::to_string(tag) + "' should be closed");
678 5904632 : getArrayDofValues(_sys.getVector(tag), n, _vector_tags_dof_u[tag]);
679 : }
680 :
681 5904054 : if (_subproblem.safeAccessTaggedMatrices())
682 : {
683 : auto & active_coupleable_matrix_tags =
684 4915411 : _subproblem.getActiveFEVariableCoupleableMatrixTags(_tid);
685 4915411 : for (auto tag : active_coupleable_matrix_tags)
686 : {
687 0 : _matrix_tags_dof_u[tag].resize(n);
688 0 : if (_need_matrix_tag_dof_u[tag] || _need_matrix_tag_u[tag])
689 0 : 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 0 : auto & mat = _sys.getMatrix(tag);
694 0 : for (unsigned i = 0; i < n; i++)
695 0 : for (unsigned j = 0; j < _count; j++)
696 0 : _matrix_tags_dof_u[tag][i](j) = mat(_dof_indices[i] + j, _dof_indices[i] + j);
697 : }
698 : }
699 : }
700 :
701 5904054 : if (_need_du_dot_du || _need_dof_du_dot_du)
702 : {
703 2820826 : _dof_du_dot_du.resize(n);
704 12824227 : for (decltype(n) i = 0; i < n; ++i)
705 10003401 : _dof_du_dot_du[i] = _sys.duDotDu(_var.number());
706 : }
707 5904054 : if (_need_du_dotdot_du || _need_dof_du_dotdot_du)
708 : {
709 0 : _dof_du_dotdot_du.resize(n);
710 0 : for (decltype(n) i = 0; i < n; ++i)
711 0 : _dof_du_dotdot_du[i] = _sys.duDotDotDu();
712 : }
713 5904054 : }
714 :
715 : template <typename OutputType>
716 : void
717 204 : MooseVariableDataBase<OutputType>::zeroSizeDofValues()
718 : {
719 204 : if (_subproblem.isTransient())
720 : {
721 168 : _dof_values_dot.resize(0);
722 168 : _dof_values_dotdot.resize(0);
723 168 : _dof_values_dot_old.resize(0);
724 168 : _dof_values_dotdot_old.resize(0);
725 168 : _dof_du_dot_du.resize(0);
726 168 : _dof_du_dotdot_du.resize(0);
727 : }
728 :
729 1488 : for (auto & dof_values : _vector_tags_dof_u)
730 1284 : dof_values.resize(0);
731 :
732 204 : _has_dof_values = false;
733 204 : }
734 :
735 : template <typename OutputType>
736 : void
737 246462825 : MooseVariableDataBase<OutputType>::assignNodalValue()
738 : {
739 246462825 : bool is_transient = _subproblem.isTransient();
740 : libmesh_assert(_dof_indices.size());
741 :
742 246462825 : auto & dof_values = _vector_tags_dof_u[_solution_tag];
743 246462825 : _nodal_value = dof_values[0];
744 246462825 : _nodal_value_array[0] = _nodal_value;
745 :
746 246462825 : if (is_transient)
747 : {
748 220077665 : if (oldestSolutionStateRequested() >= 1)
749 : {
750 4582564 : _nodal_value_old = _vector_tags_dof_u[_old_solution_tag][0];
751 4582564 : _nodal_value_old_array[0] = _nodal_value_old;
752 : }
753 220077665 : if (oldestSolutionStateRequested() >= 2)
754 : {
755 1606903 : _nodal_value_older = _vector_tags_dof_u[_older_solution_tag][0];
756 1606903 : _nodal_value_older_array[0] = _nodal_value_older;
757 : }
758 220077665 : if (_need_dof_values_dot)
759 1406446 : _nodal_value_dot = _dof_values_dot[0];
760 220077665 : if (_need_dof_values_dotdot)
761 0 : _nodal_value_dotdot = _dof_values_dotdot[0];
762 220077665 : if (_need_dof_values_dot_old)
763 0 : _nodal_value_dot_old = _dof_values_dot_old[0];
764 220077665 : if (_need_dof_values_dotdot_old)
765 0 : _nodal_value_dotdot_old = _dof_values_dotdot_old[0];
766 : }
767 246462825 : if (_previous_nl_solution_tag != Moose::INVALID_TAG_ID)
768 47014 : _nodal_value_previous_nl = _vector_tags_dof_u[_previous_nl_solution_tag][0];
769 246462825 : }
770 :
771 : template <>
772 : void
773 467911 : MooseVariableDataBase<RealVectorValue>::assignNodalValue()
774 : {
775 467911 : bool is_transient = _subproblem.isTransient();
776 :
777 467911 : auto n = _dof_indices.size();
778 : libmesh_assert(n);
779 :
780 467911 : auto & dof_values = _vector_tags_dof_u[_solution_tag];
781 1535513 : for (decltype(n) i = 0; i < n; ++i)
782 1067602 : _nodal_value(i) = dof_values[i];
783 467911 : _nodal_value_array[0] = _nodal_value;
784 :
785 467911 : if (is_transient)
786 : {
787 242945 : if (oldestSolutionStateRequested() >= 1)
788 : {
789 42537 : auto & dof_values_old = _vector_tags_dof_u[_old_solution_tag];
790 167123 : for (decltype(n) i = 0; i < n; ++i)
791 124586 : _nodal_value_old(i) = dof_values_old[i];
792 42537 : _nodal_value_old_array[0] = _nodal_value_old;
793 : }
794 242945 : if (oldestSolutionStateRequested() >= 2)
795 : {
796 3025 : auto & dof_values_older = _vector_tags_dof_u[_older_solution_tag];
797 9075 : for (decltype(n) i = 0; i < n; ++i)
798 6050 : _nodal_value_older(i) = dof_values_older[i];
799 3025 : _nodal_value_older_array[0] = _nodal_value_older;
800 : }
801 242945 : if (_need_dof_values_dot)
802 0 : for (decltype(n) i = 0; i < n; ++i)
803 0 : _nodal_value_dot(i) = _dof_values_dot[i];
804 242945 : if (_need_dof_values_dotdot)
805 0 : for (decltype(n) i = 0; i < n; ++i)
806 0 : _nodal_value_dotdot(i) = _dof_values_dotdot[i];
807 242945 : if (_need_dof_values_dot_old)
808 0 : for (decltype(n) i = 0; i < n; ++i)
809 0 : _nodal_value_dot_old(i) = _dof_values_dot_old[i];
810 242945 : if (_need_dof_values_dotdot_old)
811 0 : for (decltype(n) i = 0; i < n; ++i)
812 0 : _nodal_value_dotdot_old(i) = _dof_values_dotdot_old[i];
813 : }
814 467911 : if (_previous_nl_solution_tag != Moose::INVALID_TAG_ID)
815 : {
816 0 : auto & dof_values_previous_nl = _vector_tags_dof_u[_previous_nl_solution_tag];
817 0 : for (decltype(n) i = 0; i < n; ++i)
818 0 : _nodal_value_previous_nl(i) = dof_values_previous_nl[i];
819 : }
820 467911 : }
821 :
822 : template class MooseVariableDataBase<Real>;
823 : template class MooseVariableDataBase<RealVectorValue>;
824 : template class MooseVariableDataBase<RealEigenVector>;
|