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 547467 : MooseVariableDataBase<OutputType>::MooseVariableDataBase(const MooseVariableField<OutputType> & var,
19 : SystemBase & sys,
20 : THREAD_ID tid)
21 547467 : : _sys(sys),
22 1094934 : _subproblem(_sys.subproblem()),
23 547467 : _tid(tid),
24 547467 : _dof_map(_sys.dofMap()),
25 547467 : _count(var.count()),
26 547467 : _has_dof_values(false),
27 547467 : _max_state(0),
28 547467 : _solution_tag(_subproblem.getVectorTagID(Moose::SOLUTION_TAG)),
29 547467 : _old_solution_tag(Moose::INVALID_TAG_ID),
30 547467 : _older_solution_tag(Moose::INVALID_TAG_ID),
31 547467 : _previous_nl_solution_tag(Moose::INVALID_TAG_ID),
32 547467 : _need_u_dot(false),
33 547467 : _need_u_dotdot(false),
34 547467 : _need_u_dot_old(false),
35 547467 : _need_u_dotdot_old(false),
36 547467 : _need_du_dot_du(false),
37 547467 : _need_du_dotdot_du(false),
38 547467 : _need_grad_dot(false),
39 547467 : _need_grad_dotdot(false),
40 547467 : _need_dof_values_dot(false),
41 547467 : _need_dof_values_dotdot(false),
42 547467 : _need_dof_values_dot_old(false),
43 547467 : _need_dof_values_dotdot_old(false),
44 547467 : _need_dof_du_dot_du(false),
45 547467 : _need_dof_du_dotdot_du(false),
46 1094934 : _var(var)
47 : {
48 547467 : 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 547467 : const auto max_future_num_vector_tags = num_vector_tags + 2;
54 :
55 547467 : _vector_tags_dof_u.reserve(max_future_num_vector_tags);
56 547467 : _vector_tags_dof_u.resize(num_vector_tags);
57 547467 : _need_vector_tag_dof_u.reserve(max_future_num_vector_tags);
58 547467 : _need_vector_tag_dof_u.resize(num_vector_tags, false);
59 :
60 547467 : _need_vector_tag_u.reserve(max_future_num_vector_tags);
61 547467 : _need_vector_tag_u.resize(num_vector_tags, false);
62 547467 : _vector_tag_u.reserve(max_future_num_vector_tags);
63 547467 : _vector_tag_u.resize(num_vector_tags);
64 :
65 547467 : _need_vector_tag_grad.reserve(max_future_num_vector_tags);
66 547467 : _need_vector_tag_grad.resize(num_vector_tags, false);
67 547467 : _vector_tag_grad.reserve(max_future_num_vector_tags);
68 547467 : _vector_tag_grad.resize(num_vector_tags);
69 :
70 547467 : auto num_matrix_tags = _subproblem.numMatrixTags();
71 :
72 547467 : _matrix_tags_dof_u.resize(num_matrix_tags);
73 547467 : _need_matrix_tag_dof_u.resize(num_matrix_tags, false);
74 :
75 547467 : _need_matrix_tag_u.resize(num_matrix_tags, false);
76 547467 : _matrix_tag_u.resize(num_matrix_tags);
77 :
78 : // Always fetch the dof values for the solution tag
79 547467 : const auto soln_tag = _subproblem.getVectorTagID(Moose::SOLUTION_TAG);
80 547467 : _need_vector_tag_dof_u[soln_tag] = true;
81 547467 : _need_vector_tag_u[soln_tag] = true;
82 547467 : insertSolutionTag(soln_tag);
83 :
84 : // These MooseArray objects are used by AuxKernelBase for nodal AuxKernel objects, hence the size
85 : // size is always 1 (i.e, nodal kernels work with _qp=0 only).
86 547467 : _nodal_value_array.resize(1);
87 547467 : _nodal_value_old_array.resize(1);
88 547467 : _nodal_value_older_array.resize(1);
89 547467 : }
90 :
91 : template <typename OutputType>
92 : const typename MooseVariableDataBase<OutputType>::DoFValue &
93 388 : MooseVariableDataBase<OutputType>::nodalVectorTagValue(TagID tag) const
94 : {
95 388 : if (isNodal())
96 : {
97 388 : if (tag >= _need_vector_tag_dof_u.size())
98 0 : const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
99 :
100 388 : _need_vector_tag_dof_u[tag] = true;
101 :
102 388 : if (_sys.hasVector(tag))
103 388 : return _vector_tags_dof_u[tag];
104 : else
105 0 : mooseError(
106 0 : "Tag ", tag, " is not associated with any vector for nodal variable ", _var.name());
107 : }
108 : else
109 0 : mooseError("Nodal values can be requested only on nodal variables, variable '",
110 0 : _var.name(),
111 : "' is not nodal.");
112 : }
113 :
114 : template <typename OutputType>
115 : const typename MooseVariableDataBase<OutputType>::DoFValue &
116 140 : MooseVariableDataBase<OutputType>::nodalMatrixTagValue(TagID tag) const
117 : {
118 140 : if (isNodal())
119 : {
120 140 : if (tag >= _matrix_tags_dof_u.size())
121 : {
122 0 : _need_matrix_tag_dof_u.resize(tag + 1, false);
123 0 : const_cast<MooseVariableDataBase<OutputType> *>(this)->_matrix_tags_dof_u.resize(tag + 1);
124 : }
125 :
126 140 : _need_matrix_tag_dof_u[tag] = true;
127 :
128 140 : if (_sys.hasMatrix(tag))
129 140 : return _matrix_tags_dof_u[tag];
130 : else
131 0 : mooseError(
132 0 : "Tag ", tag, " is not associated with any matrix for nodal variable ", _var.name());
133 : }
134 : else
135 0 : mooseError("Nodal values can be requested only on nodal variables, variable '",
136 0 : _var.name(),
137 : "' is not nodal.");
138 : }
139 :
140 : template <typename OutputType>
141 : void
142 532 : MooseVariableDataBase<OutputType>::resizeVectorTagData(TagID tag)
143 : {
144 : mooseAssert(_need_vector_tag_dof_u.size() == _need_vector_tag_u.size() &&
145 : _need_vector_tag_dof_u.size() == _need_vector_tag_grad.size() &&
146 : _need_vector_tag_dof_u.size() == _vector_tags_dof_u.size() &&
147 : _need_vector_tag_dof_u.size() == _vector_tag_u.size() &&
148 : _need_vector_tag_dof_u.size() == _vector_tag_grad.size(),
149 : "These sizes should be in sync.");
150 :
151 6916 : auto check_capacity = [tag](const auto & vector_to_check)
152 : {
153 3192 : if (tag + 1 > vector_to_check.capacity())
154 0 : mooseError("New size greater than tag capacity. This will cause reallocation which will "
155 : "invalidate any stored references.");
156 : };
157 532 : check_capacity(_need_vector_tag_dof_u);
158 532 : check_capacity(_need_vector_tag_u);
159 532 : check_capacity(_need_vector_tag_grad);
160 532 : check_capacity(_vector_tags_dof_u);
161 532 : check_capacity(_vector_tag_u);
162 532 : check_capacity(_vector_tag_grad);
163 :
164 532 : _need_vector_tag_dof_u.resize(tag + 1, false);
165 532 : _need_vector_tag_u.resize(tag + 1, false);
166 532 : _need_vector_tag_grad.resize(tag + 1, false);
167 532 : _vector_tags_dof_u.resize(tag + 1);
168 532 : _vector_tag_u.resize(tag + 1);
169 532 : _vector_tag_grad.resize(tag + 1);
170 532 : }
171 :
172 : template <typename OutputType>
173 : const typename MooseVariableDataBase<OutputType>::FieldVariableValue &
174 358085 : MooseVariableDataBase<OutputType>::vectorTagValue(TagID tag) const
175 : {
176 358085 : if (tag >= _need_vector_tag_u.size())
177 126 : const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
178 :
179 358085 : _need_vector_tag_u[tag] = true;
180 :
181 358085 : if (_sys.hasVector(tag))
182 358085 : return _vector_tag_u[tag];
183 : else
184 0 : mooseError("Tag ", tag, " is not associated with any vector for variable ", _var.name());
185 : }
186 :
187 : template <typename OutputType>
188 : const typename MooseVariableDataBase<OutputType>::DoFValue &
189 1031546 : MooseVariableDataBase<OutputType>::vectorTagDofValue(TagID tag) const
190 : {
191 1031546 : if (tag >= _need_vector_tag_dof_u.size())
192 154 : const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
193 :
194 1031546 : _need_vector_tag_dof_u[tag] = true;
195 :
196 1031546 : if (_sys.hasVector(tag))
197 1031546 : return _vector_tags_dof_u[tag];
198 : else
199 0 : mooseError("Tag ", tag, " is not associated with any vector for variable ", _var.name());
200 : }
201 :
202 : template <typename OutputType>
203 : const typename MooseVariableDataBase<OutputType>::FieldVariableGradient &
204 135815 : MooseVariableDataBase<OutputType>::vectorTagGradient(TagID tag) const
205 : {
206 135815 : if (tag >= _need_vector_tag_grad.size())
207 14 : const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
208 :
209 135815 : _need_vector_tag_grad[tag] = true;
210 :
211 135815 : if (_sys.hasVector(tag))
212 135815 : return _vector_tag_grad[tag];
213 : else
214 0 : mooseError("Tag ", tag, " is not associated with any vector for variable ", _var.name());
215 : }
216 :
217 : template <typename OutputType>
218 : const typename MooseVariableDataBase<OutputType>::FieldVariableValue &
219 54 : MooseVariableDataBase<OutputType>::matrixTagValue(TagID tag) const
220 : {
221 54 : if (tag >= _matrix_tag_u.size())
222 : {
223 0 : _need_matrix_tag_u.resize(tag + 1, false);
224 0 : const_cast<MooseVariableDataBase<OutputType> *>(this)->_matrix_tag_u.resize(tag + 1);
225 : }
226 :
227 54 : _need_matrix_tag_u[tag] = true;
228 :
229 54 : if (_sys.hasMatrix(tag))
230 54 : return _matrix_tag_u[tag];
231 : else
232 0 : mooseError("Tag ", tag, " is not associated with any matrix for variable ", _var.name());
233 : }
234 :
235 : template <typename OutputType>
236 : unsigned int
237 549292295 : MooseVariableDataBase<OutputType>::oldestSolutionStateRequested() const
238 : {
239 549292295 : return _max_state;
240 : }
241 :
242 : template <typename OutputType>
243 : void
244 38710 : MooseVariableDataBase<OutputType>::needSolutionState(const unsigned int state)
245 : {
246 38710 : if (state > _max_state)
247 : {
248 16968 : _sys.needSolutionState(state);
249 16968 : _max_state = state;
250 : }
251 38710 : }
252 :
253 : template <typename OutputType>
254 : template <typename ReturnType, typename Functor>
255 : const ReturnType &
256 1524487 : MooseVariableDataBase<OutputType>::stateToTagHelper(const Moose::SolutionState state,
257 : Functor functor)
258 : {
259 1524487 : if (state > 0)
260 : {
261 : // We need to request all states that are between current and the requested state
262 38710 : stateToTagHelper<ReturnType>(Moose::SolutionState(static_cast<int>(state) - 1), functor);
263 38710 : needSolutionState(cast_int<unsigned int>(state));
264 : }
265 :
266 1524487 : switch (state)
267 : {
268 1485695 : case Moose::Current:
269 1485695 : return functor(_subproblem.getVectorTagID(Moose::SOLUTION_TAG));
270 :
271 26698 : case Moose::Old:
272 : {
273 26698 : _old_solution_tag = _subproblem.getVectorTagID(Moose::OLD_SOLUTION_TAG);
274 26698 : insertSolutionTag(_old_solution_tag);
275 26698 : return functor(_old_solution_tag);
276 : }
277 :
278 12012 : case Moose::Older:
279 : {
280 12012 : _older_solution_tag = _subproblem.getVectorTagID(Moose::OLDER_SOLUTION_TAG);
281 12012 : insertSolutionTag(_older_solution_tag);
282 12012 : return functor(_older_solution_tag);
283 : }
284 :
285 82 : case Moose::PreviousNL:
286 : {
287 82 : _previous_nl_solution_tag = _subproblem.getVectorTagID(Moose::PREVIOUS_NL_SOLUTION_TAG);
288 82 : insertSolutionTag(_previous_nl_solution_tag);
289 82 : return functor(_previous_nl_solution_tag);
290 : }
291 :
292 0 : default:
293 : // We should never get here but gcc requires that we have a default. See
294 : // htpps://stackoverflow.com/questions/18680378/after-defining-case-for-all-enum-values-compiler-still-says-control-reaches-e
295 0 : mooseError("Unknown SolutionState!");
296 : }
297 : }
298 :
299 : template <typename OutputType>
300 : const typename MooseVariableDataBase<OutputType>::FieldVariableValue &
301 319980 : MooseVariableDataBase<OutputType>::sln(Moose::SolutionState state) const
302 : {
303 677282 : auto functor = [this](TagID tag_id) -> const FieldVariableValue &
304 357302 : { return vectorTagValue(tag_id); };
305 :
306 : return const_cast<MooseVariableDataBase<OutputType> *>(this)
307 639960 : ->stateToTagHelper<FieldVariableValue>(state, functor);
308 : }
309 :
310 : template <typename OutputType>
311 : const typename MooseVariableDataBase<OutputType>::FieldVariableGradient &
312 134775 : MooseVariableDataBase<OutputType>::gradSln(Moose::SolutionState state) const
313 : {
314 270562 : auto functor = [this](TagID tag_id) -> const FieldVariableGradient &
315 135787 : { return vectorTagGradient(tag_id); };
316 :
317 : return const_cast<MooseVariableDataBase<OutputType> *>(this)
318 269550 : ->stateToTagHelper<FieldVariableGradient>(state, functor);
319 : }
320 :
321 : template <typename OutputType>
322 : const typename MooseVariableDataBase<OutputType>::DoFValue &
323 1031022 : MooseVariableDataBase<OutputType>::vectorTagDofValue(Moose::SolutionState state) const
324 : {
325 2062420 : auto functor = [this](TagID tag_id) -> const DoFValue & { return vectorTagDofValue(tag_id); };
326 :
327 1031022 : return const_cast<MooseVariableDataBase<OutputType> *>(this)->stateToTagHelper<DoFValue>(state,
328 2062044 : functor);
329 : }
330 :
331 : template <typename OutputType>
332 : const typename MooseVariableDataBase<OutputType>::DoFValue &
333 1005602 : MooseVariableDataBase<OutputType>::dofValues() const
334 : {
335 1005602 : return vectorTagDofValue(Moose::Current);
336 : }
337 :
338 : template <typename OutputType>
339 : const typename MooseVariableDataBase<OutputType>::DoFValue &
340 124 : MooseVariableDataBase<OutputType>::dofValuesOld() const
341 : {
342 124 : return vectorTagDofValue(Moose::Old);
343 : }
344 :
345 : template <typename OutputType>
346 : const typename MooseVariableDataBase<OutputType>::DoFValue &
347 42 : MooseVariableDataBase<OutputType>::dofValuesOlder() const
348 : {
349 42 : return vectorTagDofValue(Moose::Older);
350 : }
351 :
352 : template <typename OutputType>
353 : const typename MooseVariableDataBase<OutputType>::DoFValue &
354 0 : MooseVariableDataBase<OutputType>::dofValuesPreviousNL() const
355 : {
356 0 : return vectorTagDofValue(Moose::PreviousNL);
357 : }
358 :
359 : template <typename OutputType>
360 : void
361 51133711 : MooseVariableDataBase<OutputType>::setNodalValue(const OutputType & value, unsigned int idx)
362 : {
363 51133711 : auto & dof_values = _vector_tags_dof_u[_solution_tag];
364 : mooseAssert(idx < dof_values.size(), "idx is out of the bounds of degree of freedom values");
365 51133711 : dof_values[idx] = value; // update variable nodal value
366 51133711 : _has_dof_values = true;
367 51133711 : _nodal_value = value;
368 :
369 : // Update the qp values as well
370 51133711 : auto & u = _vector_tag_u[_solution_tag];
371 253161817 : for (unsigned int qp = 0; qp < u.size(); qp++)
372 202028106 : u[qp] = value;
373 51133711 : }
374 :
375 : template <>
376 : void
377 9340 : MooseVariableDataBase<RealVectorValue>::setNodalValue(const RealVectorValue & value,
378 : unsigned int idx)
379 : {
380 9340 : auto & dof_values = _vector_tags_dof_u[_solution_tag];
381 31944 : for (decltype(idx) i = 0; i < dof_values.size(); ++i, ++idx)
382 22604 : dof_values[idx] = value(i);
383 :
384 9340 : _has_dof_values = true;
385 9340 : _nodal_value = value;
386 9340 : }
387 :
388 : template <typename OutputType>
389 : void
390 55132285 : MooseVariableDataBase<OutputType>::insert(NumericVector<Number> & residual)
391 : {
392 55132285 : if (_has_dof_values)
393 : {
394 53878768 : auto & dof_values = _vector_tags_dof_u[_solution_tag];
395 : mooseAssert(dof_values.size() == _dof_indices.size(),
396 : "Degree of freedom values size and degree of freedom indices sizes must match.");
397 53878768 : residual.insert(&dof_values[0], _dof_indices);
398 : }
399 55132285 : }
400 :
401 : template <>
402 : void
403 715271 : MooseVariableDataBase<RealEigenVector>::insert(NumericVector<Number> & residual)
404 : {
405 715271 : if (_has_dof_values)
406 : {
407 715271 : auto & dof_values = _vector_tags_dof_u[_solution_tag];
408 715271 : if (isNodal())
409 : {
410 1470259 : for (unsigned int i = 0; i < _dof_indices.size(); ++i)
411 2393502 : for (unsigned int j = 0; j < _count; ++j)
412 1603456 : residual.set(_dof_indices[i] + j, dof_values[i](j));
413 : }
414 : else
415 : {
416 35058 : unsigned int n = 0;
417 111682 : for (unsigned int j = 0; j < _count; ++j)
418 : {
419 539528 : for (unsigned int i = 0; i < _dof_indices.size(); ++i)
420 462904 : residual.set(_dof_indices[i] + n, dof_values[i](j));
421 76624 : n += _dof_indices.size();
422 : }
423 : }
424 : }
425 715271 : }
426 :
427 : template <typename OutputType>
428 : void
429 2218030 : MooseVariableDataBase<OutputType>::add(NumericVector<Number> & residual)
430 : {
431 2218030 : if (_has_dof_values)
432 : {
433 38338 : auto & dof_values = _vector_tags_dof_u[_solution_tag];
434 38338 : residual.add_vector(&dof_values[0], _dof_indices);
435 : }
436 2218030 : }
437 :
438 : template <>
439 : void
440 0 : MooseVariableDataBase<RealEigenVector>::add(NumericVector<Number> & residual)
441 : {
442 0 : if (_has_dof_values)
443 : {
444 0 : auto & dof_values = _vector_tags_dof_u[_solution_tag];
445 0 : if (isNodal())
446 : {
447 0 : for (unsigned int i = 0; i < _dof_indices.size(); ++i)
448 0 : for (unsigned int j = 0; j < _count; ++j)
449 0 : residual.add(_dof_indices[i] + j, dof_values[i](j));
450 : }
451 : else
452 : {
453 0 : unsigned int n = 0;
454 0 : for (unsigned int j = 0; j < _count; ++j)
455 : {
456 0 : for (unsigned int i = 0; i < _dof_indices.size(); ++i)
457 0 : residual.add(_dof_indices[i] + n, dof_values[i](j));
458 0 : n += _dof_indices.size();
459 : }
460 : }
461 : }
462 0 : }
463 :
464 : template <typename OutputType>
465 : const OutputType &
466 1321 : MooseVariableDataBase<OutputType>::nodalValue(Moose::SolutionState state) const
467 : {
468 1321 : if (isNodal())
469 : {
470 : // Request the correct solution states and data members
471 1321 : vectorTagDofValue(state);
472 1321 : switch (state)
473 : {
474 1321 : case Moose::Current:
475 1321 : return _nodal_value;
476 :
477 0 : case Moose::Old:
478 0 : return _nodal_value_old;
479 :
480 0 : case Moose::Older:
481 0 : return _nodal_value_older;
482 :
483 0 : case Moose::PreviousNL:
484 0 : return _nodal_value_previous_nl;
485 :
486 0 : default:
487 : // We should never get here but gcc requires that we have a default. See
488 : // htpps://stackoverflow.com/questions/18680378/after-defining-case-for-all-enum-values-compiler-still-says-control-reaches-e
489 0 : mooseError("Unknown SolutionState!");
490 : }
491 : }
492 : else
493 0 : mooseError("Nodal values can be requested only on nodal variables, variable '",
494 0 : _var.name(),
495 : "' is not nodal.");
496 : }
497 :
498 : template <typename OutputType>
499 : const MooseArray<OutputType> &
500 23933 : MooseVariableDataBase<OutputType>::nodalValueArray(Moose::SolutionState state) const
501 : {
502 23933 : if (isNodal())
503 : {
504 : // Request the correct solution states and data members
505 23933 : vectorTagDofValue(state);
506 23933 : switch (state)
507 : {
508 23779 : case Moose::Current:
509 23779 : return _nodal_value_array;
510 :
511 140 : case Moose::Old:
512 140 : return _nodal_value_old_array;
513 :
514 14 : case Moose::Older:
515 14 : return _nodal_value_older_array;
516 :
517 0 : default:
518 0 : mooseError("No current support for PreviousNL for nodal value array");
519 : }
520 : }
521 : else
522 0 : mooseError("Nodal values can be requested only on nodal variables, variable '",
523 0 : _var.name(),
524 : "' is not nodal.");
525 : }
526 :
527 : template <typename OutputType>
528 : void
529 1231271944 : MooseVariableDataBase<OutputType>::fetchDoFValues()
530 : {
531 1231271944 : bool is_transient = _subproblem.isTransient();
532 :
533 1231271944 : auto n = _dof_indices.size();
534 : libmesh_assert(n);
535 :
536 1231271944 : if (is_transient)
537 : {
538 972242151 : if (_need_u_dot || _need_grad_dot || _need_dof_values_dot)
539 : {
540 : libmesh_assert(_sys.solutionUDot());
541 354423030 : _dof_values_dot.resize(n);
542 354423030 : _sys.solutionUDot()->get(_dof_indices, &_dof_values_dot[0]);
543 : }
544 972242151 : if (_need_u_dotdot || _need_grad_dotdot || _need_dof_values_dotdot)
545 : {
546 : libmesh_assert(_sys.solutionUDotDot());
547 17877 : _dof_values_dotdot.resize(n);
548 17877 : _sys.solutionUDotDot()->get(_dof_indices, &_dof_values_dotdot[0]);
549 : }
550 972242151 : if (_need_u_dot_old || _need_dof_values_dot_old)
551 : {
552 : libmesh_assert(_sys.solutionUDotOld());
553 0 : _dof_values_dot_old.resize(n);
554 0 : _sys.solutionUDotOld()->get(_dof_indices, &_dof_values_dot_old[0]);
555 : }
556 972242151 : if (_need_u_dotdot_old || _need_dof_values_dotdot_old)
557 : {
558 : libmesh_assert(_sys.solutionUDotDotOld());
559 0 : _dof_values_dotdot_old.resize(n);
560 0 : _sys.solutionUDotDotOld()->get(_dof_indices, &_dof_values_dotdot_old[0]);
561 : }
562 : }
563 :
564 2479155731 : for (auto tag : _required_vector_tags)
565 1247883787 : if (_need_vector_tag_u[tag] || _need_vector_tag_grad[tag] || _need_vector_tag_dof_u[tag])
566 1247354606 : if ((_subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_RESIDUAL &&
567 2494633180 : _subproblem.safeAccessTaggedVectors()) ||
568 1247278574 : _subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_SOLUTION)
569 : {
570 : // tag is defined on problem but may not be used by a system
571 : // the grain tracker requires being able to read from solution vectors that we are also in
572 : // the process of writing :-/
573 1247354606 : if (_sys.hasVector(tag) /* && _sys.getVector(tag).closed()*/)
574 : {
575 1247354606 : auto & vec = _sys.getVector(tag);
576 1247354606 : _vector_tags_dof_u[tag].resize(n);
577 1247354606 : vec.get(_dof_indices, &_vector_tags_dof_u[tag][0]);
578 : }
579 : }
580 :
581 1231271944 : if (_subproblem.safeAccessTaggedMatrices())
582 : {
583 : auto & active_coupleable_matrix_tags =
584 981319088 : _subproblem.getActiveFEVariableCoupleableMatrixTags(_tid);
585 :
586 981566919 : for (auto tag : active_coupleable_matrix_tags)
587 : {
588 247831 : _matrix_tags_dof_u[tag].resize(n);
589 247831 : if (_need_matrix_tag_dof_u[tag] || _need_matrix_tag_u[tag])
590 61996 : if (_sys.hasMatrix(tag) && _sys.matrixTagActive(tag) && _sys.getMatrix(tag).closed())
591 : {
592 61996 : auto & mat = _sys.getMatrix(tag);
593 124280 : for (unsigned i = 0; i < n; i++)
594 : {
595 62284 : Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
596 62284 : _matrix_tags_dof_u[tag][i] = mat(_dof_indices[i], _dof_indices[i]);
597 : }
598 : }
599 : }
600 : }
601 :
602 1231271944 : if (_need_du_dot_du || _need_dof_du_dot_du)
603 : {
604 354416102 : _dof_du_dot_du.resize(n);
605 1618769601 : for (decltype(n) i = 0; i < n; ++i)
606 1264353499 : _dof_du_dot_du[i] = _sys.duDotDu(_var.number());
607 : }
608 1231271944 : if (_need_du_dotdot_du || _need_dof_du_dotdot_du)
609 : {
610 11812 : _dof_du_dotdot_du.resize(n);
611 66800 : for (decltype(n) i = 0; i < n; ++i)
612 54988 : _dof_du_dotdot_du[i] = _sys.duDotDotDu();
613 : }
614 1231271944 : }
615 :
616 : template <typename OutputType>
617 : void
618 9582708 : MooseVariableDataBase<OutputType>::getArrayDoFValues(const NumericVector<Number> & sol,
619 : unsigned int n,
620 : MooseArray<RealEigenVector> & dof_values) const
621 : {
622 9582708 : dof_values.resize(n);
623 9582708 : if (isNodal())
624 : {
625 38291368 : for (unsigned int i = 0; i < n; ++i)
626 : {
627 29016704 : dof_values[i].resize(_count);
628 29016704 : auto dof = _dof_indices[i];
629 98278524 : for (unsigned int j = 0; j < _count; ++j)
630 69261820 : dof_values[i](j) = sol(dof++);
631 : }
632 : }
633 : else
634 : {
635 1774475 : for (unsigned int i = 0; i < n; ++i)
636 : {
637 1466431 : dof_values[i].resize(_count);
638 1466431 : auto dof = _dof_indices[i];
639 4988335 : for (unsigned int j = 0; j < _count; ++j)
640 : {
641 3521904 : dof_values[i](j) = sol(dof);
642 3521904 : dof += n;
643 : }
644 : }
645 : }
646 9582708 : }
647 :
648 : template <>
649 : void
650 6543412 : MooseVariableDataBase<RealEigenVector>::fetchDoFValues()
651 : {
652 6543412 : bool is_transient = _subproblem.isTransient();
653 :
654 6543412 : auto n = _dof_indices.size();
655 : libmesh_assert(n);
656 :
657 6543412 : if (is_transient)
658 : {
659 6169046 : if (_need_u_dot || _need_grad_dot || _need_dof_values_dot)
660 : {
661 : libmesh_assert(_sys.solutionUDot());
662 3038612 : getArrayDoFValues(*_sys.solutionUDot(), n, _dof_values_dot);
663 : }
664 6169046 : if (_need_u_dotdot || _need_grad_dotdot || _need_dof_values_dotdot)
665 : {
666 : libmesh_assert(_sys.solutionUDotDot());
667 0 : getArrayDoFValues(*_sys.solutionUDot(), n, _dof_values_dotdot);
668 : }
669 6169046 : if (_need_u_dot_old || _need_dof_values_dot_old)
670 : {
671 : libmesh_assert(_sys.solutionUDotOld());
672 0 : getArrayDoFValues(*_sys.solutionUDotOld(), n, _dof_values_dot_old);
673 : }
674 6169046 : if (_need_u_dotdot_old || _need_dof_values_dotdot_old)
675 : {
676 : libmesh_assert(_sys.solutionUDotDotOld());
677 0 : getArrayDoFValues(*_sys.solutionUDotDotOld(), n, _dof_values_dotdot_old);
678 : }
679 : }
680 :
681 13088624 : for (auto tag : _required_vector_tags)
682 6545212 : if ((_subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_RESIDUAL &&
683 13088624 : _subproblem.safeAccessTaggedVectors()) ||
684 6543412 : _subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_SOLUTION)
685 : // tag is defined on problem but may not be used by a system
686 6545212 : if (_sys.hasVector(tag) && _sys.getVector(tag).closed())
687 6544096 : getArrayDoFValues(_sys.getVector(tag), n, _vector_tags_dof_u[tag]);
688 :
689 6543412 : if (_subproblem.safeAccessTaggedMatrices())
690 : {
691 : auto & active_coupleable_matrix_tags =
692 5446828 : _subproblem.getActiveFEVariableCoupleableMatrixTags(_tid);
693 5446828 : for (auto tag : active_coupleable_matrix_tags)
694 : {
695 0 : _matrix_tags_dof_u[tag].resize(n);
696 0 : if (_need_matrix_tag_dof_u[tag] || _need_matrix_tag_u[tag])
697 0 : if (_sys.hasMatrix(tag) && _sys.matrixTagActive(tag) && _sys.getMatrix(tag).closed())
698 : {
699 0 : auto & mat = _sys.getMatrix(tag);
700 0 : for (unsigned i = 0; i < n; i++)
701 : {
702 0 : Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
703 0 : for (unsigned j = 0; j < _count; j++)
704 0 : _matrix_tags_dof_u[tag][i](j) = mat(_dof_indices[i] + j, _dof_indices[i] + j);
705 0 : }
706 : }
707 : }
708 : }
709 :
710 6543412 : if (_need_du_dot_du || _need_dof_du_dot_du)
711 : {
712 3038612 : _dof_du_dot_du.resize(n);
713 13706845 : for (decltype(n) i = 0; i < n; ++i)
714 10668233 : _dof_du_dot_du[i] = _sys.duDotDu(_var.number());
715 : }
716 6543412 : if (_need_du_dotdot_du || _need_dof_du_dotdot_du)
717 : {
718 0 : _dof_du_dotdot_du.resize(n);
719 0 : for (decltype(n) i = 0; i < n; ++i)
720 0 : _dof_du_dotdot_du[i] = _sys.duDotDotDu();
721 : }
722 6543412 : }
723 :
724 : template <typename OutputType>
725 : void
726 240 : MooseVariableDataBase<OutputType>::zeroSizeDofValues()
727 : {
728 240 : if (_subproblem.isTransient())
729 : {
730 186 : _dof_values_dot.resize(0);
731 186 : _dof_values_dotdot.resize(0);
732 186 : _dof_values_dot_old.resize(0);
733 186 : _dof_values_dotdot_old.resize(0);
734 186 : _dof_du_dot_du.resize(0);
735 186 : _dof_du_dotdot_du.resize(0);
736 : }
737 :
738 1944 : for (auto & dof_values : _vector_tags_dof_u)
739 1704 : dof_values.resize(0);
740 :
741 240 : _has_dof_values = false;
742 240 : }
743 :
744 : template <typename OutputType>
745 : void
746 303361717 : MooseVariableDataBase<OutputType>::assignNodalValue()
747 : {
748 303361717 : bool is_transient = _subproblem.isTransient();
749 :
750 : libmesh_assert(_dof_indices.size());
751 :
752 303361717 : auto & dof_values = _vector_tags_dof_u[_solution_tag];
753 303361717 : _nodal_value = dof_values[0];
754 303361717 : _nodal_value_array[0] = _nodal_value;
755 :
756 303361717 : if (is_transient)
757 : {
758 274082299 : if (oldestSolutionStateRequested() >= 1)
759 : {
760 5270947 : _nodal_value_old = _vector_tags_dof_u[_old_solution_tag][0];
761 5270947 : _nodal_value_old_array[0] = _nodal_value_old;
762 : }
763 274082299 : if (oldestSolutionStateRequested() >= 2)
764 : {
765 1855654 : _nodal_value_older = _vector_tags_dof_u[_older_solution_tag][0];
766 1855654 : _nodal_value_older_array[0] = _nodal_value_older;
767 : }
768 274082299 : if (_need_dof_values_dot)
769 1619847 : _nodal_value_dot = _dof_values_dot[0];
770 274082299 : if (_need_dof_values_dotdot)
771 0 : _nodal_value_dotdot = _dof_values_dotdot[0];
772 274082299 : if (_need_dof_values_dot_old)
773 0 : _nodal_value_dot_old = _dof_values_dot_old[0];
774 274082299 : if (_need_dof_values_dotdot_old)
775 0 : _nodal_value_dotdot_old = _dof_values_dotdot_old[0];
776 : }
777 303361717 : if (_previous_nl_solution_tag != Moose::INVALID_TAG_ID)
778 54560 : _nodal_value_previous_nl = _vector_tags_dof_u[_previous_nl_solution_tag][0];
779 303361717 : }
780 :
781 : template <>
782 : void
783 615123 : MooseVariableDataBase<RealVectorValue>::assignNodalValue()
784 : {
785 615123 : bool is_transient = _subproblem.isTransient();
786 :
787 615123 : auto n = _dof_indices.size();
788 : libmesh_assert(n);
789 :
790 615123 : auto & dof_values = _vector_tags_dof_u[_solution_tag];
791 1985858 : for (decltype(n) i = 0; i < n; ++i)
792 1370735 : _nodal_value(i) = dof_values[i];
793 615123 : _nodal_value_array[0] = _nodal_value;
794 :
795 615123 : if (is_transient)
796 : {
797 320553 : if (oldestSolutionStateRequested() >= 1)
798 : {
799 56080 : auto & dof_values_old = _vector_tags_dof_u[_old_solution_tag];
800 220008 : for (decltype(n) i = 0; i < n; ++i)
801 163928 : _nodal_value_old(i) = dof_values_old[i];
802 56080 : _nodal_value_old_array[0] = _nodal_value_old;
803 : }
804 320553 : if (oldestSolutionStateRequested() >= 2)
805 : {
806 4312 : auto & dof_values_older = _vector_tags_dof_u[_older_solution_tag];
807 12936 : for (decltype(n) i = 0; i < n; ++i)
808 8624 : _nodal_value_older(i) = dof_values_older[i];
809 4312 : _nodal_value_older_array[0] = _nodal_value_older;
810 : }
811 320553 : if (_need_dof_values_dot)
812 0 : for (decltype(n) i = 0; i < n; ++i)
813 0 : _nodal_value_dot(i) = _dof_values_dot[i];
814 320553 : if (_need_dof_values_dotdot)
815 0 : for (decltype(n) i = 0; i < n; ++i)
816 0 : _nodal_value_dotdot(i) = _dof_values_dotdot[i];
817 320553 : if (_need_dof_values_dot_old)
818 0 : for (decltype(n) i = 0; i < n; ++i)
819 0 : _nodal_value_dot_old(i) = _dof_values_dot_old[i];
820 320553 : if (_need_dof_values_dotdot_old)
821 0 : for (decltype(n) i = 0; i < n; ++i)
822 0 : _nodal_value_dotdot_old(i) = _dof_values_dotdot_old[i];
823 : }
824 615123 : if (_previous_nl_solution_tag != Moose::INVALID_TAG_ID)
825 : {
826 0 : auto & dof_values_previous_nl = _vector_tags_dof_u[_previous_nl_solution_tag];
827 0 : for (decltype(n) i = 0; i < n; ++i)
828 0 : _nodal_value_previous_nl(i) = dof_values_previous_nl[i];
829 : }
830 615123 : }
831 :
832 : template class MooseVariableDataBase<Real>;
833 : template class MooseVariableDataBase<RealVectorValue>;
834 : template class MooseVariableDataBase<RealEigenVector>;
|