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 541528 : MooseVariableDataBase<OutputType>::MooseVariableDataBase(const MooseVariableField<OutputType> & var,
19 : SystemBase & sys,
20 : THREAD_ID tid)
21 541528 : : _sys(sys),
22 1083056 : _subproblem(_sys.subproblem()),
23 541528 : _tid(tid),
24 541528 : _dof_map(_sys.dofMap()),
25 541528 : _count(var.count()),
26 541528 : _has_dof_values(false),
27 541528 : _max_state(0),
28 541528 : _solution_tag(_subproblem.getVectorTagID(Moose::SOLUTION_TAG)),
29 541528 : _old_solution_tag(Moose::INVALID_TAG_ID),
30 541528 : _older_solution_tag(Moose::INVALID_TAG_ID),
31 541528 : _previous_nl_solution_tag(Moose::INVALID_TAG_ID),
32 541528 : _need_u_dot(false),
33 541528 : _need_u_dotdot(false),
34 541528 : _need_u_dot_old(false),
35 541528 : _need_u_dotdot_old(false),
36 541528 : _need_du_dot_du(false),
37 541528 : _need_du_dotdot_du(false),
38 541528 : _need_grad_dot(false),
39 541528 : _need_grad_dotdot(false),
40 541528 : _need_dof_values_dot(false),
41 541528 : _need_dof_values_dotdot(false),
42 541528 : _need_dof_values_dot_old(false),
43 541528 : _need_dof_values_dotdot_old(false),
44 541528 : _need_dof_du_dot_du(false),
45 541528 : _need_dof_du_dotdot_du(false),
46 1083056 : _var(var)
47 : {
48 541528 : 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 541528 : const auto max_future_num_vector_tags = num_vector_tags + 2;
54 :
55 541528 : _vector_tags_dof_u.reserve(max_future_num_vector_tags);
56 541528 : _vector_tags_dof_u.resize(num_vector_tags);
57 541528 : _need_vector_tag_dof_u.reserve(max_future_num_vector_tags);
58 541528 : _need_vector_tag_dof_u.resize(num_vector_tags, false);
59 :
60 541528 : _need_vector_tag_u.reserve(max_future_num_vector_tags);
61 541528 : _need_vector_tag_u.resize(num_vector_tags, false);
62 541528 : _vector_tag_u.reserve(max_future_num_vector_tags);
63 541528 : _vector_tag_u.resize(num_vector_tags);
64 :
65 541528 : _need_vector_tag_grad.reserve(max_future_num_vector_tags);
66 541528 : _need_vector_tag_grad.resize(num_vector_tags, false);
67 541528 : _vector_tag_grad.reserve(max_future_num_vector_tags);
68 541528 : _vector_tag_grad.resize(num_vector_tags);
69 :
70 : // Always fetch the dof values for the solution tag
71 541528 : const auto soln_tag = _subproblem.getVectorTagID(Moose::SOLUTION_TAG);
72 541528 : _need_vector_tag_dof_u[soln_tag] = true;
73 541528 : _need_vector_tag_u[soln_tag] = true;
74 541528 : 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 541528 : _nodal_value_array.resize(1);
79 541528 : _nodal_value_old_array.resize(1);
80 541528 : _nodal_value_older_array.resize(1);
81 541528 : }
82 :
83 : template <typename OutputType>
84 : void
85 391921 : MooseVariableDataBase<OutputType>::sizeMatrixTagData()
86 : {
87 391921 : auto num_matrix_tags = _subproblem.numMatrixTags();
88 :
89 391921 : _matrix_tags_dof_u.resize(num_matrix_tags);
90 391921 : _need_matrix_tag_dof_u.resize(num_matrix_tags, false);
91 :
92 391921 : _need_matrix_tag_u.resize(num_matrix_tags, false);
93 391921 : _matrix_tag_u.resize(num_matrix_tags);
94 391921 : }
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 294140 : MooseVariableDataBase<OutputType>::vectorTagValue(TagID tag) const
180 : {
181 294140 : if (tag >= _need_vector_tag_u.size())
182 117 : const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
183 :
184 294140 : _var.requireQpComputations();
185 :
186 294140 : _need_vector_tag_u[tag] = true;
187 :
188 294140 : if (_sys.hasVector(tag))
189 294140 : 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 917261 : MooseVariableDataBase<OutputType>::vectorTagDofValue(TagID tag) const
197 : {
198 917261 : if (tag >= _need_vector_tag_dof_u.size())
199 156 : const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
200 :
201 917261 : _var.requireQpComputations();
202 :
203 917261 : _need_vector_tag_dof_u[tag] = true;
204 :
205 917261 : if (_sys.hasVector(tag))
206 917261 : 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 129123 : MooseVariableDataBase<OutputType>::vectorTagGradient(TagID tag) const
214 : {
215 129123 : if (tag >= _need_vector_tag_grad.size())
216 13 : const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
217 :
218 129123 : _var.requireQpComputations();
219 :
220 129123 : _need_vector_tag_grad[tag] = true;
221 :
222 129123 : if (_sys.hasVector(tag))
223 129123 : 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 441126066 : MooseVariableDataBase<OutputType>::oldestSolutionStateRequested() const
251 : {
252 441126066 : 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 1339658 : MooseVariableDataBase<OutputType>::stateToTagHelper(const Moose::SolutionState state,
270 : Functor functor)
271 : {
272 1339658 : 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 1339658 : switch (state)
280 : {
281 1303638 : case Moose::Current:
282 1303638 : 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 258805 : MooseVariableDataBase<OutputType>::sln(Moose::SolutionState state) const
315 : {
316 552236 : auto functor = [this](TagID tag_id) -> const FieldVariableValue &
317 293431 : { return vectorTagValue(tag_id); };
318 :
319 258805 : _var.requireQpComputations();
320 :
321 : return const_cast<MooseVariableDataBase<OutputType> *>(this)
322 517610 : ->stateToTagHelper<FieldVariableValue>(state, functor);
323 : }
324 :
325 : template <typename OutputType>
326 : const typename MooseVariableDataBase<OutputType>::FieldVariableGradient &
327 128167 : MooseVariableDataBase<OutputType>::gradSln(Moose::SolutionState state) const
328 : {
329 257264 : auto functor = [this](TagID tag_id) -> const FieldVariableGradient &
330 129097 : { return vectorTagGradient(tag_id); };
331 :
332 128167 : _var.requireQpComputations();
333 :
334 : return const_cast<MooseVariableDataBase<OutputType> *>(this)
335 256334 : ->stateToTagHelper<FieldVariableGradient>(state, functor);
336 : }
337 :
338 : template <typename OutputType>
339 : const typename MooseVariableDataBase<OutputType>::DofValues &
340 916742 : MooseVariableDataBase<OutputType>::vectorTagDofValue(Moose::SolutionState state) const
341 : {
342 1833872 : auto functor = [this](TagID tag_id) -> const DofValues & { return vectorTagDofValue(tag_id); };
343 :
344 916742 : _var.requireQpComputations();
345 :
346 916742 : return const_cast<MooseVariableDataBase<OutputType> *>(this)->stateToTagHelper<DofValues>(
347 1833484 : state, functor);
348 : }
349 :
350 : template <typename OutputType>
351 : const typename MooseVariableDataBase<OutputType>::DofValues &
352 892101 : MooseVariableDataBase<OutputType>::dofValues() const
353 : {
354 892101 : 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 46038132 : MooseVariableDataBase<OutputType>::setNodalValue(const OutputType & value, unsigned int idx)
381 : {
382 46038132 : 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 46038132 : dof_values[idx] = value; // update variable nodal value
385 46038132 : _has_dof_values = true;
386 46038132 : _nodal_value = value;
387 :
388 : // Update the qp values as well
389 46038132 : auto & u = _vector_tag_u[_solution_tag];
390 229010636 : for (unsigned int qp = 0; qp < u.size(); qp++)
391 182972504 : u[qp] = value;
392 46038132 : }
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 49785303 : MooseVariableDataBase<OutputType>::insert(NumericVector<Number> & residual)
410 : {
411 49785303 : if (_has_dof_values)
412 : {
413 48678340 : 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 48678340 : residual.insert(&dof_values[0], _dof_indices);
417 : }
418 49785303 : }
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 1042343390 : MooseVariableDataBase<OutputType>::fetchDofValues()
535 : {
536 1042343390 : bool is_transient = _subproblem.isTransient();
537 :
538 1042343390 : auto n = _dof_indices.size();
539 : libmesh_assert(n);
540 :
541 1042343390 : if (is_transient)
542 : {
543 823107020 : if (_need_u_dot || _need_grad_dot || _need_dof_values_dot)
544 : {
545 : libmesh_assert(_sys.solutionUDot());
546 305779312 : _dof_values_dot.resize(n);
547 305779312 : _sys.solutionUDot()->get(_dof_indices, &_dof_values_dot[0]);
548 : }
549 823107020 : 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 823107020 : 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 823107020 : 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 2096854369 : for (auto tag : _required_vector_tags)
570 1054510979 : if (_need_vector_tag_u[tag] || _need_vector_tag_grad[tag] || _need_vector_tag_dof_u[tag])
571 1054008780 : if ((_subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_RESIDUAL &&
572 2107938031 : _subproblem.safeAccessTaggedVectors()) ||
573 1053929251 : _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 1054008780 : if (_sys.hasVector(tag) /* && _sys.getVector(tag).closed()*/)
580 : {
581 1054008780 : auto & vec = _sys.getVector(tag);
582 1054008780 : _vector_tags_dof_u[tag].resize(n);
583 1054008780 : vec.get(_dof_indices, &_vector_tags_dof_u[tag][0]);
584 : }
585 : }
586 :
587 1042343390 : if (_subproblem.safeAccessTaggedMatrices())
588 : {
589 : auto & active_coupleable_matrix_tags =
590 831573807 : _subproblem.getActiveFEVariableCoupleableMatrixTags(_tid);
591 :
592 831849434 : 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 1042343390 : if (_need_du_dot_du || _need_dof_du_dot_du)
608 : {
609 305773800 : _dof_du_dot_du.resize(n);
610 1408902486 : for (decltype(n) i = 0; i < n; ++i)
611 1103128686 : _dof_du_dot_du[i] = _sys.duDotDu(_var.number());
612 : }
613 1042343390 : 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 1042343390 : }
620 :
621 : template <typename OutputType>
622 : void
623 7620558 : MooseVariableDataBase<OutputType>::getArrayDofValues(const NumericVector<Number> & sol,
624 : const unsigned int nshapes,
625 : MooseArray<RealEigenVector> & dof_values) const
626 : {
627 7620558 : dof_values.resize(nshapes);
628 31344158 : for (const auto i : make_range(nshapes))
629 : {
630 23723600 : dof_values[i].resize(_count);
631 72811877 : for (const auto j : make_range(_count))
632 49088277 : dof_values[i](j) = sol(_dof_indices[j * nshapes + i]);
633 : }
634 7620558 : }
635 :
636 : template <>
637 : void
638 5351604 : MooseVariableDataBase<RealEigenVector>::fetchDofValues()
639 : {
640 5351604 : bool is_transient = _subproblem.isTransient();
641 :
642 5351604 : auto n = _dof_indices.size() / _count;
643 : libmesh_assert(n);
644 :
645 5351604 : if (is_transient)
646 : {
647 4998738 : if (_need_u_dot || _need_grad_dot || _need_dof_values_dot)
648 : {
649 : libmesh_assert(_sys.solutionUDot());
650 2268376 : getArrayDofValues(*_sys.solutionUDot(), n, _dof_values_dot);
651 : }
652 4998738 : 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 4998738 : 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 4998738 : 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 10704748 : for (auto tag : _required_vector_tags)
670 5353144 : if ((_subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_RESIDUAL &&
671 10704748 : _subproblem.safeAccessTaggedVectors()) ||
672 5351604 : _subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_SOLUTION)
673 : // tag is defined on problem but may not be used by a system
674 5353144 : if (_sys.hasVector(tag))
675 : {
676 : mooseAssert(_sys.getVector(tag).closed(),
677 : "Vector with tag '" + std::to_string(tag) + "' should be closed");
678 5352182 : getArrayDofValues(_sys.getVector(tag), n, _vector_tags_dof_u[tag]);
679 : }
680 :
681 5351604 : if (_subproblem.safeAccessTaggedMatrices())
682 : {
683 : auto & active_coupleable_matrix_tags =
684 4631461 : _subproblem.getActiveFEVariableCoupleableMatrixTags(_tid);
685 4631461 : 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 5351604 : if (_need_du_dot_du || _need_dof_du_dot_du)
702 : {
703 2268376 : _dof_du_dot_du.resize(n);
704 10061977 : for (decltype(n) i = 0; i < n; ++i)
705 7793601 : _dof_du_dot_du[i] = _sys.duDotDu(_var.number());
706 : }
707 5351604 : 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 5351604 : }
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 246466848 : MooseVariableDataBase<OutputType>::assignNodalValue()
738 : {
739 246466848 : bool is_transient = _subproblem.isTransient();
740 : libmesh_assert(_dof_indices.size());
741 :
742 246466848 : auto & dof_values = _vector_tags_dof_u[_solution_tag];
743 246466848 : _nodal_value = dof_values[0];
744 246466848 : _nodal_value_array[0] = _nodal_value;
745 :
746 246466848 : if (is_transient)
747 : {
748 220080450 : if (oldestSolutionStateRequested() >= 1)
749 : {
750 4582330 : _nodal_value_old = _vector_tags_dof_u[_old_solution_tag][0];
751 4582330 : _nodal_value_old_array[0] = _nodal_value_old;
752 : }
753 220080450 : 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 220080450 : if (_need_dof_values_dot)
759 1406446 : _nodal_value_dot = _dof_values_dot[0];
760 220080450 : if (_need_dof_values_dotdot)
761 0 : _nodal_value_dotdot = _dof_values_dotdot[0];
762 220080450 : if (_need_dof_values_dot_old)
763 0 : _nodal_value_dot_old = _dof_values_dot_old[0];
764 220080450 : if (_need_dof_values_dotdot_old)
765 0 : _nodal_value_dotdot_old = _dof_values_dotdot_old[0];
766 : }
767 246466848 : 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 246466848 : }
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>;
|