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 510907 : MooseVariableDataBase<OutputType>::MooseVariableDataBase(const MooseVariableField<OutputType> & var,
19 : SystemBase & sys,
20 : THREAD_ID tid)
21 510907 : : _sys(sys),
22 1021814 : _subproblem(_sys.subproblem()),
23 510907 : _tid(tid),
24 510907 : _dof_map(_sys.dofMap()),
25 510907 : _count(var.count()),
26 510907 : _has_dof_values(false),
27 510907 : _max_state(0),
28 510907 : _solution_tag(_subproblem.getVectorTagID(Moose::SOLUTION_TAG)),
29 510907 : _old_solution_tag(Moose::INVALID_TAG_ID),
30 510907 : _older_solution_tag(Moose::INVALID_TAG_ID),
31 510907 : _previous_nl_solution_tag(Moose::INVALID_TAG_ID),
32 510907 : _need_u_dot(false),
33 510907 : _need_u_dotdot(false),
34 510907 : _need_u_dot_old(false),
35 510907 : _need_u_dotdot_old(false),
36 510907 : _need_du_dot_du(false),
37 510907 : _need_du_dotdot_du(false),
38 510907 : _need_grad_dot(false),
39 510907 : _need_grad_dotdot(false),
40 510907 : _need_dof_values_dot(false),
41 510907 : _need_dof_values_dotdot(false),
42 510907 : _need_dof_values_dot_old(false),
43 510907 : _need_dof_values_dotdot_old(false),
44 510907 : _need_dof_du_dot_du(false),
45 510907 : _need_dof_du_dotdot_du(false),
46 1021814 : _var(var)
47 : {
48 510907 : 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 510907 : const auto max_future_num_vector_tags = num_vector_tags + 2;
54 :
55 510907 : _vector_tags_dof_u.reserve(max_future_num_vector_tags);
56 510907 : _vector_tags_dof_u.resize(num_vector_tags);
57 510907 : _need_vector_tag_dof_u.reserve(max_future_num_vector_tags);
58 510907 : _need_vector_tag_dof_u.resize(num_vector_tags, false);
59 :
60 510907 : _need_vector_tag_u.reserve(max_future_num_vector_tags);
61 510907 : _need_vector_tag_u.resize(num_vector_tags, false);
62 510907 : _vector_tag_u.reserve(max_future_num_vector_tags);
63 510907 : _vector_tag_u.resize(num_vector_tags);
64 :
65 510907 : _need_vector_tag_grad.reserve(max_future_num_vector_tags);
66 510907 : _need_vector_tag_grad.resize(num_vector_tags, false);
67 510907 : _vector_tag_grad.reserve(max_future_num_vector_tags);
68 510907 : _vector_tag_grad.resize(num_vector_tags);
69 :
70 510907 : auto num_matrix_tags = _subproblem.numMatrixTags();
71 :
72 510907 : _matrix_tags_dof_u.resize(num_matrix_tags);
73 510907 : _need_matrix_tag_dof_u.resize(num_matrix_tags, false);
74 :
75 510907 : _need_matrix_tag_u.resize(num_matrix_tags, false);
76 510907 : _matrix_tag_u.resize(num_matrix_tags);
77 :
78 : // Always fetch the dof values for the solution tag
79 510907 : const auto soln_tag = _subproblem.getVectorTagID(Moose::SOLUTION_TAG);
80 510907 : _need_vector_tag_dof_u[soln_tag] = true;
81 510907 : _need_vector_tag_u[soln_tag] = true;
82 510907 : 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 510907 : _nodal_value_array.resize(1);
87 510907 : _nodal_value_old_array.resize(1);
88 510907 : _nodal_value_older_array.resize(1);
89 510907 : }
90 :
91 : template <typename OutputType>
92 : const typename MooseVariableDataBase<OutputType>::DoFValue &
93 363 : MooseVariableDataBase<OutputType>::nodalVectorTagValue(TagID tag) const
94 : {
95 363 : if (isNodal())
96 : {
97 363 : if (tag >= _need_vector_tag_dof_u.size())
98 0 : const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
99 :
100 363 : _need_vector_tag_dof_u[tag] = true;
101 :
102 363 : if (_sys.hasVector(tag))
103 363 : 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 130 : MooseVariableDataBase<OutputType>::nodalMatrixTagValue(TagID tag) const
117 : {
118 130 : if (isNodal())
119 : {
120 130 : 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 130 : _need_matrix_tag_dof_u[tag] = true;
127 :
128 130 : if (_sys.hasMatrix(tag))
129 130 : 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 494 : 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 6422 : auto check_capacity = [tag](const auto & vector_to_check)
152 : {
153 2964 : 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 494 : check_capacity(_need_vector_tag_dof_u);
158 494 : check_capacity(_need_vector_tag_u);
159 494 : check_capacity(_need_vector_tag_grad);
160 494 : check_capacity(_vector_tags_dof_u);
161 494 : check_capacity(_vector_tag_u);
162 494 : check_capacity(_vector_tag_grad);
163 :
164 494 : _need_vector_tag_dof_u.resize(tag + 1, false);
165 494 : _need_vector_tag_u.resize(tag + 1, false);
166 494 : _need_vector_tag_grad.resize(tag + 1, false);
167 494 : _vector_tags_dof_u.resize(tag + 1);
168 494 : _vector_tag_u.resize(tag + 1);
169 494 : _vector_tag_grad.resize(tag + 1);
170 494 : }
171 :
172 : template <typename OutputType>
173 : const typename MooseVariableDataBase<OutputType>::FieldVariableValue &
174 330753 : MooseVariableDataBase<OutputType>::vectorTagValue(TagID tag) const
175 : {
176 330753 : if (tag >= _need_vector_tag_u.size())
177 117 : const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
178 :
179 330753 : _need_vector_tag_u[tag] = true;
180 :
181 330753 : if (_sys.hasVector(tag))
182 330753 : 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 947831 : MooseVariableDataBase<OutputType>::vectorTagDofValue(TagID tag) const
190 : {
191 947831 : if (tag >= _need_vector_tag_dof_u.size())
192 143 : const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
193 :
194 947831 : _need_vector_tag_dof_u[tag] = true;
195 :
196 947831 : if (_sys.hasVector(tag))
197 947831 : 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 127188 : MooseVariableDataBase<OutputType>::vectorTagGradient(TagID tag) const
205 : {
206 127188 : if (tag >= _need_vector_tag_grad.size())
207 13 : const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
208 :
209 127188 : _need_vector_tag_grad[tag] = true;
210 :
211 127188 : if (_sys.hasVector(tag))
212 127188 : 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 50 : MooseVariableDataBase<OutputType>::matrixTagValue(TagID tag) const
220 : {
221 50 : 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 50 : _need_matrix_tag_u[tag] = true;
228 :
229 50 : if (_sys.hasMatrix(tag))
230 50 : 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 488440160 : MooseVariableDataBase<OutputType>::oldestSolutionStateRequested() const
238 : {
239 488440160 : return _max_state;
240 : }
241 :
242 : template <typename OutputType>
243 : void
244 36003 : MooseVariableDataBase<OutputType>::needSolutionState(const unsigned int state)
245 : {
246 36003 : if (state > _max_state)
247 : {
248 15772 : _sys.needSolutionState(state);
249 15772 : _max_state = state;
250 : }
251 36003 : }
252 :
253 : template <typename OutputType>
254 : template <typename ReturnType, typename Functor>
255 : const ReturnType &
256 1404878 : MooseVariableDataBase<OutputType>::stateToTagHelper(const Moose::SolutionState state,
257 : Functor functor)
258 : {
259 1404878 : if (state > 0)
260 : {
261 : // We need to request all states that are between current and the requested state
262 36003 : stateToTagHelper<ReturnType>(Moose::SolutionState(static_cast<int>(state) - 1), functor);
263 36003 : needSolutionState(cast_int<unsigned int>(state));
264 : }
265 :
266 1404878 : switch (state)
267 : {
268 1368797 : case Moose::Current:
269 1368797 : return functor(_subproblem.getVectorTagID(Moose::SOLUTION_TAG));
270 :
271 24849 : case Moose::Old:
272 : {
273 24849 : _old_solution_tag = _subproblem.getVectorTagID(Moose::OLD_SOLUTION_TAG);
274 24849 : insertSolutionTag(_old_solution_tag);
275 24849 : return functor(_old_solution_tag);
276 : }
277 :
278 11154 : case Moose::Older:
279 : {
280 11154 : _older_solution_tag = _subproblem.getVectorTagID(Moose::OLDER_SOLUTION_TAG);
281 11154 : insertSolutionTag(_older_solution_tag);
282 11154 : return functor(_older_solution_tag);
283 : }
284 :
285 78 : case Moose::PreviousNL:
286 : {
287 78 : _previous_nl_solution_tag = _subproblem.getVectorTagID(Moose::PREVIOUS_NL_SOLUTION_TAG);
288 78 : insertSolutionTag(_previous_nl_solution_tag);
289 78 : 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 295340 : MooseVariableDataBase<OutputType>::sln(Moose::SolutionState state) const
302 : {
303 625362 : auto functor = [this](TagID tag_id) -> const FieldVariableValue &
304 330022 : { return vectorTagValue(tag_id); };
305 :
306 : return const_cast<MooseVariableDataBase<OutputType> *>(this)
307 590680 : ->stateToTagHelper<FieldVariableValue>(state, functor);
308 : }
309 :
310 : template <typename OutputType>
311 : const typename MooseVariableDataBase<OutputType>::FieldVariableGradient &
312 126190 : MooseVariableDataBase<OutputType>::gradSln(Moose::SolutionState state) const
313 : {
314 253352 : auto functor = [this](TagID tag_id) -> const FieldVariableGradient &
315 127162 : { return vectorTagGradient(tag_id); };
316 :
317 : return const_cast<MooseVariableDataBase<OutputType> *>(this)
318 252380 : ->stateToTagHelper<FieldVariableGradient>(state, functor);
319 : }
320 :
321 : template <typename OutputType>
322 : const typename MooseVariableDataBase<OutputType>::DoFValue &
323 947345 : MooseVariableDataBase<OutputType>::vectorTagDofValue(Moose::SolutionState state) const
324 : {
325 1895039 : auto functor = [this](TagID tag_id) -> const DoFValue & { return vectorTagDofValue(tag_id); };
326 :
327 947345 : return const_cast<MooseVariableDataBase<OutputType> *>(this)->stateToTagHelper<DoFValue>(state,
328 1894690 : functor);
329 : }
330 :
331 : template <typename OutputType>
332 : const typename MooseVariableDataBase<OutputType>::DoFValue &
333 923730 : MooseVariableDataBase<OutputType>::dofValues() const
334 : {
335 923730 : return vectorTagDofValue(Moose::Current);
336 : }
337 :
338 : template <typename OutputType>
339 : const typename MooseVariableDataBase<OutputType>::DoFValue &
340 115 : MooseVariableDataBase<OutputType>::dofValuesOld() const
341 : {
342 115 : return vectorTagDofValue(Moose::Old);
343 : }
344 :
345 : template <typename OutputType>
346 : const typename MooseVariableDataBase<OutputType>::DoFValue &
347 39 : MooseVariableDataBase<OutputType>::dofValuesOlder() const
348 : {
349 39 : 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 45400478 : MooseVariableDataBase<OutputType>::setNodalValue(const OutputType & value, unsigned int idx)
362 : {
363 45400478 : 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 45400478 : dof_values[idx] = value; // update variable nodal value
366 45400478 : _has_dof_values = true;
367 45400478 : _nodal_value = value;
368 :
369 : // Update the qp values as well
370 45400478 : auto & u = _vector_tag_u[_solution_tag];
371 224711450 : for (unsigned int qp = 0; qp < u.size(); qp++)
372 179310972 : u[qp] = value;
373 45400478 : }
374 :
375 : template <>
376 : void
377 8110 : MooseVariableDataBase<RealVectorValue>::setNodalValue(const RealVectorValue & value,
378 : unsigned int idx)
379 : {
380 8110 : auto & dof_values = _vector_tags_dof_u[_solution_tag];
381 27780 : for (decltype(idx) i = 0; i < dof_values.size(); ++i, ++idx)
382 19670 : dof_values[idx] = value(i);
383 :
384 8110 : _has_dof_values = true;
385 8110 : _nodal_value = value;
386 8110 : }
387 :
388 : template <typename OutputType>
389 : void
390 49040191 : MooseVariableDataBase<OutputType>::insert(NumericVector<Number> & residual)
391 : {
392 49040191 : if (_has_dof_values)
393 : {
394 47880887 : 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 47880887 : residual.insert(&dof_values[0], _dof_indices);
398 : }
399 49040191 : }
400 :
401 : template <>
402 : void
403 624826 : MooseVariableDataBase<RealEigenVector>::insert(NumericVector<Number> & residual)
404 : {
405 624826 : if (_has_dof_values)
406 : {
407 624826 : auto & dof_values = _vector_tags_dof_u[_solution_tag];
408 624826 : if (isNodal())
409 : {
410 1286854 : for (unsigned int i = 0; i < _dof_indices.size(); ++i)
411 2104604 : for (unsigned int j = 0; j < _count; ++j)
412 1409992 : residual.set(_dof_indices[i] + j, dof_values[i](j));
413 : }
414 : else
415 : {
416 32584 : unsigned int n = 0;
417 103544 : for (unsigned int j = 0; j < _count; ++j)
418 : {
419 485264 : for (unsigned int i = 0; i < _dof_indices.size(); ++i)
420 414304 : residual.set(_dof_indices[i] + n, dof_values[i](j));
421 70960 : n += _dof_indices.size();
422 : }
423 : }
424 : }
425 624826 : }
426 :
427 : template <typename OutputType>
428 : void
429 2043437 : MooseVariableDataBase<OutputType>::add(NumericVector<Number> & residual)
430 : {
431 2043437 : if (_has_dof_values)
432 : {
433 36956 : auto & dof_values = _vector_tags_dof_u[_solution_tag];
434 36956 : residual.add_vector(&dof_values[0], _dof_indices);
435 : }
436 2043437 : }
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 1233 : MooseVariableDataBase<OutputType>::nodalValue(Moose::SolutionState state) const
467 : {
468 1233 : if (isNodal())
469 : {
470 : // Request the correct solution states and data members
471 1233 : vectorTagDofValue(state);
472 1233 : switch (state)
473 : {
474 1233 : case Moose::Current:
475 1233 : 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 22228 : MooseVariableDataBase<OutputType>::nodalValueArray(Moose::SolutionState state) const
501 : {
502 22228 : if (isNodal())
503 : {
504 : // Request the correct solution states and data members
505 22228 : vectorTagDofValue(state);
506 22228 : switch (state)
507 : {
508 22085 : case Moose::Current:
509 22085 : return _nodal_value_array;
510 :
511 130 : case Moose::Old:
512 130 : return _nodal_value_old_array;
513 :
514 13 : case Moose::Older:
515 13 : 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 1104787514 : MooseVariableDataBase<OutputType>::fetchDoFValues()
530 : {
531 1104787514 : bool is_transient = _subproblem.isTransient();
532 :
533 1104787514 : auto n = _dof_indices.size();
534 : libmesh_assert(n);
535 :
536 1104787514 : if (is_transient)
537 : {
538 867099440 : if (_need_u_dot || _need_grad_dot || _need_dof_values_dot)
539 : {
540 : libmesh_assert(_sys.solutionUDot());
541 315625731 : _dof_values_dot.resize(n);
542 315625731 : _sys.solutionUDot()->get(_dof_indices, &_dof_values_dot[0]);
543 : }
544 867099440 : if (_need_u_dotdot || _need_grad_dotdot || _need_dof_values_dotdot)
545 : {
546 : libmesh_assert(_sys.solutionUDotDot());
547 15476 : _dof_values_dotdot.resize(n);
548 15476 : _sys.solutionUDotDot()->get(_dof_indices, &_dof_values_dotdot[0]);
549 : }
550 867099440 : 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 867099440 : 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 2224271197 : for (auto tag : _required_vector_tags)
565 1119483683 : if (_need_vector_tag_u[tag] || _need_vector_tag_grad[tag] || _need_vector_tag_dof_u[tag])
566 1119019415 : if ((_subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_RESIDUAL &&
567 2237972506 : _subproblem.safeAccessTaggedVectors()) ||
568 1118953091 : _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 1119019415 : if (_sys.hasVector(tag) /* && _sys.getVector(tag).closed()*/)
574 : {
575 1119019415 : auto & vec = _sys.getVector(tag);
576 1119019415 : _vector_tags_dof_u[tag].resize(n);
577 1119019415 : vec.get(_dof_indices, &_vector_tags_dof_u[tag][0]);
578 : }
579 : }
580 :
581 1104787514 : if (_subproblem.safeAccessTaggedMatrices())
582 : {
583 : auto & active_coupleable_matrix_tags =
584 879509362 : _subproblem.getActiveFEVariableCoupleableMatrixTags(_tid);
585 :
586 879725354 : for (auto tag : active_coupleable_matrix_tags)
587 : {
588 215992 : _matrix_tags_dof_u[tag].resize(n);
589 215992 : if (_need_matrix_tag_dof_u[tag] || _need_matrix_tag_u[tag])
590 54032 : if (_sys.hasMatrix(tag) && _sys.matrixTagActive(tag) && _sys.getMatrix(tag).closed())
591 : {
592 54032 : auto & mat = _sys.getMatrix(tag);
593 108320 : for (unsigned i = 0; i < n; i++)
594 : {
595 54288 : Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
596 54288 : _matrix_tags_dof_u[tag][i] = mat(_dof_indices[i], _dof_indices[i]);
597 : }
598 : }
599 : }
600 : }
601 :
602 1104787514 : if (_need_du_dot_du || _need_dof_du_dot_du)
603 : {
604 315619731 : _dof_du_dot_du.resize(n);
605 1436211072 : for (decltype(n) i = 0; i < n; ++i)
606 1120591341 : _dof_du_dot_du[i] = _sys.duDotDu(_var.number());
607 : }
608 1104787514 : if (_need_du_dotdot_du || _need_dof_du_dotdot_du)
609 : {
610 10204 : _dof_du_dotdot_du.resize(n);
611 57864 : for (decltype(n) i = 0; i < n; ++i)
612 47660 : _dof_du_dotdot_du[i] = _sys.duDotDotDu();
613 : }
614 1104787514 : }
615 :
616 : template <typename OutputType>
617 : void
618 8429962 : MooseVariableDataBase<OutputType>::getArrayDoFValues(const NumericVector<Number> & sol,
619 : unsigned int n,
620 : MooseArray<RealEigenVector> & dof_values) const
621 : {
622 8429962 : dof_values.resize(n);
623 8429962 : if (isNodal())
624 : {
625 34062579 : for (unsigned int i = 0; i < n; ++i)
626 : {
627 25908456 : dof_values[i].resize(_count);
628 25908456 : auto dof = _dof_indices[i];
629 87529416 : for (unsigned int j = 0; j < _count; ++j)
630 61620960 : dof_values[i](j) = sol(dof++);
631 : }
632 : }
633 : else
634 : {
635 1585061 : for (unsigned int i = 0; i < n; ++i)
636 : {
637 1309222 : dof_values[i].resize(_count);
638 1309222 : auto dof = _dof_indices[i];
639 4450347 : for (unsigned int j = 0; j < _count; ++j)
640 : {
641 3141125 : dof_values[i](j) = sol(dof);
642 3141125 : dof += n;
643 : }
644 : }
645 : }
646 8429962 : }
647 :
648 : template <>
649 : void
650 5745919 : MooseVariableDataBase<RealEigenVector>::fetchDoFValues()
651 : {
652 5745919 : bool is_transient = _subproblem.isTransient();
653 :
654 5745919 : auto n = _dof_indices.size();
655 : libmesh_assert(n);
656 :
657 5745919 : if (is_transient)
658 : {
659 5408493 : if (_need_u_dot || _need_grad_dot || _need_dof_values_dot)
660 : {
661 : libmesh_assert(_sys.solutionUDot());
662 2683515 : getArrayDoFValues(*_sys.solutionUDot(), n, _dof_values_dot);
663 : }
664 5408493 : 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 5408493 : 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 5408493 : 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 11493278 : for (auto tag : _required_vector_tags)
682 5747359 : if ((_subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_RESIDUAL &&
683 11493278 : _subproblem.safeAccessTaggedVectors()) ||
684 5745919 : _subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_SOLUTION)
685 : // tag is defined on problem but may not be used by a system
686 5747359 : if (_sys.hasVector(tag) && _sys.getVector(tag).closed())
687 5746447 : getArrayDoFValues(_sys.getVector(tag), n, _vector_tags_dof_u[tag]);
688 :
689 5745919 : if (_subproblem.safeAccessTaggedMatrices())
690 : {
691 : auto & active_coupleable_matrix_tags =
692 4778301 : _subproblem.getActiveFEVariableCoupleableMatrixTags(_tid);
693 4778301 : 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 5745919 : if (_need_du_dot_du || _need_dof_du_dot_du)
711 : {
712 2683515 : _dof_du_dot_du.resize(n);
713 12284505 : for (decltype(n) i = 0; i < n; ++i)
714 9600990 : _dof_du_dot_du[i] = _sys.duDotDu(_var.number());
715 : }
716 5745919 : 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 5745919 : }
723 :
724 : template <typename OutputType>
725 : void
726 210 : MooseVariableDataBase<OutputType>::zeroSizeDofValues()
727 : {
728 210 : if (_subproblem.isTransient())
729 : {
730 162 : _dof_values_dot.resize(0);
731 162 : _dof_values_dotdot.resize(0);
732 162 : _dof_values_dot_old.resize(0);
733 162 : _dof_values_dotdot_old.resize(0);
734 162 : _dof_du_dot_du.resize(0);
735 162 : _dof_du_dotdot_du.resize(0);
736 : }
737 :
738 1698 : for (auto & dof_values : _vector_tags_dof_u)
739 1488 : dof_values.resize(0);
740 :
741 210 : _has_dof_values = false;
742 210 : }
743 :
744 : template <typename OutputType>
745 : void
746 270234871 : MooseVariableDataBase<OutputType>::assignNodalValue()
747 : {
748 270234871 : bool is_transient = _subproblem.isTransient();
749 :
750 : libmesh_assert(_dof_indices.size());
751 :
752 270234871 : auto & dof_values = _vector_tags_dof_u[_solution_tag];
753 270234871 : _nodal_value = dof_values[0];
754 270234871 : _nodal_value_array[0] = _nodal_value;
755 :
756 270234871 : if (is_transient)
757 : {
758 243705317 : if (oldestSolutionStateRequested() >= 1)
759 : {
760 4694156 : _nodal_value_old = _vector_tags_dof_u[_old_solution_tag][0];
761 4694156 : _nodal_value_old_array[0] = _nodal_value_old;
762 : }
763 243705317 : if (oldestSolutionStateRequested() >= 2)
764 : {
765 1632476 : _nodal_value_older = _vector_tags_dof_u[_older_solution_tag][0];
766 1632476 : _nodal_value_older_array[0] = _nodal_value_older;
767 : }
768 243705317 : if (_need_dof_values_dot)
769 1442439 : _nodal_value_dot = _dof_values_dot[0];
770 243705317 : if (_need_dof_values_dotdot)
771 0 : _nodal_value_dotdot = _dof_values_dotdot[0];
772 243705317 : if (_need_dof_values_dot_old)
773 0 : _nodal_value_dot_old = _dof_values_dot_old[0];
774 243705317 : if (_need_dof_values_dotdot_old)
775 0 : _nodal_value_dotdot_old = _dof_values_dotdot_old[0];
776 : }
777 270234871 : if (_previous_nl_solution_tag != Moose::INVALID_TAG_ID)
778 51656 : _nodal_value_previous_nl = _vector_tags_dof_u[_previous_nl_solution_tag][0];
779 270234871 : }
780 :
781 : template <>
782 : void
783 560356 : MooseVariableDataBase<RealVectorValue>::assignNodalValue()
784 : {
785 560356 : bool is_transient = _subproblem.isTransient();
786 :
787 560356 : auto n = _dof_indices.size();
788 : libmesh_assert(n);
789 :
790 560356 : auto & dof_values = _vector_tags_dof_u[_solution_tag];
791 1807923 : for (decltype(n) i = 0; i < n; ++i)
792 1247567 : _nodal_value(i) = dof_values[i];
793 560356 : _nodal_value_array[0] = _nodal_value;
794 :
795 560356 : if (is_transient)
796 : {
797 289628 : if (oldestSolutionStateRequested() >= 1)
798 : {
799 50536 : auto & dof_values_old = _vector_tags_dof_u[_old_solution_tag];
800 198448 : for (decltype(n) i = 0; i < n; ++i)
801 147912 : _nodal_value_old(i) = dof_values_old[i];
802 50536 : _nodal_value_old_array[0] = _nodal_value_old;
803 : }
804 289628 : if (oldestSolutionStateRequested() >= 2)
805 : {
806 3696 : auto & dof_values_older = _vector_tags_dof_u[_older_solution_tag];
807 11088 : for (decltype(n) i = 0; i < n; ++i)
808 7392 : _nodal_value_older(i) = dof_values_older[i];
809 3696 : _nodal_value_older_array[0] = _nodal_value_older;
810 : }
811 289628 : 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 289628 : 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 289628 : 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 289628 : 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 560356 : 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 560356 : }
831 :
832 : template class MooseVariableDataBase<Real>;
833 : template class MooseVariableDataBase<RealVectorValue>;
834 : template class MooseVariableDataBase<RealEigenVector>;
|