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 122468 : MooseVariableFE<Real>::validParams()
26 : {
27 122468 : auto params = MooseVariableField<Real>::validParams();
28 122468 : params.addClassDescription(
29 : "Represents standard field variables, e.g. Lagrange, Hermite, or non-constant Monomials");
30 122468 : return params;
31 0 : }
32 :
33 : template <>
34 : InputParameters
35 15848 : MooseVariableFE<RealVectorValue>::validParams()
36 : {
37 15848 : auto params = MooseVariableField<RealVectorValue>::validParams();
38 15848 : params.addClassDescription(
39 : "Represents vector field variables, e.g. Vector Lagrange, Nedelec or Raviart-Thomas");
40 15848 : return params;
41 0 : }
42 :
43 : template <>
44 : InputParameters
45 16761 : MooseVariableFE<RealEigenVector>::validParams()
46 : {
47 16761 : auto params = MooseVariableField<RealEigenVector>::validParams();
48 16761 : params.addClassDescription(
49 : "Used for grouping standard field variables with the same finite element family and order");
50 16761 : return params;
51 0 : }
52 :
53 : template <typename OutputType>
54 165179 : MooseVariableFE<OutputType>::MooseVariableFE(const InputParameters & parameters)
55 165179 : : MooseVariableField<OutputType>(parameters)
56 : {
57 165179 : _element_data = std::make_unique<MooseVariableData<OutputType>>(*this,
58 : _sys,
59 165179 : _tid,
60 165179 : Moose::ElementType::Element,
61 165179 : this->_assembly.qRule(),
62 165179 : this->_assembly.qRuleFace(),
63 165179 : this->_assembly.node(),
64 165179 : this->_assembly.elem());
65 165179 : _neighbor_data = std::make_unique<MooseVariableData<OutputType>>(
66 : *this,
67 : _sys,
68 165179 : _tid,
69 165179 : Moose::ElementType::Neighbor,
70 165179 : this->_assembly.qRuleNeighbor(), // Place holder
71 165179 : this->_assembly.qRuleNeighbor(),
72 165179 : this->_assembly.nodeNeighbor(),
73 165179 : this->_assembly.neighbor());
74 165179 : _lower_data =
75 : std::make_unique<MooseVariableData<OutputType>>(*this,
76 : _sys,
77 165179 : _tid,
78 165179 : Moose::ElementType::Lower,
79 165179 : this->_assembly.qRuleFace(),
80 165179 : this->_assembly.qRuleFace(), // Place holder
81 165179 : this->_assembly.node(), // Place holder
82 165179 : this->_assembly.lowerDElem());
83 165179 : }
84 :
85 : template <typename OutputType>
86 : void
87 693405953 : MooseVariableFE<OutputType>::clearDofIndices()
88 : {
89 693405953 : _element_data->clearDofIndices();
90 693405953 : }
91 :
92 : template <typename OutputType>
93 : void
94 467675853 : MooseVariableFE<OutputType>::prepare()
95 : {
96 467675853 : _element_data->prepare();
97 467675853 : }
98 :
99 : template <typename OutputType>
100 : void
101 13311610 : MooseVariableFE<OutputType>::prepareNeighbor()
102 : {
103 13311610 : _neighbor_data->prepare();
104 13311610 : }
105 :
106 : template <typename OutputType>
107 : void
108 580115 : MooseVariableFE<OutputType>::prepareLowerD()
109 : {
110 580115 : _lower_data->prepare();
111 580115 : }
112 :
113 : template <typename OutputType>
114 : void
115 8572939 : MooseVariableFE<OutputType>::prepareAux()
116 : {
117 8572939 : _element_data->prepareAux();
118 8572939 : _neighbor_data->prepareAux();
119 8572939 : _lower_data->prepareAux();
120 8572939 : }
121 :
122 : template <typename OutputType>
123 : void
124 307731586 : MooseVariableFE<OutputType>::reinitNode()
125 : {
126 307731586 : _element_data->reinitNode();
127 307731586 : }
128 :
129 : template <typename OutputType>
130 : void
131 142955746 : MooseVariableFE<OutputType>::reinitAux()
132 : {
133 142955746 : _element_data->reinitAux();
134 142955746 : }
135 :
136 : template <typename OutputType>
137 : void
138 5556415 : MooseVariableFE<OutputType>::reinitAuxNeighbor()
139 : {
140 5556415 : _neighbor_data->reinitAux();
141 5556415 : }
142 :
143 : template <typename OutputType>
144 : void
145 6190 : MooseVariableFE<OutputType>::reinitNodes(const std::vector<dof_id_type> & nodes)
146 : {
147 6190 : _element_data->reinitNodes(nodes);
148 6190 : }
149 :
150 : template <typename OutputType>
151 : void
152 800 : MooseVariableFE<OutputType>::reinitNodesNeighbor(const std::vector<dof_id_type> & nodes)
153 : {
154 800 : _neighbor_data->reinitNodes(nodes);
155 800 : }
156 :
157 : template <typename OutputType>
158 : void
159 18860 : MooseVariableFE<OutputType>::getDofIndices(const Elem * elem,
160 : std::vector<dof_id_type> & dof_indices) const
161 : {
162 18860 : _element_data->getDofIndices(elem, dof_indices);
163 18860 : }
164 :
165 : template <typename OutputType>
166 : typename MooseVariableFE<OutputType>::OutputData
167 1220 : MooseVariableFE<OutputType>::getNodalValue(const Node & node) const
168 : {
169 1220 : return _element_data->getNodalValue(node, Moose::Current);
170 : }
171 :
172 : template <typename OutputType>
173 : typename MooseVariableFE<OutputType>::OutputData
174 103334 : MooseVariableFE<OutputType>::getNodalValueOld(const Node & node) const
175 : {
176 103334 : return _element_data->getNodalValue(node, Moose::Old);
177 : }
178 :
179 : template <typename OutputType>
180 : typename MooseVariableFE<OutputType>::OutputData
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>::OutputData
188 69928 : MooseVariableFE<OutputType>::getElementalValue(const Elem * elem, unsigned int idx) const
189 : {
190 69928 : return _element_data->getElementalValue(elem, Moose::Current, idx);
191 : }
192 :
193 : template <typename OutputType>
194 : typename MooseVariableFE<OutputType>::OutputData
195 480 : MooseVariableFE<OutputType>::getElementalValueOld(const Elem * elem, unsigned int idx) const
196 : {
197 480 : return _element_data->getElementalValue(elem, Moose::Old, idx);
198 : }
199 :
200 : template <typename OutputType>
201 : typename MooseVariableFE<OutputType>::OutputData
202 480 : MooseVariableFE<OutputType>::getElementalValueOlder(const Elem * elem, unsigned int idx) const
203 : {
204 480 : return _element_data->getElementalValue(elem, Moose::Older, idx);
205 : }
206 :
207 : template <typename OutputType>
208 : void
209 49232061 : MooseVariableFE<OutputType>::insert(NumericVector<Number> & vector)
210 : {
211 49232061 : _element_data->insert(vector);
212 49232061 : }
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 2007301 : MooseVariableFE<OutputType>::add(NumericVector<Number> & vector)
224 : {
225 2007301 : _element_data->add(vector);
226 2007301 : }
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>::DoFValue &
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>::DoFValue &
252 923581 : MooseVariableFE<OutputType>::dofValues() const
253 : {
254 923581 : return _element_data->dofValues();
255 : }
256 :
257 : template <typename OutputType>
258 : const typename MooseVariableFE<OutputType>::DoFValue &
259 102 : MooseVariableFE<OutputType>::dofValuesOld() const
260 : {
261 102 : return _element_data->dofValuesOld();
262 : }
263 :
264 : template <typename OutputType>
265 : const typename MooseVariableFE<OutputType>::DoFValue &
266 39 : MooseVariableFE<OutputType>::dofValuesOlder() const
267 : {
268 39 : return _element_data->dofValuesOlder();
269 : }
270 :
271 : template <typename OutputType>
272 : const typename MooseVariableFE<OutputType>::DoFValue &
273 0 : MooseVariableFE<OutputType>::dofValuesPreviousNL() const
274 : {
275 0 : return _element_data->dofValuesPreviousNL();
276 : }
277 :
278 : template <typename OutputType>
279 : const typename MooseVariableFE<OutputType>::DoFValue &
280 84 : MooseVariableFE<OutputType>::dofValuesNeighbor() const
281 : {
282 84 : return _neighbor_data->dofValues();
283 : }
284 :
285 : template <typename OutputType>
286 : const typename MooseVariableFE<OutputType>::DoFValue &
287 13 : MooseVariableFE<OutputType>::dofValuesOldNeighbor() const
288 : {
289 13 : return _neighbor_data->dofValuesOld();
290 : }
291 :
292 : template <typename OutputType>
293 : const typename MooseVariableFE<OutputType>::DoFValue &
294 0 : MooseVariableFE<OutputType>::dofValuesOlderNeighbor() const
295 : {
296 0 : return _neighbor_data->dofValuesOlder();
297 : }
298 :
299 : template <typename OutputType>
300 : const typename MooseVariableFE<OutputType>::DoFValue &
301 0 : MooseVariableFE<OutputType>::dofValuesPreviousNLNeighbor() const
302 : {
303 0 : return _neighbor_data->dofValuesPreviousNL();
304 : }
305 :
306 : template <typename OutputType>
307 : const typename MooseVariableFE<OutputType>::DoFValue &
308 305 : MooseVariableFE<OutputType>::dofValuesDot() const
309 : {
310 305 : return _element_data->dofValuesDot();
311 : }
312 :
313 : template <typename OutputType>
314 : const typename MooseVariableFE<OutputType>::DoFValue &
315 4 : MooseVariableFE<OutputType>::dofValuesDotDot() const
316 : {
317 4 : return _element_data->dofValuesDotDot();
318 : }
319 :
320 : template <typename OutputType>
321 : const typename MooseVariableFE<OutputType>::DoFValue &
322 0 : MooseVariableFE<OutputType>::dofValuesDotOld() const
323 : {
324 0 : return _element_data->dofValuesDotOld();
325 : }
326 :
327 : template <typename OutputType>
328 : const typename MooseVariableFE<OutputType>::DoFValue &
329 0 : MooseVariableFE<OutputType>::dofValuesDotDotOld() const
330 : {
331 0 : return _element_data->dofValuesDotDotOld();
332 : }
333 :
334 : template <typename OutputType>
335 : const typename MooseVariableFE<OutputType>::DoFValue &
336 0 : MooseVariableFE<OutputType>::dofValuesDotNeighbor() const
337 : {
338 0 : return _neighbor_data->dofValuesDot();
339 : }
340 :
341 : template <typename OutputType>
342 : const typename MooseVariableFE<OutputType>::DoFValue &
343 0 : MooseVariableFE<OutputType>::dofValuesDotDotNeighbor() const
344 : {
345 0 : return _neighbor_data->dofValuesDotDot();
346 : }
347 :
348 : template <typename OutputType>
349 : const typename MooseVariableFE<OutputType>::DoFValue &
350 0 : MooseVariableFE<OutputType>::dofValuesDotOldNeighbor() const
351 : {
352 0 : return _neighbor_data->dofValuesDotOld();
353 : }
354 :
355 : template <typename OutputType>
356 : const typename MooseVariableFE<OutputType>::DoFValue &
357 0 : MooseVariableFE<OutputType>::dofValuesDotDotOldNeighbor() const
358 : {
359 0 : return _neighbor_data->dofValuesDotDotOld();
360 : }
361 :
362 : template <typename OutputType>
363 : const MooseArray<Number> &
364 122 : MooseVariableFE<OutputType>::dofValuesDuDotDu() const
365 : {
366 122 : 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 1998668 : MooseVariableFE<OutputType>::prepareIC()
393 : {
394 1998668 : _element_data->prepareIC();
395 1998668 : }
396 :
397 : template <typename OutputType>
398 : void
399 524572406 : MooseVariableFE<OutputType>::computeElemValues()
400 : {
401 524572406 : _element_data->setGeometry(Moose::Volume);
402 524572406 : _element_data->computeValues();
403 524572406 : }
404 :
405 : template <typename OutputType>
406 : void
407 22604868 : MooseVariableFE<OutputType>::computeElemValuesFace()
408 : {
409 22604868 : _element_data->setGeometry(Moose::Face);
410 22604868 : _element_data->computeValues();
411 22604868 : }
412 :
413 : template <typename OutputType>
414 : void
415 8555386 : MooseVariableFE<OutputType>::computeNeighborValuesFace()
416 : {
417 8555386 : _neighbor_data->setGeometry(Moose::Face);
418 8555386 : _neighbor_data->computeValues();
419 8555386 : }
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 580115 : MooseVariableFE<OutputType>::computeLowerDValues()
432 : {
433 580115 : _lower_data->setGeometry(Moose::Volume);
434 580115 : _lower_data->computeValues();
435 580115 : }
436 :
437 : template <typename OutputType>
438 : void
439 1774 : MooseVariableFE<OutputType>::computeIncrementAtQps(const NumericVector<Number> & increment_vec)
440 : {
441 1774 : _element_data->computeIncrementAtQps(increment_vec);
442 1774 : }
443 :
444 : template <typename OutputType>
445 : void
446 7440 : MooseVariableFE<OutputType>::computeIncrementAtNode(const NumericVector<Number> & increment_vec)
447 : {
448 7440 : _element_data->computeIncrementAtNode(increment_vec);
449 7440 : }
450 :
451 : template <typename OutputType>
452 : OutputType
453 253568 : MooseVariableFE<OutputType>::getValue(const Elem * elem,
454 : const std::vector<std::vector<OutputShape>> & phi) const
455 : {
456 253568 : std::vector<dof_id_type> dof_indices;
457 253568 : this->_dof_map.dof_indices(elem, dof_indices, _var_num);
458 :
459 253568 : OutputType value = 0;
460 253568 : 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 1121652 : 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 868084 : 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 253568 : return value;
478 253568 : }
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 1233 : MooseVariableFE<OutputType>::nodalValue() const
570 : {
571 1233 : 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>::DoFValue &
583 363 : MooseVariableFE<OutputType>::nodalVectorTagValue(TagID tag) const
584 : {
585 363 : return _element_data->nodalVectorTagValue(tag);
586 : }
587 :
588 : template <typename OutputType>
589 : const typename MooseVariableFE<OutputType>::DoFValue &
590 130 : MooseVariableFE<OutputType>::nodalMatrixTagValue(TagID tag) const
591 : {
592 130 : 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 270794637 : MooseVariableFE<OutputType>::computeNodalValues()
668 : {
669 270794637 : _element_data->computeNodalValues();
670 270794637 : }
671 :
672 : template <typename OutputType>
673 : void
674 800 : MooseVariableFE<OutputType>::computeNodalNeighborValues()
675 : {
676 800 : _neighbor_data->computeNodalValues();
677 800 : }
678 :
679 : template <typename OutputType>
680 : void
681 45408588 : MooseVariableFE<OutputType>::setNodalValue(const OutputType & value, unsigned int idx)
682 : {
683 45408588 : _element_data->setNodalValue(value, idx);
684 45408588 : }
685 :
686 : template <typename OutputType>
687 : void
688 7623827 : MooseVariableFE<OutputType>::setDofValue(const OutputData & value, unsigned int index)
689 : {
690 7623827 : _element_data->setDofValue(value, index);
691 7623827 : }
692 :
693 : template <typename OutputType>
694 : void
695 571836 : MooseVariableFE<OutputType>::setDofValues(const DenseVector<OutputData> & values)
696 : {
697 571836 : _element_data->setDofValues(values);
698 571836 : }
699 :
700 : template <typename OutputType>
701 : void
702 1644 : MooseVariableFE<OutputType>::setLowerDofValues(const DenseVector<OutputData> & values)
703 : {
704 1644 : _lower_data->setDofValues(values);
705 1644 : }
706 :
707 : template <typename OutputType>
708 : void
709 54801697 : MooseVariableFE<OutputType>::insertNodalValue(NumericVector<Number> & residual,
710 : const OutputData & v)
711 : {
712 54801697 : _element_data->insertNodalValue(residual, v);
713 54801697 : }
714 :
715 : template <typename OutputType>
716 : const typename MooseVariableFE<OutputType>::FieldVariablePhiSecond &
717 26699 : MooseVariableFE<OutputType>::secondPhi() const
718 : {
719 26699 : return _element_data->secondPhi();
720 : }
721 :
722 : template <typename OutputType>
723 : const typename MooseVariableFE<OutputType>::FieldVariablePhiCurl &
724 57036 : MooseVariableFE<OutputType>::curlPhi() const
725 : {
726 57036 : return _element_data->curlPhi();
727 : }
728 :
729 : template <typename OutputType>
730 : const typename MooseVariableFE<OutputType>::FieldVariablePhiDivergence &
731 468756 : MooseVariableFE<OutputType>::divPhi() const
732 : {
733 468756 : return _element_data->divPhi();
734 : }
735 :
736 : template <typename OutputType>
737 : const typename MooseVariableFE<OutputType>::FieldVariablePhiSecond &
738 5221 : MooseVariableFE<OutputType>::secondPhiFace() const
739 : {
740 5221 : return _element_data->secondPhiFace();
741 : }
742 :
743 : template <typename OutputType>
744 : const typename MooseVariableFE<OutputType>::FieldVariablePhiCurl &
745 0 : MooseVariableFE<OutputType>::curlPhiFace() const
746 : {
747 0 : return _element_data->curlPhiFace();
748 : }
749 :
750 : template <typename OutputType>
751 : const typename MooseVariableFE<OutputType>::FieldVariablePhiDivergence &
752 0 : MooseVariableFE<OutputType>::divPhiFace() const
753 : {
754 0 : return _element_data->divPhiFace();
755 : }
756 :
757 : template <typename OutputType>
758 : const typename MooseVariableFE<OutputType>::FieldVariablePhiSecond &
759 0 : MooseVariableFE<OutputType>::secondPhiNeighbor() const
760 : {
761 0 : return _neighbor_data->secondPhi();
762 : }
763 :
764 : template <typename OutputType>
765 : const typename MooseVariableFE<OutputType>::FieldVariablePhiCurl &
766 0 : MooseVariableFE<OutputType>::curlPhiNeighbor() const
767 : {
768 0 : return _neighbor_data->curlPhi();
769 : }
770 :
771 : template <typename OutputType>
772 : const typename MooseVariableFE<OutputType>::FieldVariablePhiDivergence &
773 0 : MooseVariableFE<OutputType>::divPhiNeighbor() const
774 : {
775 0 : return _neighbor_data->divPhi();
776 : }
777 :
778 : template <typename OutputType>
779 : const typename MooseVariableFE<OutputType>::FieldVariablePhiSecond &
780 0 : MooseVariableFE<OutputType>::secondPhiFaceNeighbor() const
781 : {
782 0 : return _neighbor_data->secondPhiFace();
783 : }
784 :
785 : template <typename OutputType>
786 : const typename MooseVariableFE<OutputType>::FieldVariablePhiCurl &
787 0 : MooseVariableFE<OutputType>::curlPhiFaceNeighbor() const
788 : {
789 0 : return _neighbor_data->curlPhiFace();
790 : }
791 :
792 : template <typename OutputType>
793 : const typename MooseVariableFE<OutputType>::FieldVariablePhiDivergence &
794 0 : MooseVariableFE<OutputType>::divPhiFaceNeighbor() const
795 : {
796 0 : return _neighbor_data->divPhiFace();
797 : }
798 :
799 : template <typename OutputType>
800 : bool
801 131499690 : MooseVariableFE<OutputType>::usesSecondPhi() const
802 : {
803 131499690 : return _element_data->usesSecondPhi();
804 : }
805 :
806 : template <typename OutputType>
807 : bool
808 194810 : MooseVariableFE<OutputType>::usesSecondPhiNeighbor() const
809 : {
810 194810 : return _neighbor_data->usesSecondPhi();
811 : }
812 :
813 : template <typename OutputType>
814 : bool
815 1950419 : MooseVariableFE<OutputType>::computingCurl() const
816 : {
817 1950419 : return _element_data->computingCurl();
818 : }
819 :
820 : template <typename OutputType>
821 : bool
822 1950419 : MooseVariableFE<OutputType>::computingDiv() const
823 : {
824 1950419 : return _element_data->computingDiv();
825 : }
826 :
827 : template <typename OutputType>
828 : bool
829 442052425 : MooseVariableFE<OutputType>::isNodalDefined() const
830 : {
831 442052425 : return _element_data->isNodalDefined();
832 : }
833 :
834 : template <typename OutputType>
835 : bool
836 0 : MooseVariableFE<OutputType>::isNodalNeighborDefined() const
837 : {
838 0 : return _neighbor_data->isNodalDefined();
839 : }
840 :
841 : template <typename OutputType>
842 : unsigned int
843 145344 : MooseVariableFE<OutputType>::oldestSolutionStateRequested() const
844 : {
845 145344 : unsigned int state = 0;
846 145344 : state = std::max(state, _element_data->oldestSolutionStateRequested());
847 145344 : state = std::max(state, _neighbor_data->oldestSolutionStateRequested());
848 145344 : state = std::max(state, _lower_data->oldestSolutionStateRequested());
849 145344 : return state;
850 : }
851 :
852 : template <typename OutputType>
853 : void
854 1208735 : MooseVariableFE<OutputType>::clearAllDofIndices()
855 : {
856 1208735 : _element_data->clearDofIndices();
857 1208735 : _neighbor_data->clearDofIndices();
858 1208735 : _lower_data->clearDofIndices();
859 1208735 : }
860 :
861 : template <typename OutputType>
862 : typename MooseVariableFE<OutputType>::ValueType
863 77346 : MooseVariableFE<OutputType>::evaluate(const NodeArg & node_arg, const StateArg & state) const
864 : {
865 : mooseAssert(node_arg.node, "Must have a node");
866 77346 : const Node & node = *node_arg.node;
867 : mooseAssert(node.n_dofs(this->_sys.number(), this->number()),
868 : "Our variable must have dofs on the requested node");
869 77346 : const auto & soln = this->getSolution(state);
870 : if constexpr (std::is_same<OutputType, Real>::value)
871 : {
872 77346 : const auto dof_number = node.dof_number(this->_sys.number(), this->number(), 0);
873 77346 : ValueType ret = soln(dof_number);
874 77346 : if (Moose::doDerivatives(_subproblem, _sys))
875 19528 : Moose::derivInsert(ret.derivatives(), dof_number, 1);
876 154692 : return ret;
877 77346 : }
878 : else if constexpr (std::is_same<OutputType, RealVectorValue>::value)
879 : {
880 0 : ValueType ret;
881 0 : const auto do_derivatives = Moose::doDerivatives(_subproblem, _sys);
882 0 : for (const auto d : make_range(this->_mesh.dimension()))
883 : {
884 0 : const auto dof_number = node.dof_number(this->_sys.number(), this->number(), d);
885 0 : auto & component = ret(d);
886 0 : component = soln(dof_number);
887 0 : if (do_derivatives)
888 0 : Moose::derivInsert(component.derivatives(), dof_number, 1);
889 : }
890 0 : return ret;
891 0 : }
892 : else
893 0 : mooseError("RealEigenVector not yet supported for functors");
894 : }
895 :
896 : namespace
897 : {
898 : template <typename OutputType>
899 : struct FEBaseHelper
900 : {
901 : typedef FEBase type;
902 : };
903 :
904 : template <>
905 : struct FEBaseHelper<RealVectorValue>
906 : {
907 : typedef FEVectorBase type;
908 : };
909 : }
910 :
911 : template <typename OutputType>
912 : template <typename Shapes, typename Solution, typename GradShapes, typename GradSolution>
913 : void
914 870135 : MooseVariableFE<OutputType>::computeSolution(const Elem * const elem,
915 : const unsigned int n_qp,
916 : const StateArg & state,
917 : const Shapes & phi,
918 : Solution & local_soln,
919 : const GradShapes & grad_phi,
920 : GradSolution & grad_local_soln,
921 : Solution & dot_local_soln,
922 : GradSolution & grad_dot_local_soln) const
923 : {
924 870135 : std::vector<dof_id_type> dof_indices;
925 870135 : this->_dof_map.dof_indices(elem, dof_indices, _var_num);
926 870135 : std::vector<ADReal> dof_values;
927 870135 : std::vector<ADReal> dof_values_dot;
928 870135 : dof_values.reserve(dof_indices.size());
929 :
930 870135 : const bool computing_dot = _time_integrator && _time_integrator->dt();
931 870135 : if (computing_dot)
932 301200 : dof_values_dot.reserve(dof_indices.size());
933 :
934 870135 : const bool do_derivatives = Moose::doDerivatives(_subproblem, _sys);
935 870135 : const auto & global_soln = getSolution(state);
936 3735025 : for (const auto dof_index : dof_indices)
937 : {
938 2864890 : dof_values.push_back(ADReal(global_soln(dof_index)));
939 2864890 : if (do_derivatives && state.state == 0)
940 304402 : Moose::derivInsert(dof_values.back().derivatives(), dof_index, 1.);
941 2864890 : if (computing_dot)
942 : {
943 1546456 : if (_var_kind == Moose::VAR_SOLVER)
944 : {
945 1542040 : dof_values_dot.push_back(dof_values.back());
946 1542040 : _time_integrator->computeADTimeDerivatives(
947 1542040 : dof_values_dot.back(), dof_index, _ad_real_dummy);
948 : }
949 : else
950 4416 : dof_values_dot.push_back((*this->_sys.solutionUDot())(dof_index));
951 : }
952 : }
953 :
954 870135 : local_soln.resize(n_qp);
955 870135 : grad_local_soln.resize(n_qp);
956 870135 : if (computing_dot)
957 : {
958 301200 : dot_local_soln.resize(n_qp);
959 301200 : grad_dot_local_soln.resize(n_qp);
960 : }
961 :
962 3662544 : for (const auto qp : make_range(n_qp))
963 : {
964 2792409 : local_soln[qp] = 0;
965 2792409 : grad_local_soln[qp] = 0;
966 2792409 : if (computing_dot)
967 : {
968 1535704 : dot_local_soln[qp] = 0;
969 1535704 : grad_dot_local_soln[qp] = GradientType{};
970 : }
971 14884827 : for (const auto i : index_range(dof_indices))
972 : {
973 12092418 : local_soln[qp] += dof_values[i] * phi[i][qp];
974 12092418 : grad_local_soln[qp] += dof_values[i] * grad_phi[i][qp];
975 12092418 : if (computing_dot)
976 : {
977 8919832 : dot_local_soln[qp] += dof_values_dot[i] * phi[i][qp];
978 8919832 : grad_dot_local_soln[qp] += dof_values_dot[i] * grad_phi[i][qp];
979 : }
980 : }
981 : }
982 870135 : }
983 :
984 : template <typename OutputType>
985 : void
986 14093595 : MooseVariableFE<OutputType>::evaluateOnElement(const ElemQpArg & elem_qp,
987 : const StateArg & state,
988 : const bool cache_eligible) const
989 : {
990 : mooseAssert(this->hasBlocks(elem_qp.elem->subdomain_id()),
991 : "Variable " + this->name() + " doesn't exist on block " +
992 : std::to_string(elem_qp.elem->subdomain_id()));
993 :
994 14093595 : const Elem * const elem = elem_qp.elem;
995 14093595 : if (!cache_eligible || (elem != _current_elem_qp_functor_elem))
996 : {
997 858063 : const QBase * const qrule_template = elem_qp.qrule;
998 :
999 : using FEBaseType = typename FEBaseHelper<OutputType>::type;
1000 858063 : std::unique_ptr<FEBaseType> fe(FEBaseType::build(elem->dim(), _fe_type));
1001 858063 : auto qrule = qrule_template->clone();
1002 :
1003 858063 : const auto & phi = fe->get_phi();
1004 858063 : const auto & dphi = fe->get_dphi();
1005 858063 : fe->attach_quadrature_rule(qrule.get());
1006 858063 : fe->reinit(elem);
1007 :
1008 858063 : computeSolution(elem,
1009 : qrule->n_points(),
1010 : state,
1011 : phi,
1012 858063 : _current_elem_qp_functor_sln,
1013 : dphi,
1014 858063 : _current_elem_qp_functor_gradient,
1015 858063 : _current_elem_qp_functor_dot,
1016 858063 : _current_elem_qp_functor_grad_dot);
1017 858063 : }
1018 14093595 : if (cache_eligible)
1019 14088083 : _current_elem_qp_functor_elem = elem;
1020 : else
1021 : // These evaluations are not eligible for caching, e.g. maybe this is a single point quadrature
1022 : // rule evaluation at an arbitrary point and we don't want those evaluations to potentially be
1023 : // re-used when this function is called with a standard quadrature rule or a different point
1024 5512 : _current_elem_qp_functor_elem = nullptr;
1025 14093595 : }
1026 :
1027 : template <>
1028 : void
1029 0 : MooseVariableFE<RealEigenVector>::evaluateOnElement(const ElemQpArg &, const StateArg &, bool) const
1030 : {
1031 0 : mooseError("evaluate not implemented for array variables");
1032 : }
1033 :
1034 : template <typename OutputType>
1035 : typename MooseVariableFE<OutputType>::ValueType
1036 2208211 : MooseVariableFE<OutputType>::evaluate(const ElemQpArg & elem_qp, const StateArg & state) const
1037 : {
1038 2208211 : evaluateOnElement(elem_qp, state, /*query_cache=*/true);
1039 2208211 : const auto qp = elem_qp.qp;
1040 : mooseAssert(qp < _current_elem_qp_functor_sln.size(),
1041 : "The requested " << qp << " is outside our solution size");
1042 2208211 : return _current_elem_qp_functor_sln[qp];
1043 : }
1044 :
1045 : template <typename OutputType>
1046 : typename MooseVariableFE<OutputType>::ValueType
1047 1608 : MooseVariableFE<OutputType>::evaluate(const ElemArg & elem_arg, const StateArg & state) const
1048 : {
1049 1608 : const QMonomial qrule(elem_arg.elem->dim(), CONSTANT);
1050 : // We can use whatever we want for the point argument since it won't be used
1051 1608 : const ElemQpArg elem_qp_arg{elem_arg.elem, /*qp=*/0, &qrule, Point(0, 0, 0)};
1052 1608 : evaluateOnElement(elem_qp_arg, state, /*cache_eligible=*/false);
1053 3216 : return _current_elem_qp_functor_sln[0];
1054 1608 : }
1055 :
1056 : template <typename OutputType>
1057 : typename MooseVariableFE<OutputType>::ValueType
1058 346 : MooseVariableFE<OutputType>::faceEvaluate(const FaceArg & face_arg,
1059 : const StateArg & state,
1060 : const std::vector<ValueType> & cache_data) const
1061 : {
1062 346 : const QMonomial qrule(face_arg.fi->elem().dim() - 1, CONSTANT);
1063 346 : auto side_evaluate =
1064 1038 : [this, &qrule, &state, &cache_data](const Elem * const elem, const unsigned int side)
1065 : {
1066 : // We can use whatever we want for the point argument since it won't be used
1067 346 : const ElemSideQpArg elem_side_qp_arg{elem, side, /*qp=*/0, &qrule, Point(0, 0, 0)};
1068 346 : evaluateOnElementSide(elem_side_qp_arg, state, /*cache_eligible=*/false);
1069 692 : return cache_data[0];
1070 : };
1071 :
1072 346 : const auto continuity = this->getContinuity();
1073 : bool on_elem;
1074 : bool on_neighbor;
1075 346 : if (!face_arg.face_side)
1076 : {
1077 0 : on_elem = this->hasBlocks(face_arg.fi->elemPtr()->subdomain_id());
1078 0 : on_neighbor =
1079 0 : face_arg.fi->neighborPtr() && this->hasBlocks(face_arg.fi->neighborPtr()->subdomain_id());
1080 : }
1081 : else
1082 : {
1083 346 : on_elem = face_arg.face_side == face_arg.fi->elemPtr();
1084 346 : on_neighbor = face_arg.face_side == face_arg.fi->neighborPtr();
1085 : }
1086 :
1087 : // Only do multiple evaluations if we are not continuous and we are on an internal face
1088 346 : if ((continuity != C_ZERO && continuity != C_ONE) && on_elem && on_neighbor)
1089 0 : return (side_evaluate(face_arg.fi->elemPtr(), face_arg.fi->elemSideID()) +
1090 0 : side_evaluate(face_arg.fi->neighborPtr(), face_arg.fi->neighborSideID())) /
1091 0 : 2;
1092 346 : else if (on_elem)
1093 346 : return side_evaluate(face_arg.fi->elemPtr(), face_arg.fi->elemSideID());
1094 0 : else if (on_neighbor)
1095 0 : return side_evaluate(face_arg.fi->neighborPtr(), face_arg.fi->neighborSideID());
1096 : else
1097 0 : mooseError(
1098 : "Attempted to evaluate a moose finite element variable on a face where it is not defined");
1099 346 : }
1100 :
1101 : template <typename OutputType>
1102 : typename MooseVariableFE<OutputType>::ValueType
1103 346 : MooseVariableFE<OutputType>::evaluate(const FaceArg & face_arg, const StateArg & state) const
1104 : {
1105 346 : return faceEvaluate(face_arg, state, _current_elem_side_qp_functor_sln);
1106 : }
1107 :
1108 : template <typename OutputType>
1109 : typename MooseVariableFE<OutputType>::ValueType
1110 512 : MooseVariableFE<OutputType>::evaluate(const ElemPointArg & elem_point_arg,
1111 : const StateArg & state) const
1112 : {
1113 : mooseAssert(elem_point_arg.elem, "We need an Elem");
1114 512 : const Elem & elem = *elem_point_arg.elem;
1115 512 : const auto dim = elem.dim();
1116 512 : ArbitraryQuadrature qrule(dim);
1117 512 : const std::vector<Point> ref_point = {FEMap::inverse_map(dim, &elem, elem_point_arg.point)};
1118 512 : qrule.setPoints(ref_point);
1119 : // We can use whatever we want for the point argument since it won't be used
1120 512 : const ElemQpArg elem_qp_arg{elem_point_arg.elem, /*qp=*/0, &qrule, elem_point_arg.point};
1121 512 : evaluateOnElement(elem_qp_arg, state, /*cache_eligible=*/false);
1122 1024 : return _current_elem_qp_functor_sln[0];
1123 512 : }
1124 :
1125 : template <typename OutputType>
1126 : typename MooseVariableFE<OutputType>::GradientType
1127 11047488 : MooseVariableFE<OutputType>::evaluateGradient(const ElemQpArg & elem_qp,
1128 : const StateArg & state) const
1129 : {
1130 11047488 : evaluateOnElement(elem_qp, state, /*query_cache=*/true);
1131 11047488 : const auto qp = elem_qp.qp;
1132 : mooseAssert(qp < _current_elem_qp_functor_gradient.size(),
1133 : "The requested " << qp << " is outside our gradient size");
1134 11047488 : return _current_elem_qp_functor_gradient[qp];
1135 : }
1136 :
1137 : template <typename OutputType>
1138 : typename MooseVariableFE<OutputType>::GradientType
1139 960 : MooseVariableFE<OutputType>::evaluateGradient(const ElemArg & elem_arg,
1140 : const StateArg & state) const
1141 : {
1142 960 : const QMonomial qrule(elem_arg.elem->dim(), CONSTANT);
1143 : // We can use whatever we want for the point argument since it won't be used
1144 960 : const ElemQpArg elem_qp_arg{elem_arg.elem, /*qp=*/0, &qrule, Point(0, 0, 0)};
1145 960 : evaluateOnElement(elem_qp_arg, state, /*cache_eligible=*/false);
1146 1920 : return _current_elem_qp_functor_gradient[0];
1147 960 : }
1148 :
1149 : template <typename OutputType>
1150 : typename MooseVariableFE<OutputType>::DotType
1151 832384 : MooseVariableFE<OutputType>::evaluateDot(const ElemQpArg & elem_qp, const StateArg & state) const
1152 : {
1153 : mooseAssert(_time_integrator,
1154 : "A time derivative is being requested but we do not have a time integrator so we'll "
1155 : "have no idea how to compute it");
1156 : mooseAssert(_time_integrator->dt(),
1157 : "A time derivative is being requested but the time integrator wants to perform a 0s "
1158 : "time step");
1159 832384 : evaluateOnElement(elem_qp, state, /*query_cache=*/true);
1160 832384 : const auto qp = elem_qp.qp;
1161 : mooseAssert(qp < _current_elem_qp_functor_dot.size(),
1162 : "The requested " << qp << " is outside our dot size");
1163 832384 : return _current_elem_qp_functor_dot[qp];
1164 : }
1165 :
1166 : template <typename OutputType>
1167 : typename MooseVariableFE<OutputType>::DotType
1168 1472 : MooseVariableFE<OutputType>::evaluateDot(const ElemArg & elem_arg, const StateArg & state) const
1169 : {
1170 : mooseAssert(_time_integrator,
1171 : "A time derivative is being requested but we do not have a time integrator so we'll "
1172 : "have no idea how to compute it");
1173 : mooseAssert(_time_integrator->dt(),
1174 : "A time derivative is being requested but the time integrator wants to perform a 0s "
1175 : "time step");
1176 1472 : const QMonomial qrule(elem_arg.elem->dim(), CONSTANT);
1177 : // We can use whatever we want for the point argument since it won't be used
1178 1472 : const ElemQpArg elem_qp_arg{elem_arg.elem, /*qp=*/0, &qrule, Point(0, 0, 0)};
1179 1472 : evaluateOnElement(elem_qp_arg, state, /*cache_eligible=*/false);
1180 2944 : return _current_elem_qp_functor_dot[0];
1181 1472 : }
1182 :
1183 : template <typename OutputType>
1184 : typename MooseVariableFE<OutputType>::GradientType
1185 960 : MooseVariableFE<OutputType>::evaluateGradDot(const ElemArg & elem_arg, const StateArg & state) const
1186 : {
1187 : mooseAssert(_time_integrator,
1188 : "A time derivative is being requested but we do not have a time integrator so we'll "
1189 : "have no idea how to compute it");
1190 : mooseAssert(_time_integrator->dt(),
1191 : "A time derivative is being requested but the time integrator wants to perform a 0s "
1192 : "time step");
1193 960 : const QMonomial qrule(elem_arg.elem->dim(), CONSTANT);
1194 : // We can use whatever we want for the point argument since it won't be used
1195 960 : const ElemQpArg elem_qp_arg{elem_arg.elem, /*qp=*/0, &qrule, Point(0, 0, 0)};
1196 960 : evaluateOnElement(elem_qp_arg, state, /*cache_eligible=*/false);
1197 1920 : return _current_elem_qp_functor_grad_dot[0];
1198 960 : }
1199 :
1200 : template <typename OutputType>
1201 : void
1202 87658 : MooseVariableFE<OutputType>::evaluateOnElementSide(const ElemSideQpArg & elem_side_qp,
1203 : const StateArg & state,
1204 : const bool cache_eligible) const
1205 : {
1206 : mooseAssert(this->hasBlocks(elem_side_qp.elem->subdomain_id()),
1207 : "Variable " + this->name() + " doesn't exist on block " +
1208 : std::to_string(elem_side_qp.elem->subdomain_id()));
1209 :
1210 87658 : const Elem * const elem = elem_side_qp.elem;
1211 87658 : const auto side = elem_side_qp.side;
1212 87658 : if (!cache_eligible || elem != _current_elem_side_qp_functor_elem_side.first ||
1213 75922 : side != _current_elem_side_qp_functor_elem_side.second)
1214 : {
1215 12072 : const QBase * const qrule_template = elem_side_qp.qrule;
1216 :
1217 : using FEBaseType = typename FEBaseHelper<OutputType>::type;
1218 12072 : std::unique_ptr<FEBaseType> fe(FEBaseType::build(elem->dim(), _fe_type));
1219 12072 : auto qrule = qrule_template->clone();
1220 :
1221 12072 : const auto & phi = fe->get_phi();
1222 12072 : const auto & dphi = fe->get_dphi();
1223 12072 : fe->attach_quadrature_rule(qrule.get());
1224 12072 : fe->reinit(elem, side);
1225 :
1226 12072 : computeSolution(elem,
1227 : qrule->n_points(),
1228 : state,
1229 : phi,
1230 12072 : _current_elem_side_qp_functor_sln,
1231 : dphi,
1232 12072 : _current_elem_side_qp_functor_gradient,
1233 12072 : _current_elem_side_qp_functor_dot,
1234 12072 : _current_elem_side_qp_functor_grad_dot);
1235 12072 : }
1236 87658 : if (cache_eligible)
1237 87312 : _current_elem_side_qp_functor_elem_side = std::make_pair(elem, side);
1238 : else
1239 : // These evaluations are not eligible for caching, e.g. maybe this is a single point quadrature
1240 : // rule evaluation at an arbitrary point and we don't want those evaluations to potentially be
1241 : // re-used when this function is called with a standard quadrature rule or a different point
1242 346 : _current_elem_side_qp_functor_elem_side = std::make_pair(nullptr, libMesh::invalid_uint);
1243 87658 : }
1244 :
1245 : template <>
1246 : void
1247 0 : MooseVariableFE<RealEigenVector>::evaluateOnElementSide(const ElemSideQpArg &,
1248 : const StateArg &,
1249 : bool) const
1250 : {
1251 0 : mooseError("evaluate not implemented for array variables");
1252 : }
1253 :
1254 : template <typename OutputType>
1255 : typename MooseVariableFE<OutputType>::ValueType
1256 87312 : MooseVariableFE<OutputType>::evaluate(const ElemSideQpArg & elem_side_qp,
1257 : const StateArg & state) const
1258 : {
1259 87312 : evaluateOnElementSide(elem_side_qp, state, true);
1260 87312 : const auto qp = elem_side_qp.qp;
1261 : mooseAssert(qp < _current_elem_side_qp_functor_sln.size(),
1262 : "The requested " << qp << " is outside our solution size");
1263 87312 : return _current_elem_side_qp_functor_sln[qp];
1264 : }
1265 :
1266 : template <typename OutputType>
1267 : typename MooseVariableFE<OutputType>::GradientType
1268 0 : MooseVariableFE<OutputType>::evaluateGradient(const ElemSideQpArg & elem_side_qp,
1269 : const StateArg & state) const
1270 : {
1271 0 : evaluateOnElementSide(elem_side_qp, state, true);
1272 0 : const auto qp = elem_side_qp.qp;
1273 : mooseAssert(qp < _current_elem_side_qp_functor_gradient.size(),
1274 : "The requested " << qp << " is outside our gradient size");
1275 0 : return _current_elem_side_qp_functor_gradient[qp];
1276 : }
1277 :
1278 : template <typename OutputType>
1279 : typename MooseVariableFE<OutputType>::DotType
1280 0 : MooseVariableFE<OutputType>::evaluateDot(const ElemSideQpArg & elem_side_qp,
1281 : const StateArg & state) const
1282 : {
1283 : mooseAssert(_time_integrator && _time_integrator->dt(),
1284 : "A time derivative is being requested but we do not have a time integrator so we'll "
1285 : "have no idea how to compute it");
1286 0 : evaluateOnElementSide(elem_side_qp, state, true);
1287 0 : const auto qp = elem_side_qp.qp;
1288 : mooseAssert(qp < _current_elem_side_qp_functor_dot.size(),
1289 : "The requested " << qp << " is outside our dot size");
1290 0 : return _current_elem_side_qp_functor_dot[qp];
1291 : }
1292 :
1293 : template <typename OutputType>
1294 : typename MooseVariableFE<OutputType>::DotType
1295 0 : MooseVariableFE<OutputType>::evaluateDot(const FaceArg & face_arg, const StateArg & state) const
1296 : {
1297 : mooseAssert(_time_integrator && _time_integrator->dt(),
1298 : "A time derivative is being requested but we do not have a time integrator so we'll "
1299 : "have no idea how to compute it");
1300 0 : return faceEvaluate(face_arg, state, _current_elem_side_qp_functor_dot);
1301 : }
1302 :
1303 : template <>
1304 : typename MooseVariableFE<RealEigenVector>::ValueType
1305 0 : MooseVariableFE<RealEigenVector>::evaluate(const ElemQpArg &, const StateArg &) const
1306 : {
1307 0 : mooseError(
1308 : "MooseVariableFE::evaluate(ElemQpArg &, const StateArg &) overload not implemented for "
1309 : "array variables");
1310 : }
1311 :
1312 : template <>
1313 : typename MooseVariableFE<RealEigenVector>::ValueType
1314 0 : MooseVariableFE<RealEigenVector>::evaluate(const ElemSideQpArg &, const StateArg &) const
1315 : {
1316 0 : mooseError("MooseVariableFE::evaluate(ElemSideQpArg &, const StateArg &) overload not "
1317 : "implemented for array variables");
1318 : }
1319 :
1320 : template <>
1321 : typename MooseVariableFE<RealEigenVector>::GradientType
1322 0 : MooseVariableFE<RealEigenVector>::evaluateGradient(const ElemQpArg &, const StateArg &) const
1323 : {
1324 0 : mooseError("MooseVariableFE::evaluateGradient(ElemQpArg &, const StateArg &) overload not "
1325 : "implemented for array variables");
1326 : }
1327 :
1328 : template <>
1329 : typename MooseVariableFE<RealEigenVector>::GradientType
1330 0 : MooseVariableFE<RealEigenVector>::evaluateGradient(const ElemSideQpArg &, const StateArg &) const
1331 : {
1332 0 : mooseError("MooseVariableFE::evaluateGradient(ElemSideQpArg &, const StateArg &) overload not "
1333 : "implemented for array variables");
1334 : }
1335 :
1336 : template <>
1337 : typename MooseVariableFE<RealEigenVector>::DotType
1338 0 : MooseVariableFE<RealEigenVector>::evaluateDot(const ElemQpArg &, const StateArg &) const
1339 : {
1340 0 : mooseError("MooseVariableFE::evaluateDot(ElemQpArg &, const StateArg &) overload not "
1341 : "implemented for array variables");
1342 : }
1343 :
1344 : template <>
1345 : typename MooseVariableFE<RealEigenVector>::DotType
1346 0 : MooseVariableFE<RealEigenVector>::evaluateDot(const ElemSideQpArg &, const StateArg &) const
1347 : {
1348 0 : mooseError("MooseVariableFE::evaluateDot(ElemSideQpArg &, const StateArg &) overload not "
1349 : "implemented for array variables");
1350 : }
1351 :
1352 : template <typename OutputType>
1353 : void
1354 20675 : MooseVariableFE<OutputType>::meshChanged()
1355 : {
1356 20675 : _current_elem_qp_functor_elem = nullptr;
1357 20675 : _current_elem_side_qp_functor_elem_side = std::make_pair(nullptr, libMesh::invalid_uint);
1358 20675 : MooseVariableField<OutputType>::meshChanged();
1359 20675 : }
1360 :
1361 : template <typename OutputType>
1362 : void
1363 7247313 : MooseVariableFE<OutputType>::residualSetup()
1364 : {
1365 7247313 : _current_elem_qp_functor_elem = nullptr;
1366 7247313 : _current_elem_side_qp_functor_elem_side = std::make_pair(nullptr, libMesh::invalid_uint);
1367 7247313 : MooseVariableField<OutputType>::residualSetup();
1368 7247313 : }
1369 :
1370 : template <typename OutputType>
1371 : void
1372 1204373 : MooseVariableFE<OutputType>::jacobianSetup()
1373 : {
1374 1204373 : _current_elem_qp_functor_elem = nullptr;
1375 1204373 : _current_elem_side_qp_functor_elem_side = std::make_pair(nullptr, libMesh::invalid_uint);
1376 1204373 : MooseVariableField<OutputType>::jacobianSetup();
1377 1204373 : }
1378 :
1379 : template class MooseVariableFE<Real>;
1380 : template class MooseVariableFE<RealVectorValue>;
1381 : template class MooseVariableFE<RealEigenVector>;
|