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 535511 : MooseVariableDataBase<OutputType>::MooseVariableDataBase(const MooseVariableField<OutputType> & var,
19 : SystemBase & sys,
20 : THREAD_ID tid)
21 535511 : : _sys(sys),
22 1071022 : _subproblem(_sys.subproblem()),
23 535511 : _tid(tid),
24 535511 : _dof_map(_sys.dofMap()),
25 535511 : _count(var.count()),
26 535511 : _has_dof_values(false),
27 535511 : _max_state(0),
28 535511 : _solution_tag(_subproblem.getVectorTagID(Moose::SOLUTION_TAG)),
29 535511 : _old_solution_tag(Moose::INVALID_TAG_ID),
30 535511 : _older_solution_tag(Moose::INVALID_TAG_ID),
31 535511 : _previous_nl_solution_tag(Moose::INVALID_TAG_ID),
32 535511 : _need_u_dot(false),
33 535511 : _need_u_dotdot(false),
34 535511 : _need_u_dot_old(false),
35 535511 : _need_u_dotdot_old(false),
36 535511 : _need_du_dot_du(false),
37 535511 : _need_du_dotdot_du(false),
38 535511 : _need_grad_dot(false),
39 535511 : _need_grad_dotdot(false),
40 535511 : _need_dof_values_dot(false),
41 535511 : _need_dof_values_dotdot(false),
42 535511 : _need_dof_values_dot_old(false),
43 535511 : _need_dof_values_dotdot_old(false),
44 535511 : _need_dof_du_dot_du(false),
45 535511 : _need_dof_du_dotdot_du(false),
46 1071022 : _var(var)
47 : {
48 535511 : 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 535511 : const auto max_future_num_vector_tags = num_vector_tags + 2;
54 :
55 535511 : _vector_tags_dof_u.reserve(max_future_num_vector_tags);
56 535511 : _vector_tags_dof_u.resize(num_vector_tags);
57 535511 : _need_vector_tag_dof_u.reserve(max_future_num_vector_tags);
58 535511 : _need_vector_tag_dof_u.resize(num_vector_tags, false);
59 :
60 535511 : _need_vector_tag_u.reserve(max_future_num_vector_tags);
61 535511 : _need_vector_tag_u.resize(num_vector_tags, false);
62 535511 : _vector_tag_u.reserve(max_future_num_vector_tags);
63 535511 : _vector_tag_u.resize(num_vector_tags);
64 :
65 535511 : _need_vector_tag_grad.reserve(max_future_num_vector_tags);
66 535511 : _need_vector_tag_grad.resize(num_vector_tags, false);
67 535511 : _vector_tag_grad.reserve(max_future_num_vector_tags);
68 535511 : _vector_tag_grad.resize(num_vector_tags);
69 :
70 : // Always fetch the dof values for the solution tag
71 535511 : const auto soln_tag = _subproblem.getVectorTagID(Moose::SOLUTION_TAG);
72 535511 : _need_vector_tag_dof_u[soln_tag] = true;
73 535511 : _need_vector_tag_u[soln_tag] = true;
74 535511 : 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 535511 : _nodal_value_array.resize(1);
79 535511 : _nodal_value_old_array.resize(1);
80 535511 : _nodal_value_older_array.resize(1);
81 535511 : }
82 :
83 : template <typename OutputType>
84 : void
85 386386 : MooseVariableDataBase<OutputType>::sizeMatrixTagData()
86 : {
87 386386 : auto num_matrix_tags = _subproblem.numMatrixTags();
88 :
89 386386 : _matrix_tags_dof_u.resize(num_matrix_tags);
90 386386 : _need_matrix_tag_dof_u.resize(num_matrix_tags, false);
91 :
92 386386 : _need_matrix_tag_u.resize(num_matrix_tags, false);
93 386386 : _matrix_tag_u.resize(num_matrix_tags);
94 386386 : }
95 :
96 : template <typename OutputType>
97 : const typename MooseVariableDataBase<OutputType>::DofValues &
98 433 : MooseVariableDataBase<OutputType>::nodalVectorTagValue(TagID tag) const
99 : {
100 433 : if (isNodal())
101 : {
102 433 : if (tag >= _need_vector_tag_dof_u.size())
103 0 : const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
104 :
105 433 : _need_vector_tag_dof_u[tag] = true;
106 :
107 433 : if (_sys.hasVector(tag))
108 433 : return _vector_tags_dof_u[tag];
109 : else
110 0 : mooseError(
111 0 : "Tag ", tag, " is not associated with any vector for nodal variable ", _var.name());
112 : }
113 : else
114 0 : mooseError("Nodal values can be requested only on nodal variables, variable '",
115 0 : _var.name(),
116 : "' is not nodal.");
117 : }
118 :
119 : template <typename OutputType>
120 : const typename MooseVariableDataBase<OutputType>::DofValues &
121 225 : MooseVariableDataBase<OutputType>::nodalMatrixTagValue(TagID tag) const
122 : {
123 225 : if (isNodal())
124 : {
125 225 : if (tag >= _matrix_tags_dof_u.size())
126 : {
127 0 : _need_matrix_tag_dof_u.resize(tag + 1, false);
128 0 : const_cast<MooseVariableDataBase<OutputType> *>(this)->_matrix_tags_dof_u.resize(tag + 1);
129 : }
130 :
131 225 : _need_matrix_tag_dof_u[tag] = true;
132 :
133 225 : if (_sys.hasMatrix(tag))
134 225 : return _matrix_tags_dof_u[tag];
135 : else
136 0 : mooseError(
137 0 : "Tag ", tag, " is not associated with any matrix for nodal variable ", _var.name());
138 : }
139 : else
140 0 : mooseError("Nodal values can be requested only on nodal variables, variable '",
141 0 : _var.name(),
142 : "' is not nodal.");
143 : }
144 :
145 : template <typename OutputType>
146 : void
147 507 : 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 6591 : auto check_capacity = [tag](const auto & vector_to_check)
157 : {
158 3042 : 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 507 : check_capacity(_need_vector_tag_dof_u);
163 507 : check_capacity(_need_vector_tag_u);
164 507 : check_capacity(_need_vector_tag_grad);
165 507 : check_capacity(_vector_tags_dof_u);
166 507 : check_capacity(_vector_tag_u);
167 507 : check_capacity(_vector_tag_grad);
168 :
169 507 : _need_vector_tag_dof_u.resize(tag + 1, false);
170 507 : _need_vector_tag_u.resize(tag + 1, false);
171 507 : _need_vector_tag_grad.resize(tag + 1, false);
172 507 : _vector_tags_dof_u.resize(tag + 1);
173 507 : _vector_tag_u.resize(tag + 1);
174 507 : _vector_tag_grad.resize(tag + 1);
175 507 : }
176 :
177 : template <typename OutputType>
178 : const typename MooseVariableDataBase<OutputType>::FieldVariableValue &
179 346475 : MooseVariableDataBase<OutputType>::vectorTagValue(TagID tag) const
180 : {
181 346475 : if (tag >= _need_vector_tag_u.size())
182 117 : const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
183 :
184 346475 : _need_vector_tag_u[tag] = true;
185 :
186 346475 : if (_sys.hasVector(tag))
187 346475 : 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>::DofValues &
194 915906 : MooseVariableDataBase<OutputType>::vectorTagDofValue(TagID tag) const
195 : {
196 915906 : if (tag >= _need_vector_tag_dof_u.size())
197 156 : const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
198 :
199 915906 : _need_vector_tag_dof_u[tag] = true;
200 :
201 915906 : if (_sys.hasVector(tag))
202 915906 : 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 126576 : MooseVariableDataBase<OutputType>::vectorTagGradient(TagID tag) const
210 : {
211 126576 : if (tag >= _need_vector_tag_grad.size())
212 13 : const_cast<MooseVariableDataBase<OutputType> *>(this)->resizeVectorTagData(tag);
213 :
214 126576 : _need_vector_tag_grad[tag] = true;
215 :
216 126576 : if (_sys.hasVector(tag))
217 126576 : 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 48 : MooseVariableDataBase<OutputType>::matrixTagValue(TagID tag) const
225 : {
226 48 : 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 48 : _need_matrix_tag_u[tag] = true;
233 :
234 48 : if (_sys.hasMatrix(tag))
235 48 : 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 439974631 : MooseVariableDataBase<OutputType>::oldestSolutionStateRequested() const
243 : {
244 439974631 : return _max_state;
245 : }
246 :
247 : template <typename OutputType>
248 : void
249 35944 : MooseVariableDataBase<OutputType>::needSolutionState(const unsigned int state)
250 : {
251 35944 : if (state > _max_state)
252 : {
253 15750 : _sys.needSolutionState(state);
254 15750 : _max_state = state;
255 : }
256 35944 : }
257 :
258 : template <typename OutputType>
259 : template <typename ReturnType, typename Functor>
260 : const ReturnType &
261 1388091 : MooseVariableDataBase<OutputType>::stateToTagHelper(const Moose::SolutionState state,
262 : Functor functor)
263 : {
264 1388091 : if (state > 0)
265 : {
266 : // We need to request all states that are between current and the requested state
267 35944 : stateToTagHelper<ReturnType>(Moose::SolutionState(static_cast<int>(state) - 1), functor);
268 35944 : needSolutionState(cast_int<unsigned int>(state));
269 : }
270 :
271 1388091 : switch (state)
272 : {
273 1352071 : case Moose::Current:
274 1352071 : return functor(_subproblem.getVectorTagID(Moose::SOLUTION_TAG));
275 :
276 24777 : case Moose::Old:
277 : {
278 24777 : _old_solution_tag = _subproblem.getVectorTagID(Moose::OLD_SOLUTION_TAG);
279 24777 : insertSolutionTag(_old_solution_tag);
280 24777 : return functor(_old_solution_tag);
281 : }
282 :
283 11167 : case Moose::Older:
284 : {
285 11167 : _older_solution_tag = _subproblem.getVectorTagID(Moose::OLDER_SOLUTION_TAG);
286 11167 : insertSolutionTag(_older_solution_tag);
287 11167 : return functor(_older_solution_tag);
288 : }
289 :
290 76 : case Moose::PreviousNL:
291 : {
292 76 : _previous_nl_solution_tag = _subproblem.getVectorTagID(Moose::PREVIOUS_NL_SOLUTION_TAG);
293 76 : insertSolutionTag(_previous_nl_solution_tag);
294 76 : 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 311140 : MooseVariableDataBase<OutputType>::sln(Moose::SolutionState state) const
307 : {
308 656906 : auto functor = [this](TagID tag_id) -> const FieldVariableValue &
309 345766 : { return vectorTagValue(tag_id); };
310 :
311 : return const_cast<MooseVariableDataBase<OutputType> *>(this)
312 622280 : ->stateToTagHelper<FieldVariableValue>(state, functor);
313 : }
314 :
315 : template <typename OutputType>
316 : const typename MooseVariableDataBase<OutputType>::FieldVariableGradient &
317 125620 : MooseVariableDataBase<OutputType>::gradSln(Moose::SolutionState state) const
318 : {
319 252170 : auto functor = [this](TagID tag_id) -> const FieldVariableGradient &
320 126550 : { return vectorTagGradient(tag_id); };
321 :
322 : return const_cast<MooseVariableDataBase<OutputType> *>(this)
323 251240 : ->stateToTagHelper<FieldVariableGradient>(state, functor);
324 : }
325 :
326 : template <typename OutputType>
327 : const typename MooseVariableDataBase<OutputType>::DofValues &
328 915387 : MooseVariableDataBase<OutputType>::vectorTagDofValue(Moose::SolutionState state) const
329 : {
330 1831162 : auto functor = [this](TagID tag_id) -> const DofValues & { return vectorTagDofValue(tag_id); };
331 :
332 915387 : return const_cast<MooseVariableDataBase<OutputType> *>(this)->stateToTagHelper<DofValues>(
333 1830774 : state, functor);
334 : }
335 :
336 : template <typename OutputType>
337 : const typename MooseVariableDataBase<OutputType>::DofValues &
338 891009 : MooseVariableDataBase<OutputType>::dofValues() const
339 : {
340 891009 : return vectorTagDofValue(Moose::Current);
341 : }
342 :
343 : template <typename OutputType>
344 : const typename MooseVariableDataBase<OutputType>::DofValues &
345 128 : MooseVariableDataBase<OutputType>::dofValuesOld() const
346 : {
347 128 : return vectorTagDofValue(Moose::Old);
348 : }
349 :
350 : template <typename OutputType>
351 : const typename MooseVariableDataBase<OutputType>::DofValues &
352 52 : MooseVariableDataBase<OutputType>::dofValuesOlder() const
353 : {
354 52 : return vectorTagDofValue(Moose::Older);
355 : }
356 :
357 : template <typename OutputType>
358 : const typename MooseVariableDataBase<OutputType>::DofValues &
359 0 : MooseVariableDataBase<OutputType>::dofValuesPreviousNL() const
360 : {
361 0 : return vectorTagDofValue(Moose::PreviousNL);
362 : }
363 :
364 : template <typename OutputType>
365 : void
366 45811007 : MooseVariableDataBase<OutputType>::setNodalValue(const OutputType & value, unsigned int idx)
367 : {
368 45811007 : 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 45811007 : dof_values[idx] = value; // update variable nodal value
371 45811007 : _has_dof_values = true;
372 45811007 : _nodal_value = value;
373 :
374 : // Update the qp values as well
375 45811007 : auto & u = _vector_tag_u[_solution_tag];
376 227136525 : for (unsigned int qp = 0; qp < u.size(); qp++)
377 181325518 : u[qp] = value;
378 45811007 : }
379 :
380 : template <>
381 : void
382 8315 : MooseVariableDataBase<RealVectorValue>::setNodalValue(const RealVectorValue & value,
383 : unsigned int idx)
384 : {
385 8315 : auto & dof_values = _vector_tags_dof_u[_solution_tag];
386 28449 : for (decltype(idx) i = 0; i < dof_values.size(); ++i, ++idx)
387 20134 : dof_values[idx] = value(i);
388 :
389 8315 : _has_dof_values = true;
390 8315 : _nodal_value = value;
391 8315 : }
392 :
393 : template <typename OutputType>
394 : void
395 49518574 : MooseVariableDataBase<OutputType>::insert(NumericVector<Number> & residual)
396 : {
397 49518574 : if (_has_dof_values)
398 : {
399 48411611 : const 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 48411611 : residual.insert(&dof_values[0], _dof_indices);
403 : }
404 49518574 : }
405 :
406 : template <>
407 : void
408 633042 : MooseVariableDataBase<RealEigenVector>::insert(NumericVector<Number> & residual)
409 : {
410 633042 : if (_has_dof_values)
411 : {
412 633042 : const auto & dof_values = _vector_tags_dof_u[_solution_tag];
413 : mooseAssert(_dof_indices.size() % _count == 0,
414 : "Dof indices should be cleanly divisible by the variable count");
415 633042 : const auto n_shapes = _dof_indices.size() / _count;
416 2453420 : for (const auto indx : index_range(_dof_indices))
417 : {
418 1820378 : const auto i = indx % n_shapes;
419 1820378 : const auto j = indx / n_shapes;
420 1820378 : residual.set(_dof_indices[indx], dof_values[i](j));
421 : }
422 : }
423 633042 : }
424 :
425 : template <typename OutputType>
426 : void
427 1959703 : MooseVariableDataBase<OutputType>::add(NumericVector<Number> & residual)
428 : {
429 1959703 : if (_has_dof_values)
430 : {
431 33256 : const auto & dof_values = _vector_tags_dof_u[_solution_tag];
432 33256 : residual.add_vector(&dof_values[0], _dof_indices);
433 : }
434 1959703 : }
435 :
436 : template <>
437 : void
438 0 : MooseVariableDataBase<RealEigenVector>::add(NumericVector<Number> & residual)
439 : {
440 0 : if (_has_dof_values)
441 : {
442 0 : const auto & dof_values = _vector_tags_dof_u[_solution_tag];
443 : mooseAssert(_dof_indices.size() % _count == 0,
444 : "Dof indices should be cleanly divisible by the variable count");
445 0 : const auto n_shapes = _dof_indices.size() / _count;
446 0 : for (const auto indx : index_range(_dof_indices))
447 : {
448 0 : const auto i = indx % n_shapes;
449 0 : const auto j = indx / n_shapes;
450 0 : residual.add(_dof_indices[indx], dof_values[i](j));
451 : }
452 : }
453 0 : }
454 :
455 : template <typename OutputType>
456 : const OutputType &
457 1239 : MooseVariableDataBase<OutputType>::nodalValue(Moose::SolutionState state) const
458 : {
459 1239 : if (isNodal())
460 : {
461 : // Request the correct solution states and data members
462 1239 : vectorTagDofValue(state);
463 1239 : switch (state)
464 : {
465 1239 : case Moose::Current:
466 1239 : return _nodal_value;
467 :
468 0 : case Moose::Old:
469 0 : return _nodal_value_old;
470 :
471 0 : case Moose::Older:
472 0 : return _nodal_value_older;
473 :
474 0 : case Moose::PreviousNL:
475 0 : return _nodal_value_previous_nl;
476 :
477 0 : default:
478 : // We should never get here but gcc requires that we have a default. See
479 : // htpps://stackoverflow.com/questions/18680378/after-defining-case-for-all-enum-values-compiler-still-says-control-reaches-e
480 0 : mooseError("Unknown SolutionState!");
481 : }
482 : }
483 : else
484 0 : mooseError("Nodal values can be requested only on nodal variables, variable '",
485 0 : _var.name(),
486 : "' is not nodal.");
487 : }
488 :
489 : template <typename OutputType>
490 : const MooseArray<OutputType> &
491 22959 : MooseVariableDataBase<OutputType>::nodalValueArray(Moose::SolutionState state) const
492 : {
493 22959 : if (isNodal())
494 : {
495 : // Request the correct solution states and data members
496 22959 : vectorTagDofValue(state);
497 22959 : switch (state)
498 : {
499 22816 : case Moose::Current:
500 22816 : return _nodal_value_array;
501 :
502 130 : case Moose::Old:
503 130 : return _nodal_value_old_array;
504 :
505 13 : case Moose::Older:
506 13 : return _nodal_value_older_array;
507 :
508 0 : default:
509 0 : mooseError("No current support for PreviousNL for nodal value array");
510 : }
511 : }
512 : else
513 0 : mooseError("Nodal values can be requested only on nodal variables, variable '",
514 0 : _var.name(),
515 : "' is not nodal.");
516 : }
517 :
518 : template <typename OutputType>
519 : void
520 1039575875 : MooseVariableDataBase<OutputType>::fetchDofValues()
521 : {
522 1039575875 : bool is_transient = _subproblem.isTransient();
523 :
524 1039575875 : auto n = _dof_indices.size();
525 : libmesh_assert(n);
526 :
527 1039575875 : if (is_transient)
528 : {
529 821726485 : if (_need_u_dot || _need_grad_dot || _need_dof_values_dot)
530 : {
531 : libmesh_assert(_sys.solutionUDot());
532 305154690 : _dof_values_dot.resize(n);
533 305154690 : _sys.solutionUDot()->get(_dof_indices, &_dof_values_dot[0]);
534 : }
535 821726485 : if (_need_u_dotdot || _need_grad_dotdot || _need_dof_values_dotdot)
536 : {
537 : libmesh_assert(_sys.solutionUDotDot());
538 13246 : _dof_values_dotdot.resize(n);
539 13246 : _sys.solutionUDotDot()->get(_dof_indices, &_dof_values_dotdot[0]);
540 : }
541 821726485 : if (_need_u_dot_old || _need_dof_values_dot_old)
542 : {
543 : libmesh_assert(_sys.solutionUDotOld());
544 0 : _dof_values_dot_old.resize(n);
545 0 : _sys.solutionUDotOld()->get(_dof_indices, &_dof_values_dot_old[0]);
546 : }
547 821726485 : if (_need_u_dotdot_old || _need_dof_values_dotdot_old)
548 : {
549 : libmesh_assert(_sys.solutionUDotDotOld());
550 0 : _dof_values_dotdot_old.resize(n);
551 0 : _sys.solutionUDotDotOld()->get(_dof_indices, &_dof_values_dotdot_old[0]);
552 : }
553 : }
554 :
555 2091318823 : for (auto tag : _required_vector_tags)
556 1051742948 : if (_need_vector_tag_u[tag] || _need_vector_tag_grad[tag] || _need_vector_tag_dof_u[tag])
557 1051240749 : if ((_subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_RESIDUAL &&
558 2102401969 : _subproblem.safeAccessTaggedVectors()) ||
559 1051161220 : _subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_SOLUTION)
560 : {
561 : // tag is defined on problem but may not be used by a system
562 : // the grain tracker requires being able to read from solution vectors that we are also in
563 : // the process of writing :-/
564 : // Note: the extra vector tags are also still not closed when a TagVectorAux uses them
565 1051240749 : if (_sys.hasVector(tag) /* && _sys.getVector(tag).closed()*/)
566 : {
567 1051240749 : auto & vec = _sys.getVector(tag);
568 1051240749 : _vector_tags_dof_u[tag].resize(n);
569 1051240749 : vec.get(_dof_indices, &_vector_tags_dof_u[tag][0]);
570 : }
571 : }
572 :
573 1039575875 : if (_subproblem.safeAccessTaggedMatrices())
574 : {
575 : auto & active_coupleable_matrix_tags =
576 829896711 : _subproblem.getActiveFEVariableCoupleableMatrixTags(_tid);
577 :
578 830172338 : for (auto tag : active_coupleable_matrix_tags)
579 : {
580 275627 : _matrix_tags_dof_u[tag].resize(n);
581 275627 : if (_need_matrix_tag_dof_u[tag] || _need_matrix_tag_u[tag])
582 69085 : if (_sys.hasMatrix(tag) && _sys.matrixTagActive(tag))
583 : {
584 : mooseAssert(_sys.getMatrix(tag).closed(),
585 : "Matrix with tag '" + std::to_string(tag) + "' should be closed");
586 69085 : auto & mat = _sys.getMatrix(tag);
587 138426 : for (unsigned i = 0; i < n; i++)
588 69341 : _matrix_tags_dof_u[tag][i] = mat(_dof_indices[i], _dof_indices[i]);
589 : }
590 : }
591 : }
592 :
593 1039575875 : if (_need_du_dot_du || _need_dof_du_dot_du)
594 : {
595 305149178 : _dof_du_dot_du.resize(n);
596 1406078477 : for (decltype(n) i = 0; i < n; ++i)
597 1100929299 : _dof_du_dot_du[i] = _sys.duDotDu(_var.number());
598 : }
599 1039575875 : if (_need_du_dotdot_du || _need_dof_du_dotdot_du)
600 : {
601 9646 : _dof_du_dotdot_du.resize(n);
602 56942 : for (decltype(n) i = 0; i < n; ++i)
603 47296 : _dof_du_dotdot_du[i] = _sys.duDotDotDu();
604 : }
605 1039575875 : }
606 :
607 : template <typename OutputType>
608 : void
609 8721772 : MooseVariableDataBase<OutputType>::getArrayDofValues(const NumericVector<Number> & sol,
610 : const unsigned int nshapes,
611 : MooseArray<RealEigenVector> & dof_values) const
612 : {
613 8721772 : dof_values.resize(nshapes);
614 36857386 : for (const auto i : make_range(nshapes))
615 : {
616 28135614 : dof_values[i].resize(_count);
617 94887119 : for (const auto j : make_range(_count))
618 66751505 : dof_values[i](j) = sol(_dof_indices[j * nshapes + i]);
619 : }
620 8721772 : }
621 :
622 : template <>
623 : void
624 5900368 : MooseVariableDataBase<RealEigenVector>::fetchDofValues()
625 : {
626 5900368 : bool is_transient = _subproblem.isTransient();
627 :
628 5900368 : auto n = _dof_indices.size() / _count;
629 : libmesh_assert(n);
630 :
631 5900368 : if (is_transient)
632 : {
633 5547488 : if (_need_u_dot || _need_grad_dot || _need_dof_values_dot)
634 : {
635 : libmesh_assert(_sys.solutionUDot());
636 2820826 : getArrayDofValues(*_sys.solutionUDot(), n, _dof_values_dot);
637 : }
638 5547488 : if (_need_u_dotdot || _need_grad_dotdot || _need_dof_values_dotdot)
639 : {
640 : libmesh_assert(_sys.solutionUDotDot());
641 0 : getArrayDofValues(*_sys.solutionUDot(), n, _dof_values_dotdot);
642 : }
643 5547488 : if (_need_u_dot_old || _need_dof_values_dot_old)
644 : {
645 : libmesh_assert(_sys.solutionUDotOld());
646 0 : getArrayDofValues(*_sys.solutionUDotOld(), n, _dof_values_dot_old);
647 : }
648 5547488 : if (_need_u_dotdot_old || _need_dof_values_dotdot_old)
649 : {
650 : libmesh_assert(_sys.solutionUDotDotOld());
651 0 : getArrayDofValues(*_sys.solutionUDotDotOld(), n, _dof_values_dotdot_old);
652 : }
653 : }
654 :
655 11802276 : for (auto tag : _required_vector_tags)
656 5901908 : if ((_subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_RESIDUAL &&
657 11802276 : _subproblem.safeAccessTaggedVectors()) ||
658 5900368 : _subproblem.vectorTagType(tag) == Moose::VECTOR_TAG_SOLUTION)
659 : // tag is defined on problem but may not be used by a system
660 5901908 : if (_sys.hasVector(tag))
661 : {
662 : mooseAssert(_sys.getVector(tag).closed(),
663 : "Vector with tag '" + std::to_string(tag) + "' should be closed");
664 5900946 : getArrayDofValues(_sys.getVector(tag), n, _vector_tags_dof_u[tag]);
665 : }
666 :
667 5900368 : if (_subproblem.safeAccessTaggedMatrices())
668 : {
669 : auto & active_coupleable_matrix_tags =
670 4915425 : _subproblem.getActiveFEVariableCoupleableMatrixTags(_tid);
671 4915425 : for (auto tag : active_coupleable_matrix_tags)
672 : {
673 0 : _matrix_tags_dof_u[tag].resize(n);
674 0 : if (_need_matrix_tag_dof_u[tag] || _need_matrix_tag_u[tag])
675 0 : if (_sys.hasMatrix(tag) && _sys.matrixTagActive(tag))
676 : {
677 : mooseAssert(_sys.getMatrix(tag).closed(),
678 : "Matrix with tag '" + std::to_string(tag) + "' should be closed");
679 0 : auto & mat = _sys.getMatrix(tag);
680 0 : for (unsigned i = 0; i < n; i++)
681 0 : for (unsigned j = 0; j < _count; j++)
682 0 : _matrix_tags_dof_u[tag][i](j) = mat(_dof_indices[i] + j, _dof_indices[i] + j);
683 : }
684 : }
685 : }
686 :
687 5900368 : if (_need_du_dot_du || _need_dof_du_dot_du)
688 : {
689 2820826 : _dof_du_dot_du.resize(n);
690 12824227 : for (decltype(n) i = 0; i < n; ++i)
691 10003401 : _dof_du_dot_du[i] = _sys.duDotDu(_var.number());
692 : }
693 5900368 : if (_need_du_dotdot_du || _need_dof_du_dotdot_du)
694 : {
695 0 : _dof_du_dotdot_du.resize(n);
696 0 : for (decltype(n) i = 0; i < n; ++i)
697 0 : _dof_du_dotdot_du[i] = _sys.duDotDotDu();
698 : }
699 5900368 : }
700 :
701 : template <typename OutputType>
702 : void
703 204 : MooseVariableDataBase<OutputType>::zeroSizeDofValues()
704 : {
705 204 : if (_subproblem.isTransient())
706 : {
707 168 : _dof_values_dot.resize(0);
708 168 : _dof_values_dotdot.resize(0);
709 168 : _dof_values_dot_old.resize(0);
710 168 : _dof_values_dotdot_old.resize(0);
711 168 : _dof_du_dot_du.resize(0);
712 168 : _dof_du_dotdot_du.resize(0);
713 : }
714 :
715 1488 : for (auto & dof_values : _vector_tags_dof_u)
716 1284 : dof_values.resize(0);
717 :
718 204 : _has_dof_values = false;
719 204 : }
720 :
721 : template <typename OutputType>
722 : void
723 245880719 : MooseVariableDataBase<OutputType>::assignNodalValue()
724 : {
725 245880719 : bool is_transient = _subproblem.isTransient();
726 : libmesh_assert(_dof_indices.size());
727 :
728 245880719 : auto & dof_values = _vector_tags_dof_u[_solution_tag];
729 245880719 : _nodal_value = dof_values[0];
730 245880719 : _nodal_value_array[0] = _nodal_value;
731 :
732 245880719 : if (is_transient)
733 : {
734 219507371 : if (oldestSolutionStateRequested() >= 1)
735 : {
736 4581819 : _nodal_value_old = _vector_tags_dof_u[_old_solution_tag][0];
737 4581819 : _nodal_value_old_array[0] = _nodal_value_old;
738 : }
739 219507371 : if (oldestSolutionStateRequested() >= 2)
740 : {
741 1606903 : _nodal_value_older = _vector_tags_dof_u[_older_solution_tag][0];
742 1606903 : _nodal_value_older_array[0] = _nodal_value_older;
743 : }
744 219507371 : if (_need_dof_values_dot)
745 1406446 : _nodal_value_dot = _dof_values_dot[0];
746 219507371 : if (_need_dof_values_dotdot)
747 0 : _nodal_value_dotdot = _dof_values_dotdot[0];
748 219507371 : if (_need_dof_values_dot_old)
749 0 : _nodal_value_dot_old = _dof_values_dot_old[0];
750 219507371 : if (_need_dof_values_dotdot_old)
751 0 : _nodal_value_dotdot_old = _dof_values_dotdot_old[0];
752 : }
753 245880719 : if (_previous_nl_solution_tag != Moose::INVALID_TAG_ID)
754 47014 : _nodal_value_previous_nl = _vector_tags_dof_u[_previous_nl_solution_tag][0];
755 245880719 : }
756 :
757 : template <>
758 : void
759 467911 : MooseVariableDataBase<RealVectorValue>::assignNodalValue()
760 : {
761 467911 : bool is_transient = _subproblem.isTransient();
762 :
763 467911 : auto n = _dof_indices.size();
764 : libmesh_assert(n);
765 :
766 467911 : auto & dof_values = _vector_tags_dof_u[_solution_tag];
767 1535513 : for (decltype(n) i = 0; i < n; ++i)
768 1067602 : _nodal_value(i) = dof_values[i];
769 467911 : _nodal_value_array[0] = _nodal_value;
770 :
771 467911 : if (is_transient)
772 : {
773 242945 : if (oldestSolutionStateRequested() >= 1)
774 : {
775 42537 : auto & dof_values_old = _vector_tags_dof_u[_old_solution_tag];
776 167123 : for (decltype(n) i = 0; i < n; ++i)
777 124586 : _nodal_value_old(i) = dof_values_old[i];
778 42537 : _nodal_value_old_array[0] = _nodal_value_old;
779 : }
780 242945 : if (oldestSolutionStateRequested() >= 2)
781 : {
782 3025 : auto & dof_values_older = _vector_tags_dof_u[_older_solution_tag];
783 9075 : for (decltype(n) i = 0; i < n; ++i)
784 6050 : _nodal_value_older(i) = dof_values_older[i];
785 3025 : _nodal_value_older_array[0] = _nodal_value_older;
786 : }
787 242945 : if (_need_dof_values_dot)
788 0 : for (decltype(n) i = 0; i < n; ++i)
789 0 : _nodal_value_dot(i) = _dof_values_dot[i];
790 242945 : if (_need_dof_values_dotdot)
791 0 : for (decltype(n) i = 0; i < n; ++i)
792 0 : _nodal_value_dotdot(i) = _dof_values_dotdot[i];
793 242945 : if (_need_dof_values_dot_old)
794 0 : for (decltype(n) i = 0; i < n; ++i)
795 0 : _nodal_value_dot_old(i) = _dof_values_dot_old[i];
796 242945 : if (_need_dof_values_dotdot_old)
797 0 : for (decltype(n) i = 0; i < n; ++i)
798 0 : _nodal_value_dotdot_old(i) = _dof_values_dotdot_old[i];
799 : }
800 467911 : if (_previous_nl_solution_tag != Moose::INVALID_TAG_ID)
801 : {
802 0 : auto & dof_values_previous_nl = _vector_tags_dof_u[_previous_nl_solution_tag];
803 0 : for (decltype(n) i = 0; i < n; ++i)
804 0 : _nodal_value_previous_nl(i) = dof_values_previous_nl[i];
805 : }
806 467911 : }
807 :
808 : template class MooseVariableDataBase<Real>;
809 : template class MooseVariableDataBase<RealVectorValue>;
810 : template class MooseVariableDataBase<RealEigenVector>;
|