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 "MooseVariableFE.h"
11 : #include <typeinfo>
12 : #include "TimeIntegrator.h"
13 : #include "NonlinearSystemBase.h"
14 : #include "DisplacedSystem.h"
15 : #include "Assembly.h"
16 : #include "MooseVariableData.h"
17 : #include "ArbitraryQuadrature.h"
18 :
19 : #include "libmesh/quadrature_monomial.h"
20 :
21 : using namespace libMesh;
22 :
23 : template <>
24 : InputParameters
25 116885 : MooseVariableFE<Real>::validParams()
26 : {
27 116885 : auto params = MooseVariableField<Real>::validParams();
28 116885 : params.addClassDescription(
29 : "Represents standard field variables, e.g. Lagrange, Hermite, or non-constant Monomials");
30 116885 : return params;
31 0 : }
32 :
33 : template <>
34 : InputParameters
35 4627 : MooseVariableFE<RealVectorValue>::validParams()
36 : {
37 4627 : auto params = MooseVariableField<RealVectorValue>::validParams();
38 4627 : params.addClassDescription(
39 : "Represents vector field variables, e.g. Vector Lagrange, Nedelec or Raviart-Thomas");
40 4627 : return params;
41 0 : }
42 :
43 : template <>
44 : InputParameters
45 5574 : MooseVariableFE<RealEigenVector>::validParams()
46 : {
47 5574 : auto params = MooseVariableField<RealEigenVector>::validParams();
48 5574 : params.addClassDescription(
49 : "Used for grouping standard field variables with the same finite element family and order");
50 5574 : return params;
51 0 : }
52 :
53 : template <typename OutputType>
54 174071 : MooseVariableFE<OutputType>::MooseVariableFE(const InputParameters & parameters)
55 174071 : : MooseVariableField<OutputType>(parameters)
56 : {
57 174071 : _element_data = std::make_unique<MooseVariableData<OutputType>>(*this,
58 : _sys,
59 174071 : _tid,
60 174071 : Moose::ElementType::Element,
61 174071 : this->_assembly.qRule(),
62 174071 : this->_assembly.qRuleFace(),
63 174071 : this->_assembly.node(),
64 174071 : this->_assembly.elem());
65 174071 : _neighbor_data = std::make_unique<MooseVariableData<OutputType>>(
66 : *this,
67 : _sys,
68 174071 : _tid,
69 174071 : Moose::ElementType::Neighbor,
70 174071 : this->_assembly.qRuleNeighbor(), // Place holder
71 174071 : this->_assembly.qRuleNeighbor(),
72 174071 : this->_assembly.nodeNeighbor(),
73 174071 : this->_assembly.neighbor());
74 174071 : _lower_data =
75 : std::make_unique<MooseVariableData<OutputType>>(*this,
76 : _sys,
77 174071 : _tid,
78 174071 : Moose::ElementType::Lower,
79 174071 : this->_assembly.qRuleFace(),
80 174071 : this->_assembly.qRuleFace(), // Place holder
81 174071 : this->_assembly.node(), // Place holder
82 174071 : this->_assembly.lowerDElem());
83 174071 : }
84 :
85 : template <typename OutputType>
86 : void
87 691173809 : MooseVariableFE<OutputType>::clearDofIndices()
88 : {
89 691173809 : _element_data->clearDofIndices();
90 691173809 : }
91 :
92 : template <typename OutputType>
93 : void
94 460622142 : MooseVariableFE<OutputType>::prepare()
95 : {
96 460622142 : _element_data->prepare();
97 460622142 : }
98 :
99 : template <typename OutputType>
100 : void
101 12686135 : MooseVariableFE<OutputType>::prepareNeighbor()
102 : {
103 12686135 : _neighbor_data->prepare();
104 12686135 : }
105 :
106 : template <typename OutputType>
107 : void
108 567998 : MooseVariableFE<OutputType>::prepareLowerD()
109 : {
110 567998 : _lower_data->prepare();
111 567998 : }
112 :
113 : template <typename OutputType>
114 : void
115 8245939 : MooseVariableFE<OutputType>::prepareAux()
116 : {
117 8245939 : _element_data->prepareAux();
118 8245939 : _neighbor_data->prepareAux();
119 8245939 : _lower_data->prepareAux();
120 8245939 : }
121 :
122 : template <typename OutputType>
123 : void
124 282198903 : MooseVariableFE<OutputType>::reinitNode()
125 : {
126 282198903 : _element_data->reinitNode();
127 282198903 : }
128 :
129 : template <typename OutputType>
130 : void
131 146841631 : MooseVariableFE<OutputType>::reinitAux()
132 : {
133 146841631 : _element_data->reinitAux();
134 146841631 : }
135 :
136 : template <typename OutputType>
137 : void
138 5366777 : MooseVariableFE<OutputType>::reinitAuxNeighbor()
139 : {
140 5366777 : _neighbor_data->reinitAux();
141 5366777 : }
142 :
143 : template <typename OutputType>
144 : void
145 5355 : MooseVariableFE<OutputType>::reinitNodes(const std::vector<dof_id_type> & nodes)
146 : {
147 5355 : _element_data->reinitNodes(nodes);
148 5355 : }
149 :
150 : template <typename OutputType>
151 : void
152 1257 : MooseVariableFE<OutputType>::reinitNodesNeighbor(const std::vector<dof_id_type> & nodes)
153 : {
154 1257 : _neighbor_data->reinitNodes(nodes);
155 1257 : }
156 :
157 : template <typename OutputType>
158 : void
159 18960 : MooseVariableFE<OutputType>::getDofIndices(const Elem * elem,
160 : std::vector<dof_id_type> & dof_indices) const
161 : {
162 18960 : _element_data->getDofIndices(elem, dof_indices);
163 18960 : }
164 :
165 : template <typename OutputType>
166 : typename MooseVariableFE<OutputType>::DofValue
167 1199 : MooseVariableFE<OutputType>::getNodalValue(const Node & node) const
168 : {
169 1199 : return _element_data->getNodalValue(node, Moose::Current);
170 : }
171 :
172 : template <typename OutputType>
173 : typename MooseVariableFE<OutputType>::DofValue
174 108900 : MooseVariableFE<OutputType>::getNodalValueOld(const Node & node) const
175 : {
176 108900 : return _element_data->getNodalValue(node, Moose::Old);
177 : }
178 :
179 : template <typename OutputType>
180 : typename MooseVariableFE<OutputType>::DofValue
181 0 : MooseVariableFE<OutputType>::getNodalValueOlder(const Node & node) const
182 : {
183 0 : return _element_data->getNodalValue(node, Moose::Older);
184 : }
185 :
186 : template <typename OutputType>
187 : typename MooseVariableFE<OutputType>::DofValue
188 69803 : MooseVariableFE<OutputType>::getElementalValue(const Elem * elem, unsigned int idx) const
189 : {
190 69803 : return _element_data->getElementalValue(elem, Moose::Current, idx);
191 : }
192 :
193 : template <typename OutputType>
194 : typename MooseVariableFE<OutputType>::DofValue
195 492 : MooseVariableFE<OutputType>::getElementalValueOld(const Elem * elem, unsigned int idx) const
196 : {
197 492 : return _element_data->getElementalValue(elem, Moose::Old, idx);
198 : }
199 :
200 : template <typename OutputType>
201 : typename MooseVariableFE<OutputType>::DofValue
202 492 : MooseVariableFE<OutputType>::getElementalValueOlder(const Elem * elem, unsigned int idx) const
203 : {
204 492 : return _element_data->getElementalValue(elem, Moose::Older, idx);
205 : }
206 :
207 : template <typename OutputType>
208 : void
209 49830860 : MooseVariableFE<OutputType>::insert(NumericVector<Number> & vector)
210 : {
211 49830860 : _element_data->insert(vector);
212 49830860 : }
213 :
214 : template <typename OutputType>
215 : void
216 1644 : MooseVariableFE<OutputType>::insertLower(NumericVector<Number> & vector)
217 : {
218 1644 : _lower_data->insert(vector);
219 1644 : }
220 :
221 : template <typename OutputType>
222 : void
223 1923567 : MooseVariableFE<OutputType>::add(NumericVector<Number> & vector)
224 : {
225 1923567 : _element_data->add(vector);
226 1923567 : }
227 :
228 : template <typename OutputType>
229 : void
230 1760 : MooseVariableFE<OutputType>::addSolution(const DenseVector<Number> & v)
231 : {
232 1760 : _element_data->addSolution(this->_sys.solution(), v);
233 1760 : }
234 :
235 : template <typename OutputType>
236 : void
237 960 : MooseVariableFE<OutputType>::addSolutionNeighbor(const DenseVector<Number> & v)
238 : {
239 960 : _neighbor_data->addSolution(this->_sys.solution(), v);
240 960 : }
241 :
242 : template <typename OutputType>
243 : const typename MooseVariableFE<OutputType>::DofValues &
244 0 : MooseVariableFE<OutputType>::dofValue() const
245 : {
246 0 : mooseDeprecated("Use dofValues instead of dofValue");
247 0 : return dofValues();
248 : }
249 :
250 : template <typename OutputType>
251 : const typename MooseVariableFE<OutputType>::DofValues &
252 890830 : MooseVariableFE<OutputType>::dofValues() const
253 : {
254 890830 : return _element_data->dofValues();
255 : }
256 :
257 : template <typename OutputType>
258 : const typename MooseVariableFE<OutputType>::DofValues &
259 115 : MooseVariableFE<OutputType>::dofValuesOld() const
260 : {
261 115 : return _element_data->dofValuesOld();
262 : }
263 :
264 : template <typename OutputType>
265 : const typename MooseVariableFE<OutputType>::DofValues &
266 52 : MooseVariableFE<OutputType>::dofValuesOlder() const
267 : {
268 52 : return _element_data->dofValuesOlder();
269 : }
270 :
271 : template <typename OutputType>
272 : const typename MooseVariableFE<OutputType>::DofValues &
273 0 : MooseVariableFE<OutputType>::dofValuesPreviousNL() const
274 : {
275 0 : return _element_data->dofValuesPreviousNL();
276 : }
277 :
278 : template <typename OutputType>
279 : const typename MooseVariableFE<OutputType>::DofValues &
280 114 : MooseVariableFE<OutputType>::dofValuesNeighbor() const
281 : {
282 114 : return _neighbor_data->dofValues();
283 : }
284 :
285 : template <typename OutputType>
286 : const typename MooseVariableFE<OutputType>::DofValues &
287 13 : MooseVariableFE<OutputType>::dofValuesOldNeighbor() const
288 : {
289 13 : return _neighbor_data->dofValuesOld();
290 : }
291 :
292 : template <typename OutputType>
293 : const typename MooseVariableFE<OutputType>::DofValues &
294 0 : MooseVariableFE<OutputType>::dofValuesOlderNeighbor() const
295 : {
296 0 : return _neighbor_data->dofValuesOlder();
297 : }
298 :
299 : template <typename OutputType>
300 : const typename MooseVariableFE<OutputType>::DofValues &
301 0 : MooseVariableFE<OutputType>::dofValuesPreviousNLNeighbor() const
302 : {
303 0 : return _neighbor_data->dofValuesPreviousNL();
304 : }
305 :
306 : template <typename OutputType>
307 : const typename MooseVariableFE<OutputType>::DofValues &
308 348 : MooseVariableFE<OutputType>::dofValuesDot() const
309 : {
310 348 : return _element_data->dofValuesDot();
311 : }
312 :
313 : template <typename OutputType>
314 : const typename MooseVariableFE<OutputType>::DofValues &
315 3 : MooseVariableFE<OutputType>::dofValuesDotDot() const
316 : {
317 3 : return _element_data->dofValuesDotDot();
318 : }
319 :
320 : template <typename OutputType>
321 : const typename MooseVariableFE<OutputType>::DofValues &
322 0 : MooseVariableFE<OutputType>::dofValuesDotOld() const
323 : {
324 0 : return _element_data->dofValuesDotOld();
325 : }
326 :
327 : template <typename OutputType>
328 : const typename MooseVariableFE<OutputType>::DofValues &
329 0 : MooseVariableFE<OutputType>::dofValuesDotDotOld() const
330 : {
331 0 : return _element_data->dofValuesDotDotOld();
332 : }
333 :
334 : template <typename OutputType>
335 : const typename MooseVariableFE<OutputType>::DofValues &
336 0 : MooseVariableFE<OutputType>::dofValuesDotNeighbor() const
337 : {
338 0 : return _neighbor_data->dofValuesDot();
339 : }
340 :
341 : template <typename OutputType>
342 : const typename MooseVariableFE<OutputType>::DofValues &
343 0 : MooseVariableFE<OutputType>::dofValuesDotDotNeighbor() const
344 : {
345 0 : return _neighbor_data->dofValuesDotDot();
346 : }
347 :
348 : template <typename OutputType>
349 : const typename MooseVariableFE<OutputType>::DofValues &
350 0 : MooseVariableFE<OutputType>::dofValuesDotOldNeighbor() const
351 : {
352 0 : return _neighbor_data->dofValuesDotOld();
353 : }
354 :
355 : template <typename OutputType>
356 : const typename MooseVariableFE<OutputType>::DofValues &
357 0 : MooseVariableFE<OutputType>::dofValuesDotDotOldNeighbor() const
358 : {
359 0 : return _neighbor_data->dofValuesDotDotOld();
360 : }
361 :
362 : template <typename OutputType>
363 : const MooseArray<Number> &
364 165 : MooseVariableFE<OutputType>::dofValuesDuDotDu() const
365 : {
366 165 : return _element_data->dofValuesDuDotDu();
367 : }
368 :
369 : template <typename OutputType>
370 : const MooseArray<Number> &
371 0 : MooseVariableFE<OutputType>::dofValuesDuDotDotDu() const
372 : {
373 0 : return _element_data->dofValuesDuDotDotDu();
374 : }
375 :
376 : template <typename OutputType>
377 : const MooseArray<Number> &
378 0 : MooseVariableFE<OutputType>::dofValuesDuDotDuNeighbor() const
379 : {
380 0 : return _neighbor_data->dofValuesDuDotDu();
381 : }
382 :
383 : template <typename OutputType>
384 : const MooseArray<Number> &
385 0 : MooseVariableFE<OutputType>::dofValuesDuDotDotDuNeighbor() const
386 : {
387 0 : return _neighbor_data->dofValuesDuDotDotDu();
388 : }
389 :
390 : template <typename OutputType>
391 : void
392 2207079 : MooseVariableFE<OutputType>::prepareIC()
393 : {
394 2207079 : _element_data->prepareIC();
395 2207079 : }
396 :
397 : template <typename OutputType>
398 : void
399 520547203 : MooseVariableFE<OutputType>::computeElemValues()
400 : {
401 520547203 : _element_data->setGeometry(Moose::Volume);
402 520547203 : _element_data->computeValues();
403 520547203 : }
404 :
405 : template <typename OutputType>
406 : void
407 15701447 : MooseVariableFE<OutputType>::computeElemValuesFace()
408 : {
409 15701447 : _element_data->setGeometry(Moose::Face);
410 15701447 : _element_data->computeValues();
411 15701447 : }
412 :
413 : template <typename OutputType>
414 : void
415 8106973 : MooseVariableFE<OutputType>::computeNeighborValuesFace()
416 : {
417 8106973 : _neighbor_data->setGeometry(Moose::Face);
418 8106973 : _neighbor_data->computeValues();
419 8106973 : }
420 :
421 : template <typename OutputType>
422 : void
423 29120 : MooseVariableFE<OutputType>::computeNeighborValues()
424 : {
425 29120 : _neighbor_data->setGeometry(Moose::Volume);
426 29120 : _neighbor_data->computeValues();
427 29120 : }
428 :
429 : template <typename OutputType>
430 : void
431 567998 : MooseVariableFE<OutputType>::computeLowerDValues()
432 : {
433 567998 : _lower_data->setGeometry(Moose::Volume);
434 567998 : _lower_data->computeValues();
435 567998 : }
436 :
437 : template <typename OutputType>
438 : void
439 1563 : MooseVariableFE<OutputType>::computeIncrementAtQps(const NumericVector<Number> & increment_vec)
440 : {
441 1563 : _element_data->computeIncrementAtQps(increment_vec);
442 1563 : }
443 :
444 : template <typename OutputType>
445 : void
446 7525 : MooseVariableFE<OutputType>::computeIncrementAtNode(const NumericVector<Number> & increment_vec)
447 : {
448 7525 : _element_data->computeIncrementAtNode(increment_vec);
449 7525 : }
450 :
451 : template <typename OutputType>
452 : OutputType
453 252897 : MooseVariableFE<OutputType>::getValue(const Elem * elem,
454 : const std::vector<std::vector<OutputShape>> & phi) const
455 : {
456 252897 : std::vector<dof_id_type> dof_indices;
457 252897 : this->_dof_map.dof_indices(elem, dof_indices, _var_num);
458 :
459 252897 : OutputType value = 0;
460 252897 : if (isNodal())
461 : {
462 : mooseAssert(dof_indices.size() == phi.size(),
463 : "The number of shapes does not match the number of dof indices on the elem");
464 :
465 1120539 : for (unsigned int i = 0; i < dof_indices.size(); ++i)
466 : {
467 : // The zero index is because we only have one point that the phis are evaluated at
468 867642 : value += phi[i][0] * (*this->_sys.currentSolution())(dof_indices[i]);
469 : }
470 : }
471 : else
472 : {
473 : mooseAssert(dof_indices.size() == 1, "Wrong size for dof indices");
474 0 : value = (*this->_sys.currentSolution())(dof_indices[0]);
475 : }
476 :
477 252897 : return value;
478 252897 : }
479 :
480 : template <>
481 : RealEigenVector
482 0 : MooseVariableFE<RealEigenVector>::getValue(const Elem * elem,
483 : const std::vector<std::vector<Real>> & phi) const
484 : {
485 0 : std::vector<dof_id_type> dof_indices;
486 0 : this->_dof_map.dof_indices(elem, dof_indices, _var_num);
487 :
488 0 : RealEigenVector value(_count);
489 0 : if (isNodal())
490 : {
491 0 : for (unsigned int i = 0; i < dof_indices.size(); ++i)
492 0 : for (unsigned int j = 0; j < _count; j++)
493 : {
494 : // The zero index is because we only have one point that the phis are evaluated at
495 0 : value(j) += phi[i][0] * (*this->_sys.currentSolution())(dof_indices[i] + j);
496 : }
497 : }
498 : else
499 : {
500 : mooseAssert(dof_indices.size() == 1, "Wrong size for dof indices");
501 0 : unsigned int n = 0;
502 0 : for (unsigned int j = 0; j < _count; j++)
503 : {
504 0 : value(j) = (*this->_sys.currentSolution())(dof_indices[0] + n);
505 0 : n += this->_dof_indices.size();
506 : }
507 : }
508 :
509 0 : return value;
510 0 : }
511 :
512 : template <typename OutputType>
513 : typename OutputTools<OutputType>::OutputGradient
514 0 : MooseVariableFE<OutputType>::getGradient(
515 : const Elem * elem,
516 : const std::vector<std::vector<typename OutputTools<OutputType>::OutputShapeGradient>> &
517 : grad_phi) const
518 : {
519 0 : std::vector<dof_id_type> dof_indices;
520 0 : this->_dof_map.dof_indices(elem, dof_indices, _var_num);
521 :
522 0 : typename OutputTools<OutputType>::OutputGradient value;
523 0 : if (isNodal())
524 : {
525 0 : for (unsigned int i = 0; i < dof_indices.size(); ++i)
526 : {
527 : // The zero index is because we only have one point that the phis are evaluated at
528 0 : value += grad_phi[i][0] * (*this->_sys.currentSolution())(dof_indices[i]);
529 : }
530 : }
531 : else
532 : {
533 : mooseAssert(dof_indices.size() == 1, "Wrong size for dof indices");
534 0 : value = 0.0;
535 : }
536 :
537 0 : return value;
538 0 : }
539 :
540 : template <>
541 : RealVectorArrayValue
542 0 : MooseVariableFE<RealEigenVector>::getGradient(
543 : const Elem * elem, const std::vector<std::vector<RealVectorValue>> & grad_phi) const
544 : {
545 0 : std::vector<dof_id_type> dof_indices;
546 0 : this->_dof_map.dof_indices(elem, dof_indices, _var_num);
547 :
548 0 : RealVectorArrayValue value(_count, LIBMESH_DIM);
549 0 : if (isNodal())
550 : {
551 0 : for (unsigned int i = 0; i < dof_indices.size(); ++i)
552 0 : for (unsigned int j = 0; j < _count; ++j)
553 0 : for (const auto k : make_range(Moose::dim))
554 : {
555 : // The zero index is because we only have one point that the phis are evaluated at
556 0 : value(j, k) += grad_phi[i][0](k) * (*this->_sys.currentSolution())(dof_indices[i] + j);
557 : }
558 : }
559 : else
560 : {
561 : mooseAssert(dof_indices.size() == 1, "Wrong size for dof indices");
562 : }
563 :
564 0 : return value;
565 0 : }
566 :
567 : template <typename OutputType>
568 : const OutputType &
569 1239 : MooseVariableFE<OutputType>::nodalValue() const
570 : {
571 1239 : return _element_data->nodalValue(Moose::Current);
572 : }
573 :
574 : template <typename OutputType>
575 : const OutputType &
576 0 : MooseVariableFE<OutputType>::nodalValueNeighbor() const
577 : {
578 0 : return _neighbor_data->nodalValue(Moose::Current);
579 : }
580 :
581 : template <typename OutputType>
582 : const typename MooseVariableFE<OutputType>::DofValues &
583 433 : MooseVariableFE<OutputType>::nodalVectorTagValue(TagID tag) const
584 : {
585 433 : return _element_data->nodalVectorTagValue(tag);
586 : }
587 :
588 : template <typename OutputType>
589 : const typename MooseVariableFE<OutputType>::DofValues &
590 225 : MooseVariableFE<OutputType>::nodalMatrixTagValue(TagID tag) const
591 : {
592 225 : return _element_data->nodalMatrixTagValue(tag);
593 : }
594 :
595 : template <typename OutputType>
596 : const OutputType &
597 0 : MooseVariableFE<OutputType>::nodalValueOld() const
598 : {
599 0 : return _element_data->nodalValue(Moose::Old);
600 : }
601 :
602 : template <typename OutputType>
603 : const OutputType &
604 0 : MooseVariableFE<OutputType>::nodalValueOldNeighbor() const
605 : {
606 0 : return _neighbor_data->nodalValue(Moose::Old);
607 : }
608 :
609 : template <typename OutputType>
610 : const OutputType &
611 0 : MooseVariableFE<OutputType>::nodalValueOlder() const
612 : {
613 0 : return _element_data->nodalValue(Moose::Older);
614 : }
615 :
616 : template <typename OutputType>
617 : const OutputType &
618 0 : MooseVariableFE<OutputType>::nodalValueOlderNeighbor() const
619 : {
620 0 : return _neighbor_data->nodalValue(Moose::Older);
621 : }
622 :
623 : template <typename OutputType>
624 : const OutputType &
625 0 : MooseVariableFE<OutputType>::nodalValuePreviousNL() const
626 : {
627 0 : return _element_data->nodalValue(Moose::PreviousNL);
628 : }
629 :
630 : template <typename OutputType>
631 : const OutputType &
632 0 : MooseVariableFE<OutputType>::nodalValuePreviousNLNeighbor() const
633 : {
634 0 : return _neighbor_data->nodalValue(Moose::PreviousNL);
635 : }
636 :
637 : template <typename OutputType>
638 : const OutputType &
639 0 : MooseVariableFE<OutputType>::nodalValueDot() const
640 : {
641 0 : return _element_data->nodalValueDot();
642 : }
643 :
644 : template <typename OutputType>
645 : const OutputType &
646 0 : MooseVariableFE<OutputType>::nodalValueDotDot() const
647 : {
648 0 : return _element_data->nodalValueDotDot();
649 : }
650 :
651 : template <typename OutputType>
652 : const OutputType &
653 0 : MooseVariableFE<OutputType>::nodalValueDotOld() const
654 : {
655 0 : return _element_data->nodalValueDotOld();
656 : }
657 :
658 : template <typename OutputType>
659 : const OutputType &
660 0 : MooseVariableFE<OutputType>::nodalValueDotDotOld() const
661 : {
662 0 : return _element_data->nodalValueDotDotOld();
663 : }
664 :
665 : template <typename OutputType>
666 : void
667 246347577 : MooseVariableFE<OutputType>::computeNodalValues()
668 : {
669 246347577 : _element_data->computeNodalValues();
670 246347577 : }
671 :
672 : template <typename OutputType>
673 : void
674 1257 : MooseVariableFE<OutputType>::computeNodalNeighborValues()
675 : {
676 1257 : _neighbor_data->computeNodalValues();
677 1257 : }
678 :
679 : template <typename OutputType>
680 : void
681 45819322 : MooseVariableFE<OutputType>::setNodalValue(const OutputType & value, unsigned int idx)
682 : {
683 45819322 : _element_data->setNodalValue(value, idx);
684 45819322 : }
685 :
686 : template <typename OutputType>
687 : void
688 8421231 : MooseVariableFE<OutputType>::setDofValue(const DofValue & value, unsigned int index)
689 : {
690 8421231 : _element_data->setDofValue(value, index);
691 8421231 : }
692 :
693 : template <typename OutputType>
694 : void
695 581243 : MooseVariableFE<OutputType>::setDofValues(const DenseVector<DofValue> & values)
696 : {
697 581243 : _element_data->setDofValues(values);
698 581243 : }
699 :
700 : template <typename OutputType>
701 : void
702 1644 : MooseVariableFE<OutputType>::setLowerDofValues(const DenseVector<DofValue> & values)
703 : {
704 1644 : _lower_data->setDofValues(values);
705 1644 : }
706 :
707 : template <typename OutputType>
708 : void
709 55691662 : MooseVariableFE<OutputType>::insertNodalValue(NumericVector<Number> & residual, const DofValue & v)
710 : {
711 55691662 : _element_data->insertNodalValue(residual, v);
712 55691662 : }
713 :
714 : template <typename OutputType>
715 : const typename MooseVariableFE<OutputType>::FieldVariablePhiSecond &
716 24335 : MooseVariableFE<OutputType>::secondPhi() const
717 : {
718 24335 : return _element_data->secondPhi();
719 : }
720 :
721 : template <typename OutputType>
722 : const typename MooseVariableFE<OutputType>::FieldVariablePhiCurl &
723 57030 : MooseVariableFE<OutputType>::curlPhi() const
724 : {
725 57030 : return _element_data->curlPhi();
726 : }
727 :
728 : template <typename OutputType>
729 : const typename MooseVariableFE<OutputType>::FieldVariablePhiDivergence &
730 520870 : MooseVariableFE<OutputType>::divPhi() const
731 : {
732 520870 : return _element_data->divPhi();
733 : }
734 :
735 : template <typename OutputType>
736 : const typename MooseVariableFE<OutputType>::FieldVariablePhiSecond &
737 4261 : MooseVariableFE<OutputType>::secondPhiFace() const
738 : {
739 4261 : return _element_data->secondPhiFace();
740 : }
741 :
742 : template <typename OutputType>
743 : const typename MooseVariableFE<OutputType>::FieldVariablePhiCurl &
744 0 : MooseVariableFE<OutputType>::curlPhiFace() const
745 : {
746 0 : return _element_data->curlPhiFace();
747 : }
748 :
749 : template <typename OutputType>
750 : const typename MooseVariableFE<OutputType>::FieldVariablePhiDivergence &
751 0 : MooseVariableFE<OutputType>::divPhiFace() const
752 : {
753 0 : return _element_data->divPhiFace();
754 : }
755 :
756 : template <typename OutputType>
757 : const typename MooseVariableFE<OutputType>::FieldVariablePhiSecond &
758 0 : MooseVariableFE<OutputType>::secondPhiNeighbor() const
759 : {
760 0 : return _neighbor_data->secondPhi();
761 : }
762 :
763 : template <typename OutputType>
764 : const typename MooseVariableFE<OutputType>::FieldVariablePhiCurl &
765 0 : MooseVariableFE<OutputType>::curlPhiNeighbor() const
766 : {
767 0 : return _neighbor_data->curlPhi();
768 : }
769 :
770 : template <typename OutputType>
771 : const typename MooseVariableFE<OutputType>::FieldVariablePhiDivergence &
772 0 : MooseVariableFE<OutputType>::divPhiNeighbor() const
773 : {
774 0 : return _neighbor_data->divPhi();
775 : }
776 :
777 : template <typename OutputType>
778 : const typename MooseVariableFE<OutputType>::FieldVariablePhiSecond &
779 0 : MooseVariableFE<OutputType>::secondPhiFaceNeighbor() const
780 : {
781 0 : return _neighbor_data->secondPhiFace();
782 : }
783 :
784 : template <typename OutputType>
785 : const typename MooseVariableFE<OutputType>::FieldVariablePhiCurl &
786 0 : MooseVariableFE<OutputType>::curlPhiFaceNeighbor() const
787 : {
788 0 : return _neighbor_data->curlPhiFace();
789 : }
790 :
791 : template <typename OutputType>
792 : const typename MooseVariableFE<OutputType>::FieldVariablePhiDivergence &
793 0 : MooseVariableFE<OutputType>::divPhiFaceNeighbor() const
794 : {
795 0 : return _neighbor_data->divPhiFace();
796 : }
797 :
798 : template <typename OutputType>
799 : bool
800 126918663 : MooseVariableFE<OutputType>::usesSecondPhi() const
801 : {
802 126918663 : return _element_data->usesSecondPhi();
803 : }
804 :
805 : template <typename OutputType>
806 : bool
807 188641 : MooseVariableFE<OutputType>::usesSecondPhiNeighbor() const
808 : {
809 188641 : return _neighbor_data->usesSecondPhi();
810 : }
811 :
812 : template <typename OutputType>
813 : bool
814 1873054 : MooseVariableFE<OutputType>::computingCurl() const
815 : {
816 1873054 : return _element_data->computingCurl();
817 : }
818 :
819 : template <typename OutputType>
820 : bool
821 1873054 : MooseVariableFE<OutputType>::computingDiv() const
822 : {
823 1873054 : return _element_data->computingDiv();
824 : }
825 :
826 : template <typename OutputType>
827 : bool
828 418254962 : MooseVariableFE<OutputType>::isNodalDefined() const
829 : {
830 418254962 : return _element_data->isNodalDefined();
831 : }
832 :
833 : template <typename OutputType>
834 : bool
835 0 : MooseVariableFE<OutputType>::isNodalNeighborDefined() const
836 : {
837 0 : return _neighbor_data->isNodalDefined();
838 : }
839 :
840 : template <typename OutputType>
841 : unsigned int
842 153919 : MooseVariableFE<OutputType>::oldestSolutionStateRequested() const
843 : {
844 153919 : unsigned int state = 0;
845 153919 : state = std::max(state, _element_data->oldestSolutionStateRequested());
846 153919 : state = std::max(state, _neighbor_data->oldestSolutionStateRequested());
847 153919 : state = std::max(state, _lower_data->oldestSolutionStateRequested());
848 153919 : return state;
849 : }
850 :
851 : template <typename OutputType>
852 : void
853 1234433 : MooseVariableFE<OutputType>::clearAllDofIndices()
854 : {
855 1234433 : _element_data->clearDofIndices();
856 1234433 : _neighbor_data->clearDofIndices();
857 1234433 : _lower_data->clearDofIndices();
858 1234433 : }
859 :
860 : template <typename OutputType>
861 : typename MooseVariableFE<OutputType>::ValueType
862 80384 : MooseVariableFE<OutputType>::evaluate(const NodeArg & node_arg, const StateArg & state) const
863 : {
864 : mooseAssert(node_arg.node, "Must have a node");
865 80384 : const Node & node = *node_arg.node;
866 : mooseAssert(node.n_dofs(this->_sys.number(), this->number()),
867 : "Our variable must have dofs on the requested node");
868 80384 : const auto & soln = this->getSolution(state);
869 : if constexpr (std::is_same<OutputType, Real>::value)
870 : {
871 80384 : const auto dof_number = node.dof_number(this->_sys.number(), this->number(), 0);
872 80384 : ValueType ret = soln(dof_number);
873 80384 : if (Moose::doDerivatives(_subproblem, _sys))
874 19104 : Moose::derivInsert(ret.derivatives(), dof_number, 1);
875 160768 : return ret;
876 80384 : }
877 : else if constexpr (std::is_same<OutputType, RealVectorValue>::value)
878 : {
879 0 : ValueType ret;
880 0 : const auto do_derivatives = Moose::doDerivatives(_subproblem, _sys);
881 0 : for (const auto d : make_range(this->_mesh.dimension()))
882 : {
883 0 : const auto dof_number = node.dof_number(this->_sys.number(), this->number(), d);
884 0 : auto & component = ret(d);
885 0 : component = soln(dof_number);
886 0 : if (do_derivatives)
887 0 : Moose::derivInsert(component.derivatives(), dof_number, 1);
888 : }
889 0 : return ret;
890 0 : }
891 : else
892 0 : mooseError("RealEigenVector not yet supported for functors");
893 : }
894 :
895 : namespace
896 : {
897 : template <typename OutputType>
898 : struct FEBaseHelper
899 : {
900 : typedef FEBase type;
901 : };
902 :
903 : template <>
904 : struct FEBaseHelper<RealVectorValue>
905 : {
906 : typedef FEVectorBase type;
907 : };
908 : }
909 :
910 : template <typename OutputType>
911 : template <typename Shapes, typename Solution, typename GradShapes, typename GradSolution>
912 : void
913 864590 : MooseVariableFE<OutputType>::computeSolution(const Elem * const elem,
914 : const unsigned int n_qp,
915 : const StateArg & state,
916 : const Shapes & phi,
917 : Solution & local_soln,
918 : const GradShapes & grad_phi,
919 : GradSolution & grad_local_soln,
920 : Solution & dot_local_soln,
921 : GradSolution & grad_dot_local_soln) const
922 : {
923 864590 : std::vector<dof_id_type> dof_indices;
924 864590 : this->_dof_map.dof_indices(elem, dof_indices, _var_num);
925 864590 : std::vector<ADReal> dof_values;
926 864590 : std::vector<ADReal> dof_values_dot;
927 864590 : dof_values.reserve(dof_indices.size());
928 :
929 864590 : const bool computing_dot = _time_integrator && _time_integrator->dt();
930 864590 : if (computing_dot)
931 321170 : dof_values_dot.reserve(dof_indices.size());
932 :
933 864590 : const bool do_derivatives = Moose::doDerivatives(_subproblem, _sys);
934 864590 : const auto & global_soln = getSolution(state);
935 3869072 : for (const auto dof_index : dof_indices)
936 : {
937 3004482 : dof_values.push_back(ADReal(global_soln(dof_index)));
938 3004482 : if (do_derivatives && state.state == 0)
939 356376 : Moose::derivInsert(dof_values.back().derivatives(), dof_index, 1.);
940 3004482 : if (computing_dot)
941 : {
942 1652174 : if (_var_kind == Moose::VAR_SOLVER)
943 : {
944 1637940 : dof_values_dot.push_back(dof_values.back());
945 1637940 : _time_integrator->computeADTimeDerivatives(
946 1637940 : dof_values_dot.back(), dof_index, _ad_real_dummy);
947 : }
948 : else
949 14234 : dof_values_dot.push_back((*this->_sys.solutionUDot())(dof_index));
950 : }
951 : }
952 :
953 864590 : local_soln.resize(n_qp);
954 864590 : grad_local_soln.resize(n_qp);
955 864590 : if (computing_dot)
956 : {
957 321170 : dot_local_soln.resize(n_qp);
958 321170 : grad_dot_local_soln.resize(n_qp);
959 : }
960 :
961 3720158 : for (const auto qp : make_range(n_qp))
962 : {
963 2855568 : local_soln[qp] = 0;
964 2855568 : grad_local_soln[qp] = 0;
965 2855568 : if (computing_dot)
966 : {
967 1629086 : dot_local_soln[qp] = 0;
968 1629086 : grad_dot_local_soln[qp] = GradientType{};
969 : }
970 15756838 : for (const auto i : index_range(dof_indices))
971 : {
972 12901270 : local_soln[qp] += dof_values[i] * phi[i][qp];
973 12901270 : grad_local_soln[qp] += dof_values[i] * grad_phi[i][qp];
974 12901270 : if (computing_dot)
975 : {
976 9579322 : dot_local_soln[qp] += dof_values_dot[i] * phi[i][qp];
977 9579322 : grad_dot_local_soln[qp] += dof_values_dot[i] * grad_phi[i][qp];
978 : }
979 : }
980 : }
981 864590 : }
982 :
983 : template <typename OutputType>
984 : void
985 14297900 : MooseVariableFE<OutputType>::evaluateOnElement(const ElemQpArg & elem_qp,
986 : const StateArg & state,
987 : const bool cache_eligible) const
988 : {
989 : mooseAssert(this->hasBlocks(elem_qp.elem->subdomain_id()),
990 : "Variable " + this->name() + " doesn't exist on block " +
991 : std::to_string(elem_qp.elem->subdomain_id()));
992 :
993 14297900 : const Elem * const elem = elem_qp.elem;
994 14297900 : if (!cache_eligible || (elem != _current_elem_qp_functor_elem))
995 : {
996 847992 : const QBase * const qrule_template = elem_qp.qrule;
997 :
998 : using FEBaseType = typename FEBaseHelper<OutputType>::type;
999 847992 : std::unique_ptr<FEBaseType> fe(FEBaseType::build(elem->dim(), _fe_type));
1000 847992 : auto qrule = qrule_template->clone();
1001 :
1002 847992 : const auto & phi = fe->get_phi();
1003 847992 : const auto & dphi = fe->get_dphi();
1004 847992 : fe->attach_quadrature_rule(qrule.get());
1005 847992 : fe->reinit(elem);
1006 :
1007 847992 : computeSolution(elem,
1008 : qrule->n_points(),
1009 : state,
1010 : phi,
1011 847992 : _current_elem_qp_functor_sln,
1012 : dphi,
1013 847992 : _current_elem_qp_functor_gradient,
1014 847992 : _current_elem_qp_functor_dot,
1015 847992 : _current_elem_qp_functor_grad_dot);
1016 847992 : }
1017 14297900 : if (cache_eligible)
1018 14269036 : _current_elem_qp_functor_elem = elem;
1019 : else
1020 : // These evaluations are not eligible for caching, e.g. maybe this is a single point quadrature
1021 : // rule evaluation at an arbitrary point and we don't want those evaluations to potentially be
1022 : // re-used when this function is called with a standard quadrature rule or a different point
1023 28864 : _current_elem_qp_functor_elem = nullptr;
1024 14297900 : }
1025 :
1026 : template <>
1027 : void
1028 0 : MooseVariableFE<RealEigenVector>::evaluateOnElement(const ElemQpArg &, const StateArg &, bool) const
1029 : {
1030 0 : mooseError("evaluate not implemented for array variables");
1031 : }
1032 :
1033 : template <typename OutputType>
1034 : typename MooseVariableFE<OutputType>::ValueType
1035 2023396 : MooseVariableFE<OutputType>::evaluate(const ElemQpArg & elem_qp, const StateArg & state) const
1036 : {
1037 2023396 : evaluateOnElement(elem_qp, state, /*query_cache=*/true);
1038 2023396 : const auto qp = elem_qp.qp;
1039 : mooseAssert(qp < _current_elem_qp_functor_sln.size(),
1040 : "The requested " << qp << " is outside our solution size");
1041 2023396 : return _current_elem_qp_functor_sln[qp];
1042 : }
1043 :
1044 : template <typename OutputType>
1045 : typename MooseVariableFE<OutputType>::ValueType
1046 21548 : MooseVariableFE<OutputType>::evaluate(const ElemArg & elem_arg, const StateArg & state) const
1047 : {
1048 21548 : const QMonomial qrule(elem_arg.elem->dim(), CONSTANT);
1049 : // We can use whatever we want for the point argument since it won't be used
1050 21548 : const ElemQpArg elem_qp_arg{elem_arg.elem, /*qp=*/0, &qrule, Point(0, 0, 0)};
1051 21548 : evaluateOnElement(elem_qp_arg, state, /*cache_eligible=*/false);
1052 43096 : return _current_elem_qp_functor_sln[0];
1053 21548 : }
1054 :
1055 : template <typename OutputType>
1056 : typename MooseVariableFE<OutputType>::ValueType
1057 2664 : MooseVariableFE<OutputType>::faceEvaluate(const FaceArg & face_arg,
1058 : const StateArg & state,
1059 : const std::vector<ValueType> & cache_data) const
1060 : {
1061 2664 : const QMonomial qrule(face_arg.fi->elem().dim() - 1, CONSTANT);
1062 2664 : auto side_evaluate =
1063 2664 : [this, &qrule, &state, &cache_data](const Elem * const elem, const unsigned int side)
1064 : {
1065 : // We can use whatever we want for the point argument since it won't be used
1066 2664 : const ElemSideQpArg elem_side_qp_arg{elem, side, /*qp=*/0, &qrule, Point(0, 0, 0)};
1067 2664 : evaluateOnElementSide(elem_side_qp_arg, state, /*cache_eligible=*/false);
1068 5328 : return cache_data[0];
1069 : };
1070 :
1071 2664 : const auto continuity = this->getContinuity();
1072 : bool on_elem;
1073 : bool on_neighbor;
1074 2664 : if (!face_arg.face_side)
1075 : {
1076 2364 : on_elem = this->hasBlocks(face_arg.fi->elemPtr()->subdomain_id());
1077 2364 : on_neighbor =
1078 2364 : face_arg.fi->neighborPtr() && this->hasBlocks(face_arg.fi->neighborPtr()->subdomain_id());
1079 : }
1080 : else
1081 : {
1082 300 : on_elem = face_arg.face_side == face_arg.fi->elemPtr();
1083 300 : on_neighbor = face_arg.face_side == face_arg.fi->neighborPtr();
1084 : }
1085 :
1086 : // Only do multiple evaluations if we are not continuous and we are on an internal face
1087 2664 : if ((continuity != C_ZERO && continuity != C_ONE) && on_elem && on_neighbor)
1088 0 : return (side_evaluate(face_arg.fi->elemPtr(), face_arg.fi->elemSideID()) +
1089 0 : side_evaluate(face_arg.fi->neighborPtr(), face_arg.fi->neighborSideID())) /
1090 0 : 2;
1091 2664 : else if (on_elem)
1092 2664 : return side_evaluate(face_arg.fi->elemPtr(), face_arg.fi->elemSideID());
1093 0 : else if (on_neighbor)
1094 0 : return side_evaluate(face_arg.fi->neighborPtr(), face_arg.fi->neighborSideID());
1095 : else
1096 0 : mooseError(
1097 : "Attempted to evaluate a moose finite element variable on a face where it is not defined");
1098 2664 : }
1099 :
1100 : template <typename OutputType>
1101 : typename MooseVariableFE<OutputType>::ValueType
1102 2664 : MooseVariableFE<OutputType>::evaluate(const FaceArg & face_arg, const StateArg & state) const
1103 : {
1104 2664 : return faceEvaluate(face_arg, state, _current_elem_side_qp_functor_sln);
1105 : }
1106 :
1107 : template <typename OutputType>
1108 : typename MooseVariableFE<OutputType>::ValueType
1109 3532 : MooseVariableFE<OutputType>::evaluate(const ElemPointArg & elem_point_arg,
1110 : const StateArg & state) const
1111 : {
1112 : mooseAssert(elem_point_arg.elem, "We need an Elem");
1113 3532 : const Elem & elem = *elem_point_arg.elem;
1114 3532 : const auto dim = elem.dim();
1115 3532 : ArbitraryQuadrature qrule(dim);
1116 7064 : const std::vector<Point> ref_point = {FEMap::inverse_map(dim, &elem, elem_point_arg.point)};
1117 3532 : qrule.setPoints(ref_point);
1118 : // We can use whatever we want for the point argument since it won't be used
1119 3532 : const ElemQpArg elem_qp_arg{elem_point_arg.elem, /*qp=*/0, &qrule, elem_point_arg.point};
1120 3532 : evaluateOnElement(elem_qp_arg, state, /*cache_eligible=*/false);
1121 7064 : return _current_elem_qp_functor_sln[0];
1122 3532 : }
1123 :
1124 : template <typename OutputType>
1125 : typename MooseVariableFE<OutputType>::GradientType
1126 11408032 : MooseVariableFE<OutputType>::evaluateGradient(const ElemQpArg & elem_qp,
1127 : const StateArg & state) const
1128 : {
1129 11408032 : evaluateOnElement(elem_qp, state, /*query_cache=*/true);
1130 11408032 : const auto qp = elem_qp.qp;
1131 : mooseAssert(qp < _current_elem_qp_functor_gradient.size(),
1132 : "The requested " << qp << " is outside our gradient size");
1133 11408032 : return _current_elem_qp_functor_gradient[qp];
1134 : }
1135 :
1136 : template <typename OutputType>
1137 : typename MooseVariableFE<OutputType>::GradientType
1138 1080 : MooseVariableFE<OutputType>::evaluateGradient(const ElemArg & elem_arg,
1139 : const StateArg & state) const
1140 : {
1141 1080 : const QMonomial qrule(elem_arg.elem->dim(), CONSTANT);
1142 : // We can use whatever we want for the point argument since it won't be used
1143 1080 : const ElemQpArg elem_qp_arg{elem_arg.elem, /*qp=*/0, &qrule, Point(0, 0, 0)};
1144 1080 : evaluateOnElement(elem_qp_arg, state, /*cache_eligible=*/false);
1145 2160 : return _current_elem_qp_functor_gradient[0];
1146 1080 : }
1147 :
1148 : template <typename OutputType>
1149 : typename MooseVariableFE<OutputType>::DotType
1150 837608 : MooseVariableFE<OutputType>::evaluateDot(const ElemQpArg & elem_qp, const StateArg & state) const
1151 : {
1152 : mooseAssert(_time_integrator,
1153 : "A time derivative is being requested but we do not have a time integrator so we'll "
1154 : "have no idea how to compute it");
1155 : mooseAssert(_time_integrator->dt(),
1156 : "A time derivative is being requested but the time integrator wants to perform a 0s "
1157 : "time step");
1158 837608 : evaluateOnElement(elem_qp, state, /*query_cache=*/true);
1159 837608 : const auto qp = elem_qp.qp;
1160 : mooseAssert(qp < _current_elem_qp_functor_dot.size(),
1161 : "The requested " << qp << " is outside our dot size");
1162 837608 : return _current_elem_qp_functor_dot[qp];
1163 : }
1164 :
1165 : template <typename OutputType>
1166 : typename MooseVariableFE<OutputType>::DotType
1167 1624 : MooseVariableFE<OutputType>::evaluateDot(const ElemArg & elem_arg, const StateArg & state) const
1168 : {
1169 : mooseAssert(_time_integrator,
1170 : "A time derivative is being requested but we do not have a time integrator so we'll "
1171 : "have no idea how to compute it");
1172 : mooseAssert(_time_integrator->dt(),
1173 : "A time derivative is being requested but the time integrator wants to perform a 0s "
1174 : "time step");
1175 1624 : const QMonomial qrule(elem_arg.elem->dim(), CONSTANT);
1176 : // We can use whatever we want for the point argument since it won't be used
1177 1624 : const ElemQpArg elem_qp_arg{elem_arg.elem, /*qp=*/0, &qrule, Point(0, 0, 0)};
1178 1624 : evaluateOnElement(elem_qp_arg, state, /*cache_eligible=*/false);
1179 3248 : return _current_elem_qp_functor_dot[0];
1180 1624 : }
1181 :
1182 : template <typename OutputType>
1183 : typename MooseVariableFE<OutputType>::GradientType
1184 1080 : MooseVariableFE<OutputType>::evaluateGradDot(const ElemArg & elem_arg, const StateArg & state) const
1185 : {
1186 : mooseAssert(_time_integrator,
1187 : "A time derivative is being requested but we do not have a time integrator so we'll "
1188 : "have no idea how to compute it");
1189 : mooseAssert(_time_integrator->dt(),
1190 : "A time derivative is being requested but the time integrator wants to perform a 0s "
1191 : "time step");
1192 1080 : const QMonomial qrule(elem_arg.elem->dim(), CONSTANT);
1193 : // We can use whatever we want for the point argument since it won't be used
1194 1080 : const ElemQpArg elem_qp_arg{elem_arg.elem, /*qp=*/0, &qrule, Point(0, 0, 0)};
1195 1080 : evaluateOnElement(elem_qp_arg, state, /*cache_eligible=*/false);
1196 2160 : return _current_elem_qp_functor_grad_dot[0];
1197 1080 : }
1198 :
1199 : template <typename OutputType>
1200 : void
1201 100340 : MooseVariableFE<OutputType>::evaluateOnElementSide(const ElemSideQpArg & elem_side_qp,
1202 : const StateArg & state,
1203 : const bool cache_eligible) const
1204 : {
1205 : mooseAssert(this->hasBlocks(elem_side_qp.elem->subdomain_id()),
1206 : "Variable " + this->name() + " doesn't exist on block " +
1207 : std::to_string(elem_side_qp.elem->subdomain_id()));
1208 :
1209 100340 : const Elem * const elem = elem_side_qp.elem;
1210 100340 : const auto side = elem_side_qp.side;
1211 100340 : if (!cache_eligible || elem != _current_elem_side_qp_functor_elem_side.first ||
1212 84078 : side != _current_elem_side_qp_functor_elem_side.second)
1213 : {
1214 16598 : const QBase * const qrule_template = elem_side_qp.qrule;
1215 :
1216 : using FEBaseType = typename FEBaseHelper<OutputType>::type;
1217 16598 : std::unique_ptr<FEBaseType> fe(FEBaseType::build(elem->dim(), _fe_type));
1218 16598 : auto qrule = qrule_template->clone();
1219 :
1220 16598 : const auto & phi = fe->get_phi();
1221 16598 : const auto & dphi = fe->get_dphi();
1222 16598 : fe->attach_quadrature_rule(qrule.get());
1223 16598 : fe->reinit(elem, side);
1224 :
1225 16598 : computeSolution(elem,
1226 : qrule->n_points(),
1227 : state,
1228 : phi,
1229 16598 : _current_elem_side_qp_functor_sln,
1230 : dphi,
1231 16598 : _current_elem_side_qp_functor_gradient,
1232 16598 : _current_elem_side_qp_functor_dot,
1233 16598 : _current_elem_side_qp_functor_grad_dot);
1234 16598 : }
1235 100340 : if (cache_eligible)
1236 97676 : _current_elem_side_qp_functor_elem_side = std::make_pair(elem, side);
1237 : else
1238 : // These evaluations are not eligible for caching, e.g. maybe this is a single point quadrature
1239 : // rule evaluation at an arbitrary point and we don't want those evaluations to potentially be
1240 : // re-used when this function is called with a standard quadrature rule or a different point
1241 2664 : _current_elem_side_qp_functor_elem_side = std::make_pair(nullptr, libMesh::invalid_uint);
1242 100340 : }
1243 :
1244 : template <>
1245 : void
1246 0 : MooseVariableFE<RealEigenVector>::evaluateOnElementSide(const ElemSideQpArg &,
1247 : const StateArg &,
1248 : bool) const
1249 : {
1250 0 : mooseError("evaluate not implemented for array variables");
1251 : }
1252 :
1253 : template <typename OutputType>
1254 : typename MooseVariableFE<OutputType>::ValueType
1255 97676 : MooseVariableFE<OutputType>::evaluate(const ElemSideQpArg & elem_side_qp,
1256 : const StateArg & state) const
1257 : {
1258 97676 : evaluateOnElementSide(elem_side_qp, state, true);
1259 97676 : const auto qp = elem_side_qp.qp;
1260 : mooseAssert(qp < _current_elem_side_qp_functor_sln.size(),
1261 : "The requested " << qp << " is outside our solution size");
1262 97676 : return _current_elem_side_qp_functor_sln[qp];
1263 : }
1264 :
1265 : template <typename OutputType>
1266 : typename MooseVariableFE<OutputType>::GradientType
1267 0 : MooseVariableFE<OutputType>::evaluateGradient(const ElemSideQpArg & elem_side_qp,
1268 : const StateArg & state) const
1269 : {
1270 0 : evaluateOnElementSide(elem_side_qp, state, true);
1271 0 : const auto qp = elem_side_qp.qp;
1272 : mooseAssert(qp < _current_elem_side_qp_functor_gradient.size(),
1273 : "The requested " << qp << " is outside our gradient size");
1274 0 : return _current_elem_side_qp_functor_gradient[qp];
1275 : }
1276 :
1277 : template <typename OutputType>
1278 : typename MooseVariableFE<OutputType>::DotType
1279 0 : MooseVariableFE<OutputType>::evaluateDot(const ElemSideQpArg & elem_side_qp,
1280 : const StateArg & state) const
1281 : {
1282 : mooseAssert(_time_integrator && _time_integrator->dt(),
1283 : "A time derivative is being requested but we do not have a time integrator so we'll "
1284 : "have no idea how to compute it");
1285 0 : evaluateOnElementSide(elem_side_qp, state, true);
1286 0 : const auto qp = elem_side_qp.qp;
1287 : mooseAssert(qp < _current_elem_side_qp_functor_dot.size(),
1288 : "The requested " << qp << " is outside our dot size");
1289 0 : return _current_elem_side_qp_functor_dot[qp];
1290 : }
1291 :
1292 : template <typename OutputType>
1293 : typename MooseVariableFE<OutputType>::DotType
1294 0 : MooseVariableFE<OutputType>::evaluateDot(const FaceArg & face_arg, const StateArg & state) const
1295 : {
1296 : mooseAssert(_time_integrator && _time_integrator->dt(),
1297 : "A time derivative is being requested but we do not have a time integrator so we'll "
1298 : "have no idea how to compute it");
1299 0 : return faceEvaluate(face_arg, state, _current_elem_side_qp_functor_dot);
1300 : }
1301 :
1302 : template <>
1303 : typename MooseVariableFE<RealEigenVector>::ValueType
1304 0 : MooseVariableFE<RealEigenVector>::evaluate(const ElemQpArg &, const StateArg &) const
1305 : {
1306 0 : mooseError(
1307 : "MooseVariableFE::evaluate(ElemQpArg &, const StateArg &) overload not implemented for "
1308 : "array variables");
1309 : }
1310 :
1311 : template <>
1312 : typename MooseVariableFE<RealEigenVector>::ValueType
1313 0 : MooseVariableFE<RealEigenVector>::evaluate(const ElemSideQpArg &, const StateArg &) const
1314 : {
1315 0 : mooseError("MooseVariableFE::evaluate(ElemSideQpArg &, const StateArg &) overload not "
1316 : "implemented for array variables");
1317 : }
1318 :
1319 : template <>
1320 : typename MooseVariableFE<RealEigenVector>::GradientType
1321 0 : MooseVariableFE<RealEigenVector>::evaluateGradient(const ElemQpArg &, const StateArg &) const
1322 : {
1323 0 : mooseError("MooseVariableFE::evaluateGradient(ElemQpArg &, const StateArg &) overload not "
1324 : "implemented for array variables");
1325 : }
1326 :
1327 : template <>
1328 : typename MooseVariableFE<RealEigenVector>::GradientType
1329 0 : MooseVariableFE<RealEigenVector>::evaluateGradient(const ElemSideQpArg &, const StateArg &) const
1330 : {
1331 0 : mooseError("MooseVariableFE::evaluateGradient(ElemSideQpArg &, const StateArg &) overload not "
1332 : "implemented for array variables");
1333 : }
1334 :
1335 : template <>
1336 : typename MooseVariableFE<RealEigenVector>::DotType
1337 0 : MooseVariableFE<RealEigenVector>::evaluateDot(const ElemQpArg &, const StateArg &) const
1338 : {
1339 0 : mooseError("MooseVariableFE::evaluateDot(ElemQpArg &, const StateArg &) overload not "
1340 : "implemented for array variables");
1341 : }
1342 :
1343 : template <>
1344 : typename MooseVariableFE<RealEigenVector>::DotType
1345 0 : MooseVariableFE<RealEigenVector>::evaluateDot(const ElemSideQpArg &, const StateArg &) const
1346 : {
1347 0 : mooseError("MooseVariableFE::evaluateDot(ElemSideQpArg &, const StateArg &) overload not "
1348 : "implemented for array variables");
1349 : }
1350 :
1351 : template <typename OutputType>
1352 : void
1353 23988 : MooseVariableFE<OutputType>::meshChanged()
1354 : {
1355 23988 : _current_elem_qp_functor_elem = nullptr;
1356 23988 : _current_elem_side_qp_functor_elem_side = std::make_pair(nullptr, libMesh::invalid_uint);
1357 23988 : MooseVariableField<OutputType>::meshChanged();
1358 23988 : }
1359 :
1360 : template <typename OutputType>
1361 : void
1362 7433477 : MooseVariableFE<OutputType>::residualSetup()
1363 : {
1364 7433477 : _current_elem_qp_functor_elem = nullptr;
1365 7433477 : _current_elem_side_qp_functor_elem_side = std::make_pair(nullptr, libMesh::invalid_uint);
1366 7433477 : MooseVariableField<OutputType>::residualSetup();
1367 7433477 : }
1368 :
1369 : template <typename OutputType>
1370 : void
1371 1232525 : MooseVariableFE<OutputType>::jacobianSetup()
1372 : {
1373 1232525 : _current_elem_qp_functor_elem = nullptr;
1374 1232525 : _current_elem_side_qp_functor_elem_side = std::make_pair(nullptr, libMesh::invalid_uint);
1375 1232525 : MooseVariableField<OutputType>::jacobianSetup();
1376 1232525 : }
1377 :
1378 : template <typename OutputType>
1379 : void
1380 124792 : MooseVariableFE<OutputType>::sizeMatrixTagData()
1381 : {
1382 124792 : _element_data->sizeMatrixTagData();
1383 124792 : _neighbor_data->sizeMatrixTagData();
1384 124792 : _lower_data->sizeMatrixTagData();
1385 124792 : }
1386 :
1387 : template class MooseVariableFE<Real>;
1388 : template class MooseVariableFE<RealVectorValue>;
1389 : template class MooseVariableFE<RealEigenVector>;
|