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 551538 : MooseVariableDataBase<OutputType>::MooseVariableDataBase(const MooseVariableField<OutputType> & var,
19 : SystemBase & sys,
20 : THREAD_ID tid)
21 551538 : : _sys(sys),
22 1103076 : _subproblem(_sys.subproblem()),
23 551538 : _tid(tid),
24 551538 : _dof_map(_sys.dofMap()),
25 551538 : _count(var.count()),
26 551538 : _has_dof_values(false),
27 551538 : _max_state(0),
28 551538 : _solution_tag(_subproblem.getVectorTagID(Moose::SOLUTION_TAG)),
29 551538 : _old_solution_tag(Moose::INVALID_TAG_ID),
30 551538 : _older_solution_tag(Moose::INVALID_TAG_ID),
31 551538 : _previous_nl_solution_tag(Moose::INVALID_TAG_ID),
32 551538 : _need_u_dot(false),
33 551538 : _need_u_dotdot(false),
34 551538 : _need_u_dot_old(false),
35 551538 : _need_u_dotdot_old(false),
36 551538 : _need_du_dot_du(false),
37 551538 : _need_du_dotdot_du(false),
38 551538 : _need_grad_dot(false),
39 551538 : _need_grad_dotdot(false),
40 551538 : _need_dof_values_dot(false),
41 551538 : _need_dof_values_dotdot(false),
42 551538 : _need_dof_values_dot_old(false),
43 551538 : _need_dof_values_dotdot_old(false),
44 551538 : _need_dof_du_dot_du(false),
45 551538 : _need_dof_du_dotdot_du(false),
46 1103076 : _var(var)
47 : {
48 551538 : 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 551538 : const auto max_future_num_vector_tags = num_vector_tags + 2;
54 :
55 551538 : _vector_tags_dof_u.reserve(max_future_num_vector_tags);
56 551538 : _vector_tags_dof_u.resize(num_vector_tags);
57 551538 : _need_vector_tag_dof_u.reserve(max_future_num_vector_tags);
58 551538 : _need_vector_tag_dof_u.resize(num_vector_tags, false);
59 :
60 551538 : _need_vector_tag_u.reserve(max_future_num_vector_tags);
61 551538 : _need_vector_tag_u.resize(num_vector_tags, false);
62 551538 : _vector_tag_u.reserve(max_future_num_vector_tags);
63 551538 : _vector_tag_u.resize(num_vector_tags);
64 :
65 551538 : _need_vector_tag_grad.reserve(max_future_num_vector_tags);
66 551538 : _need_vector_tag_grad.resize(num_vector_tags, false);
67 551538 : _vector_tag_grad.reserve(max_future_num_vector_tags);
68 551538 : _vector_tag_grad.resize(num_vector_tags);
69 :
70 : // Always fetch the dof values for the solution tag
71 551538 : const auto soln_tag = _subproblem.getVectorTagID(Moose::SOLUTION_TAG);
72 551538 : _need_vector_tag_dof_u[soln_tag] = true;
73 551538 : _need_vector_tag_u[soln_tag] = true;
74 551538 : 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 551538 : _nodal_value_array.resize(1);
79 551538 : _nodal_value_old_array.resize(1);
80 551538 : _nodal_value_older_array.resize(1);
81 551538 : }
82 :
83 : template <typename OutputType>
84 : void
85 394753 : MooseVariableDataBase<OutputType>::sizeMatrixTagData()
86 : {
87 394753 : auto num_matrix_tags = _subproblem.numMatrixTags();
88 :
89 394753 : _matrix_tags_dof_u.resize(num_matrix_tags);
90 394753 : _need_matrix_tag_dof_u.resize(num_matrix_tags, false);
91 :
92 394753 : _need_matrix_tag_u.resize(num_matrix_tags, false);
93 394753 : _matrix_tag_u.resize(num_matrix_tags);
94 394753 : }
95 :
96 : template <typename OutputType>
97 : const typename MooseVariableDataBase<OutputType>::DoFValue &
98 388 : MooseVariableDataBase<OutputType>::nodalVectorTagValue(TagID tag) const
99 : {
100 388 : if (isNodal())
101 : {
102 388 : if (tag >= _need_vector_tag_dof_u.size())
103 0 : const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
104 :
105 388 : _need_vector_tag_dof_u[tag] = true;
106 :
107 388 : if (_sys.hasVector(tag))
108 388 : 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>::DoFValue &
121 140 : MooseVariableDataBase<OutputType>::nodalMatrixTagValue(TagID tag) const
122 : {
123 140 : if (isNodal())
124 : {
125 140 : 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 140 : _need_matrix_tag_dof_u[tag] = true;
132 :
133 140 : if (_sys.hasMatrix(tag))
134 140 : 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 546 : 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 7098 : auto check_capacity = [tag](const auto & vector_to_check)
157 : {
158 3276 : 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 546 : check_capacity(_need_vector_tag_dof_u);
163 546 : check_capacity(_need_vector_tag_u);
164 546 : check_capacity(_need_vector_tag_grad);
165 546 : check_capacity(_vector_tags_dof_u);
166 546 : check_capacity(_vector_tag_u);
167 546 : check_capacity(_vector_tag_grad);
168 :
169 546 : _need_vector_tag_dof_u.resize(tag + 1, false);
170 546 : _need_vector_tag_u.resize(tag + 1, false);
171 546 : _need_vector_tag_grad.resize(tag + 1, false);
172 546 : _vector_tags_dof_u.resize(tag + 1);
173 546 : _vector_tag_u.resize(tag + 1);
174 546 : _vector_tag_grad.resize(tag + 1);
175 546 : }
176 :
177 : template <typename OutputType>
178 : const typename MooseVariableDataBase<OutputType>::FieldVariableValue &
179 360086 : MooseVariableDataBase<OutputType>::vectorTagValue(TagID tag) const
180 : {
181 360086 : if (tag >= _need_vector_tag_u.size())
182 126 : const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
183 :
184 360086 : _need_vector_tag_u[tag] = true;
185 :
186 360086 : if (_sys.hasVector(tag))
187 360086 : return _vector_tag_u[tag];
188 : else
189 0 : mooseError("Tag ", tag, " is not associated with any vector for variable ", _var.name());
190 : }
191 :
192 : template <typename OutputType>
193 : const typename MooseVariableDataBase<OutputType>::DoFValue &
194 1032862 : MooseVariableDataBase<OutputType>::vectorTagDofValue(TagID tag) const
195 : {
196 1032862 : if (tag >= _need_vector_tag_dof_u.size())
197 168 : const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
198 :
199 1032862 : _need_vector_tag_dof_u[tag] = true;
200 :
201 1032862 : if (_sys.hasVector(tag))
202 1032862 : return _vector_tags_dof_u[tag];
203 : else
204 0 : mooseError("Tag ", tag, " is not associated with any vector for variable ", _var.name());
205 : }
206 :
207 : template <typename OutputType>
208 : const typename MooseVariableDataBase<OutputType>::FieldVariableGradient &
209 137000 : MooseVariableDataBase<OutputType>::vectorTagGradient(TagID tag) const
210 : {
211 137000 : if (tag >= _need_vector_tag_grad.size())
212 14 : const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
213 :
214 137000 : _need_vector_tag_grad[tag] = true;
215 :
216 137000 : if (_sys.hasVector(tag))
217 137000 : return _vector_tag_grad[tag];
218 : else
219 0 : mooseError("Tag ", tag, " is not associated with any vector for variable ", _var.name());
220 : }
221 :
222 : template <typename OutputType>
223 : const typename MooseVariableDataBase<OutputType>::FieldVariableValue &
224 54 : MooseVariableDataBase<OutputType>::matrixTagValue(TagID tag) const
225 : {
226 54 : if (tag >= _matrix_tag_u.size())
227 : {
228 0 : _need_matrix_tag_u.resize(tag + 1, false);
229 0 : const_cast<MooseVariableDataBase<OutputType> *>(this)->_matrix_tag_u.resize(tag + 1);
230 : }
231 :
232 54 : _need_matrix_tag_u[tag] = true;
233 :
234 54 : if (_sys.hasMatrix(tag))
235 54 : return _matrix_tag_u[tag];
236 : else
237 0 : mooseError("Tag ", tag, " is not associated with any matrix for variable ", _var.name());
238 : }
239 :
240 : template <typename OutputType>
241 : unsigned int
242 550960405 : MooseVariableDataBase<OutputType>::oldestSolutionStateRequested() const
243 : {
244 550960405 : return _max_state;
245 : }
246 :
247 : template <typename OutputType>
248 : void
249 38752 : MooseVariableDataBase<OutputType>::needSolutionState(const unsigned int state)
250 : {
251 38752 : if (state > _max_state)
252 : {
253 16996 : _sys.needSolutionState(state);
254 16996 : _max_state = state;
255 : }
256 38752 : }
257 :
258 : template <typename OutputType>
259 : template <typename ReturnType, typename Functor>
260 : const ReturnType &
261 1528989 : MooseVariableDataBase<OutputType>::stateToTagHelper(const Moose::SolutionState state,
262 : Functor functor)
263 : {
264 1528989 : if (state > 0)
265 : {
266 : // We need to request all states that are between current and the requested state
267 38752 : stateToTagHelper<ReturnType>(Moose::SolutionState(static_cast<int>(state) - 1), functor);
268 38752 : needSolutionState(cast_int<unsigned int>(state));
269 : }
270 :
271 1528989 : switch (state)
272 : {
273 1490155 : case Moose::Current:
274 1490155 : return functor(_subproblem.getVectorTagID(Moose::SOLUTION_TAG));
275 :
276 26726 : case Moose::Old:
277 : {
278 26726 : _old_solution_tag = _subproblem.getVectorTagID(Moose::OLD_SOLUTION_TAG);
279 26726 : insertSolutionTag(_old_solution_tag);
280 26726 : return functor(_old_solution_tag);
281 : }
282 :
283 12026 : case Moose::Older:
284 : {
285 12026 : _older_solution_tag = _subproblem.getVectorTagID(Moose::OLDER_SOLUTION_TAG);
286 12026 : insertSolutionTag(_older_solution_tag);
287 12026 : return functor(_older_solution_tag);
288 : }
289 :
290 82 : case Moose::PreviousNL:
291 : {
292 82 : _previous_nl_solution_tag = _subproblem.getVectorTagID(Moose::PREVIOUS_NL_SOLUTION_TAG);
293 82 : insertSolutionTag(_previous_nl_solution_tag);
294 82 : return functor(_previous_nl_solution_tag);
295 : }
296 :
297 0 : 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 0 : mooseError("Unknown SolutionState!");
301 : }
302 : }
303 :
304 : template <typename OutputType>
305 : const typename MooseVariableDataBase<OutputType>::FieldVariableValue &
306 321981 : MooseVariableDataBase<OutputType>::sln(Moose::SolutionState state) const
307 : {
308 681284 : auto functor = [this](TagID tag_id) -> const FieldVariableValue &
309 359303 : { return vectorTagValue(tag_id); };
310 :
311 : return const_cast<MooseVariableDataBase<OutputType> *>(this)
312 643962 : ->stateToTagHelper<FieldVariableValue>(state, functor);
313 : }
314 :
315 : template <typename OutputType>
316 : const typename MooseVariableDataBase<OutputType>::FieldVariableGradient &
317 135960 : MooseVariableDataBase<OutputType>::gradSln(Moose::SolutionState state) const
318 : {
319 272932 : auto functor = [this](TagID tag_id) -> const FieldVariableGradient &
320 136972 : { return vectorTagGradient(tag_id); };
321 :
322 : return const_cast<MooseVariableDataBase<OutputType> *>(this)
323 271920 : ->stateToTagHelper<FieldVariableGradient>(state, functor);
324 : }
325 :
326 : template <typename OutputType>
327 : const typename MooseVariableDataBase<OutputType>::DoFValue &
328 1032296 : MooseVariableDataBase<OutputType>::vectorTagDofValue(Moose::SolutionState state) const
329 : {
330 2065010 : auto functor = [this](TagID tag_id) -> const DoFValue & { return vectorTagDofValue(tag_id); };
331 :
332 1032296 : return const_cast<MooseVariableDataBase<OutputType> *>(this)->stateToTagHelper<DoFValue>(state,
333 2064592 : functor);
334 : }
335 :
336 : template <typename OutputType>
337 : const typename MooseVariableDataBase<OutputType>::DoFValue &
338 1006576 : MooseVariableDataBase<OutputType>::dofValues() const
339 : {
340 1006576 : return vectorTagDofValue(Moose::Current);
341 : }
342 :
343 : template <typename OutputType>
344 : const typename MooseVariableDataBase<OutputType>::DoFValue &
345 138 : MooseVariableDataBase<OutputType>::dofValuesOld() const
346 : {
347 138 : return vectorTagDofValue(Moose::Old);
348 : }
349 :
350 : template <typename OutputType>
351 : const typename MooseVariableDataBase<OutputType>::DoFValue &
352 56 : MooseVariableDataBase<OutputType>::dofValuesOlder() const
353 : {
354 56 : return vectorTagDofValue(Moose::Older);
355 : }
356 :
357 : template <typename OutputType>
358 : const typename MooseVariableDataBase<OutputType>::DoFValue &
359 0 : MooseVariableDataBase<OutputType>::dofValuesPreviousNL() const
360 : {
361 0 : return vectorTagDofValue(Moose::PreviousNL);
362 : }
363 :
364 : template <typename OutputType>
365 : void
366 51201795 : MooseVariableDataBase<OutputType>::setNodalValue(const OutputType & value, unsigned int idx)
367 : {
368 51201795 : 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 51201795 : dof_values[idx] = value; // update variable nodal value
371 51201795 : _has_dof_values = true;
372 51201795 : _nodal_value = value;
373 :
374 : // Update the qp values as well
375 51201795 : auto & u = _vector_tag_u[_solution_tag];
376 253613275 : for (unsigned int qp = 0; qp < u.size(); qp++)
377 202411480 : u[qp] = value;
378 51201795 : }
379 :
380 : template <>
381 : void
382 9340 : MooseVariableDataBase<RealVectorValue>::setNodalValue(const RealVectorValue & value,
383 : unsigned int idx)
384 : {
385 9340 : auto & dof_values = _vector_tags_dof_u[_solution_tag];
386 31944 : for (decltype(idx) i = 0; i < dof_values.size(); ++i, ++idx)
387 22604 : dof_values[idx] = value(i);
388 :
389 9340 : _has_dof_values = true;
390 9340 : _nodal_value = value;
391 9340 : }
392 :
393 : template <typename OutputType>
394 : void
395 55202512 : MooseVariableDataBase<OutputType>::insert(NumericVector<Number> & residual)
396 : {
397 55202512 : if (_has_dof_values)
398 : {
399 53948554 : 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 53948554 : residual.insert(&dof_values[0], _dof_indices);
403 : }
404 55202512 : }
405 :
406 : template <>
407 : void
408 715271 : MooseVariableDataBase<RealEigenVector>::insert(NumericVector<Number> & residual)
409 : {
410 715271 : if (_has_dof_values)
411 : {
412 715271 : auto & dof_values = _vector_tags_dof_u[_solution_tag];
413 715271 : if (isNodal())
414 : {
415 1470259 : for (unsigned int i = 0; i < _dof_indices.size(); ++i)
416 2393502 : for (unsigned int j = 0; j < _count; ++j)
417 1603456 : residual.set(_dof_indices[i] + j, dof_values[i](j));
418 : }
419 : else
420 : {
421 35058 : unsigned int n = 0;
422 111682 : for (unsigned int j = 0; j < _count; ++j)
423 : {
424 539528 : for (unsigned int i = 0; i < _dof_indices.size(); ++i)
425 462904 : residual.set(_dof_indices[i] + n, dof_values[i](j));
426 76624 : n += _dof_indices.size();
427 : }
428 : }
429 : }
430 715271 : }
431 :
432 : template <typename OutputType>
433 : void
434 2218030 : MooseVariableDataBase<OutputType>::add(NumericVector<Number> & residual)
435 : {
436 2218030 : if (_has_dof_values)
437 : {
438 38338 : auto & dof_values = _vector_tags_dof_u[_solution_tag];
439 38338 : residual.add_vector(&dof_values[0], _dof_indices);
440 : }
441 2218030 : }
442 :
443 : template <>
444 : void
445 0 : MooseVariableDataBase<RealEigenVector>::add(NumericVector<Number> & residual)
446 : {
447 0 : if (_has_dof_values)
448 : {
449 0 : auto & dof_values = _vector_tags_dof_u[_solution_tag];
450 0 : if (isNodal())
451 : {
452 0 : for (unsigned int i = 0; i < _dof_indices.size(); ++i)
453 0 : for (unsigned int j = 0; j < _count; ++j)
454 0 : residual.add(_dof_indices[i] + j, dof_values[i](j));
455 : }
456 : else
457 : {
458 0 : unsigned int n = 0;
459 0 : for (unsigned int j = 0; j < _count; ++j)
460 : {
461 0 : for (unsigned int i = 0; i < _dof_indices.size(); ++i)
462 0 : residual.add(_dof_indices[i] + n, dof_values[i](j));
463 0 : n += _dof_indices.size();
464 : }
465 : }
466 : }
467 0 : }
468 :
469 : template <typename OutputType>
470 : const OutputType &
471 1321 : MooseVariableDataBase<OutputType>::nodalValue(Moose::SolutionState state) const
472 : {
473 1321 : if (isNodal())
474 : {
475 : // Request the correct solution states and data members
476 1321 : vectorTagDofValue(state);
477 1321 : switch (state)
478 : {
479 1321 : case Moose::Current:
480 1321 : 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 24205 : MooseVariableDataBase<OutputType>::nodalValueArray(Moose::SolutionState state) const
506 : {
507 24205 : if (isNodal())
508 : {
509 : // Request the correct solution states and data members
510 24205 : vectorTagDofValue(state);
511 24205 : switch (state)
512 : {
513 24051 : case Moose::Current:
514 24051 : return _nodal_value_array;
515 :
516 140 : case Moose::Old:
517 140 : return _nodal_value_old_array;
518 :
519 14 : case Moose::Older:
520 14 : 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 1233042000 : MooseVariableDataBase<OutputType>::fetchDoFValues()
535 : {
536 1233042000 : bool is_transient = _subproblem.isTransient();
537 :
538 1233042000 : auto n = _dof_indices.size();
539 : libmesh_assert(n);
540 :
541 1233042000 : if (is_transient)
542 : {
543 973882645 : if (_need_u_dot || _need_grad_dot || _need_dof_values_dot)
544 : {
545 : libmesh_assert(_sys.solutionUDot());
546 354443478 : _dof_values_dot.resize(n);
547 354443478 : _sys.solutionUDot()->get(_dof_indices, &_dof_values_dot[0]);
548 : }
549 973882645 : if (_need_u_dotdot || _need_grad_dotdot || _need_dof_values_dotdot)
550 : {
551 : libmesh_assert(_sys.solutionUDotDot());
552 17877 : _dof_values_dotdot.resize(n);
553 17877 : _sys.solutionUDotDot()->get(_dof_indices, &_dof_values_dotdot[0]);
554 : }
555 973882645 : 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 973882645 : 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 2482746969 : for (auto tag : _required_vector_tags)
570 1249704969 : if (_need_vector_tag_u[tag] || _need_vector_tag_grad[tag] || _need_vector_tag_dof_u[tag])
571 1249175788 : if ((_subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_RESIDUAL &&
572 2498275544 : _subproblem.safeAccessTaggedVectors()) ||
573 1249099756 : _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 1249175788 : if (_sys.hasVector(tag) /* && _sys.getVector(tag).closed()*/)
579 : {
580 1249175788 : auto & vec = _sys.getVector(tag);
581 1249175788 : _vector_tags_dof_u[tag].resize(n);
582 1249175788 : vec.get(_dof_indices, &_vector_tags_dof_u[tag][0]);
583 : }
584 : }
585 :
586 1233042000 : if (_subproblem.safeAccessTaggedMatrices())
587 : {
588 : auto & active_coupleable_matrix_tags =
589 982693453 : _subproblem.getActiveFEVariableCoupleableMatrixTags(_tid);
590 :
591 982941284 : for (auto tag : active_coupleable_matrix_tags)
592 : {
593 247831 : _matrix_tags_dof_u[tag].resize(n);
594 247831 : if (_need_matrix_tag_dof_u[tag] || _need_matrix_tag_u[tag])
595 61996 : if (_sys.hasMatrix(tag) && _sys.matrixTagActive(tag) && _sys.getMatrix(tag).closed())
596 : {
597 61996 : auto & mat = _sys.getMatrix(tag);
598 124280 : for (unsigned i = 0; i < n; i++)
599 : {
600 62284 : Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
601 62284 : _matrix_tags_dof_u[tag][i] = mat(_dof_indices[i], _dof_indices[i]);
602 : }
603 : }
604 : }
605 : }
606 :
607 1233042000 : if (_need_du_dot_du || _need_dof_du_dot_du)
608 : {
609 354436550 : _dof_du_dot_du.resize(n);
610 1618840689 : for (decltype(n) i = 0; i < n; ++i)
611 1264404139 : _dof_du_dot_du[i] = _sys.duDotDu(_var.number());
612 : }
613 1233042000 : if (_need_du_dotdot_du || _need_dof_du_dotdot_du)
614 : {
615 11812 : _dof_du_dotdot_du.resize(n);
616 66800 : for (decltype(n) i = 0; i < n; ++i)
617 54988 : _dof_du_dotdot_du[i] = _sys.duDotDotDu();
618 : }
619 1233042000 : }
620 :
621 : template <typename OutputType>
622 : void
623 9582708 : MooseVariableDataBase<OutputType>::getArrayDoFValues(const NumericVector<Number> & sol,
624 : unsigned int n,
625 : MooseArray<RealEigenVector> & dof_values) const
626 : {
627 9582708 : dof_values.resize(n);
628 9582708 : if (isNodal())
629 : {
630 38291368 : for (unsigned int i = 0; i < n; ++i)
631 : {
632 29016704 : dof_values[i].resize(_count);
633 29016704 : auto dof = _dof_indices[i];
634 98278524 : for (unsigned int j = 0; j < _count; ++j)
635 69261820 : dof_values[i](j) = sol(dof++);
636 : }
637 : }
638 : else
639 : {
640 1774475 : for (unsigned int i = 0; i < n; ++i)
641 : {
642 1466431 : dof_values[i].resize(_count);
643 1466431 : auto dof = _dof_indices[i];
644 4988335 : for (unsigned int j = 0; j < _count; ++j)
645 : {
646 3521904 : dof_values[i](j) = sol(dof);
647 3521904 : dof += n;
648 : }
649 : }
650 : }
651 9582708 : }
652 :
653 : template <>
654 : void
655 6543412 : MooseVariableDataBase<RealEigenVector>::fetchDoFValues()
656 : {
657 6543412 : bool is_transient = _subproblem.isTransient();
658 :
659 6543412 : auto n = _dof_indices.size();
660 : libmesh_assert(n);
661 :
662 6543412 : if (is_transient)
663 : {
664 6169046 : if (_need_u_dot || _need_grad_dot || _need_dof_values_dot)
665 : {
666 : libmesh_assert(_sys.solutionUDot());
667 3038612 : getArrayDoFValues(*_sys.solutionUDot(), n, _dof_values_dot);
668 : }
669 6169046 : if (_need_u_dotdot || _need_grad_dotdot || _need_dof_values_dotdot)
670 : {
671 : libmesh_assert(_sys.solutionUDotDot());
672 0 : getArrayDoFValues(*_sys.solutionUDot(), n, _dof_values_dotdot);
673 : }
674 6169046 : if (_need_u_dot_old || _need_dof_values_dot_old)
675 : {
676 : libmesh_assert(_sys.solutionUDotOld());
677 0 : getArrayDoFValues(*_sys.solutionUDotOld(), n, _dof_values_dot_old);
678 : }
679 6169046 : if (_need_u_dotdot_old || _need_dof_values_dotdot_old)
680 : {
681 : libmesh_assert(_sys.solutionUDotDotOld());
682 0 : getArrayDoFValues(*_sys.solutionUDotDotOld(), n, _dof_values_dotdot_old);
683 : }
684 : }
685 :
686 13088624 : for (auto tag : _required_vector_tags)
687 6545212 : if ((_subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_RESIDUAL &&
688 13088624 : _subproblem.safeAccessTaggedVectors()) ||
689 6543412 : _subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_SOLUTION)
690 : // tag is defined on problem but may not be used by a system
691 6545212 : if (_sys.hasVector(tag) && _sys.getVector(tag).closed())
692 6544096 : getArrayDoFValues(_sys.getVector(tag), n, _vector_tags_dof_u[tag]);
693 :
694 6543412 : if (_subproblem.safeAccessTaggedMatrices())
695 : {
696 : auto & active_coupleable_matrix_tags =
697 5446828 : _subproblem.getActiveFEVariableCoupleableMatrixTags(_tid);
698 5446828 : for (auto tag : active_coupleable_matrix_tags)
699 : {
700 0 : _matrix_tags_dof_u[tag].resize(n);
701 0 : if (_need_matrix_tag_dof_u[tag] || _need_matrix_tag_u[tag])
702 0 : if (_sys.hasMatrix(tag) && _sys.matrixTagActive(tag) && _sys.getMatrix(tag).closed())
703 : {
704 0 : auto & mat = _sys.getMatrix(tag);
705 0 : for (unsigned i = 0; i < n; i++)
706 : {
707 0 : Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
708 0 : for (unsigned j = 0; j < _count; j++)
709 0 : _matrix_tags_dof_u[tag][i](j) = mat(_dof_indices[i] + j, _dof_indices[i] + j);
710 0 : }
711 : }
712 : }
713 : }
714 :
715 6543412 : if (_need_du_dot_du || _need_dof_du_dot_du)
716 : {
717 3038612 : _dof_du_dot_du.resize(n);
718 13706845 : for (decltype(n) i = 0; i < n; ++i)
719 10668233 : _dof_du_dot_du[i] = _sys.duDotDu(_var.number());
720 : }
721 6543412 : if (_need_du_dotdot_du || _need_dof_du_dotdot_du)
722 : {
723 0 : _dof_du_dotdot_du.resize(n);
724 0 : for (decltype(n) i = 0; i < n; ++i)
725 0 : _dof_du_dotdot_du[i] = _sys.duDotDotDu();
726 : }
727 6543412 : }
728 :
729 : template <typename OutputType>
730 : void
731 240 : MooseVariableDataBase<OutputType>::zeroSizeDofValues()
732 : {
733 240 : if (_subproblem.isTransient())
734 : {
735 186 : _dof_values_dot.resize(0);
736 186 : _dof_values_dotdot.resize(0);
737 186 : _dof_values_dot_old.resize(0);
738 186 : _dof_values_dotdot_old.resize(0);
739 186 : _dof_du_dot_du.resize(0);
740 186 : _dof_du_dotdot_du.resize(0);
741 : }
742 :
743 1704 : for (auto & dof_values : _vector_tags_dof_u)
744 1464 : dof_values.resize(0);
745 :
746 240 : _has_dof_values = false;
747 240 : }
748 :
749 : template <typename OutputType>
750 : void
751 304195896 : MooseVariableDataBase<OutputType>::assignNodalValue()
752 : {
753 304195896 : bool is_transient = _subproblem.isTransient();
754 :
755 : libmesh_assert(_dof_indices.size());
756 :
757 304195896 : auto & dof_values = _vector_tags_dof_u[_solution_tag];
758 304195896 : _nodal_value = dof_values[0];
759 304195896 : _nodal_value_array[0] = _nodal_value;
760 :
761 304195896 : if (is_transient)
762 : {
763 274914492 : if (oldestSolutionStateRequested() >= 1)
764 : {
765 5282069 : _nodal_value_old = _vector_tags_dof_u[_old_solution_tag][0];
766 5282069 : _nodal_value_old_array[0] = _nodal_value_old;
767 : }
768 274914492 : if (oldestSolutionStateRequested() >= 2)
769 : {
770 1866776 : _nodal_value_older = _vector_tags_dof_u[_older_solution_tag][0];
771 1866776 : _nodal_value_older_array[0] = _nodal_value_older;
772 : }
773 274914492 : if (_need_dof_values_dot)
774 1619847 : _nodal_value_dot = _dof_values_dot[0];
775 274914492 : if (_need_dof_values_dotdot)
776 0 : _nodal_value_dotdot = _dof_values_dotdot[0];
777 274914492 : if (_need_dof_values_dot_old)
778 0 : _nodal_value_dot_old = _dof_values_dot_old[0];
779 274914492 : if (_need_dof_values_dotdot_old)
780 0 : _nodal_value_dotdot_old = _dof_values_dotdot_old[0];
781 : }
782 304195896 : if (_previous_nl_solution_tag != Moose::INVALID_TAG_ID)
783 54560 : _nodal_value_previous_nl = _vector_tags_dof_u[_previous_nl_solution_tag][0];
784 304195896 : }
785 :
786 : template <>
787 : void
788 615123 : MooseVariableDataBase<RealVectorValue>::assignNodalValue()
789 : {
790 615123 : bool is_transient = _subproblem.isTransient();
791 :
792 615123 : auto n = _dof_indices.size();
793 : libmesh_assert(n);
794 :
795 615123 : auto & dof_values = _vector_tags_dof_u[_solution_tag];
796 1985858 : for (decltype(n) i = 0; i < n; ++i)
797 1370735 : _nodal_value(i) = dof_values[i];
798 615123 : _nodal_value_array[0] = _nodal_value;
799 :
800 615123 : if (is_transient)
801 : {
802 320553 : if (oldestSolutionStateRequested() >= 1)
803 : {
804 56080 : auto & dof_values_old = _vector_tags_dof_u[_old_solution_tag];
805 220008 : for (decltype(n) i = 0; i < n; ++i)
806 163928 : _nodal_value_old(i) = dof_values_old[i];
807 56080 : _nodal_value_old_array[0] = _nodal_value_old;
808 : }
809 320553 : if (oldestSolutionStateRequested() >= 2)
810 : {
811 4312 : auto & dof_values_older = _vector_tags_dof_u[_older_solution_tag];
812 12936 : for (decltype(n) i = 0; i < n; ++i)
813 8624 : _nodal_value_older(i) = dof_values_older[i];
814 4312 : _nodal_value_older_array[0] = _nodal_value_older;
815 : }
816 320553 : if (_need_dof_values_dot)
817 0 : for (decltype(n) i = 0; i < n; ++i)
818 0 : _nodal_value_dot(i) = _dof_values_dot[i];
819 320553 : if (_need_dof_values_dotdot)
820 0 : for (decltype(n) i = 0; i < n; ++i)
821 0 : _nodal_value_dotdot(i) = _dof_values_dotdot[i];
822 320553 : if (_need_dof_values_dot_old)
823 0 : for (decltype(n) i = 0; i < n; ++i)
824 0 : _nodal_value_dot_old(i) = _dof_values_dot_old[i];
825 320553 : if (_need_dof_values_dotdot_old)
826 0 : for (decltype(n) i = 0; i < n; ++i)
827 0 : _nodal_value_dotdot_old(i) = _dof_values_dotdot_old[i];
828 : }
829 615123 : if (_previous_nl_solution_tag != Moose::INVALID_TAG_ID)
830 : {
831 0 : auto & dof_values_previous_nl = _vector_tags_dof_u[_previous_nl_solution_tag];
832 0 : for (decltype(n) i = 0; i < n; ++i)
833 0 : _nodal_value_previous_nl(i) = dof_values_previous_nl[i];
834 : }
835 615123 : }
836 :
837 : template class MooseVariableDataBase<Real>;
838 : template class MooseVariableDataBase<RealVectorValue>;
839 : template class MooseVariableDataBase<RealEigenVector>;
|