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 : #pragma once
11 :
12 : #include "MooseTypes.h"
13 : #include "MooseVariableFEBase.h"
14 : #include "SubProblem.h"
15 : #include "MooseMesh.h"
16 : #include "MooseVariableField.h"
17 : #include "MooseVariableData.h"
18 :
19 : #include "libmesh/numeric_vector.h"
20 : #include "libmesh/dof_map.h"
21 : #include "libmesh/elem.h"
22 : #include "libmesh/quadrature.h"
23 : #include "libmesh/dense_vector.h"
24 : #include "libmesh/enum_fe_family.h"
25 :
26 : class TimeIntegrator;
27 : template <typename>
28 : class MooseVariableFE;
29 : typedef MooseVariableFE<Real> MooseVariable;
30 : typedef MooseVariableFE<RealVectorValue> VectorMooseVariable;
31 : typedef MooseVariableFE<RealEigenVector> ArrayMooseVariable;
32 :
33 : /**
34 : * Class for stuff related to variables
35 : *
36 : * Each variable can compute nodal or elemental (at QPs) values.
37 : *
38 : * OutputType OutputShape OutputData
39 : * ----------------------------------------------------
40 : * Real Real Real
41 : * RealVectorValue RealVectorValue Real
42 : * RealEigenVector Real RealEigenVector
43 : *
44 : */
45 : template <typename OutputType>
46 : class MooseVariableFE : public MooseVariableField<OutputType>
47 : {
48 : public:
49 : using OutputGradient = typename MooseVariableField<OutputType>::OutputGradient;
50 : using OutputSecond = typename MooseVariableField<OutputType>::OutputSecond;
51 : using OutputDivergence = typename MooseVariableField<OutputType>::OutputDivergence;
52 :
53 : using FieldVariableValue = typename MooseVariableField<OutputType>::FieldVariableValue;
54 : using FieldVariableGradient = typename MooseVariableField<OutputType>::FieldVariableGradient;
55 : using FieldVariableSecond = typename MooseVariableField<OutputType>::FieldVariableSecond;
56 : using FieldVariableCurl = typename MooseVariableField<OutputType>::FieldVariableCurl;
57 : using FieldVariableDivergence = typename MooseVariableField<OutputType>::FieldVariableDivergence;
58 :
59 : using OutputShape = typename MooseVariableField<OutputType>::OutputShape;
60 : using OutputShapeGradient = typename MooseVariableField<OutputType>::OutputShapeGradient;
61 : using OutputShapeSecond = typename MooseVariableField<OutputType>::OutputShapeSecond;
62 : using OutputShapeDivergence = typename MooseVariableField<OutputType>::OutputShapeDivergence;
63 :
64 : using FieldVariablePhiValue = typename MooseVariableField<OutputType>::FieldVariablePhiValue;
65 : using FieldVariablePhiGradient =
66 : typename MooseVariableField<OutputType>::FieldVariablePhiGradient;
67 : using FieldVariablePhiSecond = typename MooseVariableField<OutputType>::FieldVariablePhiSecond;
68 : using FieldVariablePhiCurl = typename MooseVariableField<OutputType>::FieldVariablePhiCurl;
69 : using FieldVariablePhiDivergence =
70 : typename MooseVariableField<OutputType>::FieldVariablePhiDivergence;
71 :
72 : using FieldVariableTestValue = typename MooseVariableField<OutputType>::FieldVariableTestValue;
73 : using FieldVariableTestGradient =
74 : typename MooseVariableField<OutputType>::FieldVariableTestGradient;
75 : using FieldVariableTestSecond = typename MooseVariableField<OutputType>::FieldVariableTestSecond;
76 : using FieldVariableTestCurl = typename MooseVariableField<OutputType>::FieldVariableTestCurl;
77 : using FieldVariableTestDivergence =
78 : typename MooseVariableField<OutputType>::FieldVariableTestDivergence;
79 :
80 : using OutputData = typename MooseVariableField<OutputType>::OutputData;
81 : using DoFValue = typename MooseVariableField<OutputType>::DoFValue;
82 :
83 : using FunctorArg = typename Moose::ADType<OutputType>::type;
84 : using typename Moose::FunctorBase<FunctorArg>::ValueType;
85 : using typename Moose::FunctorBase<FunctorArg>::GradientType;
86 : using typename Moose::FunctorBase<FunctorArg>::DotType;
87 :
88 : MooseVariableFE(const InputParameters & parameters);
89 :
90 : static InputParameters validParams();
91 :
92 : void clearDofIndices() override;
93 :
94 : void prepare() override;
95 : void prepareNeighbor() override;
96 : void prepareLowerD() override;
97 : virtual void prepareIC() override;
98 :
99 : void prepareAux() override;
100 :
101 : void reinitNode() override;
102 : void reinitAux() override;
103 : void reinitAuxNeighbor() override;
104 :
105 : void reinitNodes(const std::vector<dof_id_type> & nodes) override;
106 : void reinitNodesNeighbor(const std::vector<dof_id_type> & nodes) override;
107 :
108 : /**
109 : * Whether or not this variable is actually using the shape function value.
110 : *
111 : * Currently hardcoded to true because we always compute the value.
112 : */
113 0 : bool usesPhi() const { return true; }
114 : /**
115 : * Whether or not this variable is actually using the shape function gradient.
116 : *
117 : * Currently hardcoded to true because we always compute the value.
118 : */
119 0 : bool usesGradPhi() const { return true; }
120 :
121 : /**
122 : * Whether or not this variable is computing any second derivatives.
123 : */
124 : bool usesSecondPhi() const;
125 :
126 : /**
127 : * Whether or not this variable is actually using the shape function second derivative on a
128 : * neighbor.
129 : */
130 : bool usesSecondPhiNeighbor() const override final;
131 :
132 : /**
133 : * Whether or not this variable is computing any second derivatives.
134 : */
135 131499690 : bool computingSecond() const override final { return usesSecondPhi(); }
136 :
137 : /**
138 : * Whether or not this variable is computing the curl
139 : */
140 : bool computingCurl() const override final;
141 :
142 : /**
143 : * Whether or not this variable is computing the divergence
144 : */
145 : bool computingDiv() const override final;
146 :
147 922534683 : bool isNodal() const override { return _element_data->isNodal(); }
148 125 : bool hasDoFsOnNodes() const override { return _element_data->hasDoFsOnNodes(); }
149 196140 : libMesh::FEContinuity getContinuity() const override { return _element_data->getContinuity(); };
150 68250 : const Node * const & node() const { return _element_data->node(); }
151 14695164 : const dof_id_type & nodalDofIndex() const override { return _element_data->nodalDofIndex(); }
152 : virtual bool isNodalDefined() const override;
153 :
154 0 : const Node * const & nodeNeighbor() const { return _neighbor_data->node(); }
155 0 : const dof_id_type & nodalDofIndexNeighbor() const override
156 : {
157 0 : return _neighbor_data->nodalDofIndex();
158 : }
159 : bool isNodalNeighborDefined() const;
160 :
161 30467 : const Elem * const & currentElem() const override { return _element_data->currentElem(); }
162 :
163 : /**
164 : * Current side this variable is being evaluated on
165 : */
166 0 : const unsigned int & currentSide() const { return _element_data->currentSide(); }
167 :
168 : /**
169 : * Current neighboring element
170 : */
171 297 : const Elem * const & neighbor() const { return _neighbor_data->currentElem(); }
172 :
173 : virtual void getDofIndices(const Elem * elem,
174 : std::vector<dof_id_type> & dof_indices) const override;
175 2605362018 : const std::vector<dof_id_type> & dofIndices() const final { return _element_data->dofIndices(); }
176 15120531 : unsigned int numberOfDofs() const final { return _element_data->numberOfDofs(); }
177 172993515 : const std::vector<dof_id_type> & dofIndicesNeighbor() const final
178 : {
179 172993515 : return _neighbor_data->dofIndices();
180 : }
181 20156630 : const std::vector<dof_id_type> & dofIndicesLower() const final
182 : {
183 20156630 : return _lower_data->dofIndices();
184 : }
185 :
186 : void clearAllDofIndices() final;
187 :
188 0 : unsigned int numberOfDofsNeighbor() override { return _neighbor_data->dofIndices().size(); }
189 :
190 130982154 : const FieldVariablePhiValue & phi() const override { return _element_data->phi(); }
191 130928078 : const FieldVariablePhiGradient & gradPhi() const override final
192 : {
193 130928078 : return _element_data->gradPhi();
194 : }
195 1835 : const MappedArrayVariablePhiGradient & arrayGradPhi() const
196 : {
197 1835 : return _element_data->arrayGradPhi();
198 : }
199 : const FieldVariablePhiSecond & secondPhi() const override final;
200 : const FieldVariablePhiCurl & curlPhi() const override final;
201 : const FieldVariablePhiDivergence & divPhi() const override final;
202 :
203 789297 : const FieldVariablePhiValue & phiFace() const override final { return _element_data->phiFace(); }
204 763526 : const FieldVariablePhiGradient & gradPhiFace() const override final
205 : {
206 763526 : return _element_data->gradPhiFace();
207 : }
208 364 : const MappedArrayVariablePhiGradient & arrayGradPhiFace() const
209 : {
210 364 : return _element_data->arrayGradPhiFace();
211 : }
212 : const FieldVariablePhiSecond & secondPhiFace() const override final;
213 : const FieldVariablePhiCurl & curlPhiFace() const;
214 : const FieldVariablePhiDivergence & divPhiFace() const;
215 :
216 195014 : const FieldVariablePhiValue & phiNeighbor() const override final { return _neighbor_data->phi(); }
217 194930 : const FieldVariablePhiGradient & gradPhiNeighbor() const override final
218 : {
219 194930 : return _neighbor_data->gradPhi();
220 : }
221 0 : const MappedArrayVariablePhiGradient & arrayGradPhiNeighbor() const
222 : {
223 0 : return _neighbor_data->arrayGradPhi();
224 : }
225 : const FieldVariablePhiSecond & secondPhiNeighbor() const override final;
226 : const FieldVariablePhiCurl & curlPhiNeighbor() const;
227 : const FieldVariablePhiDivergence & divPhiNeighbor() const;
228 :
229 297141 : const FieldVariablePhiValue & phiFaceNeighbor() const override final
230 : {
231 297141 : return _neighbor_data->phiFace();
232 : }
233 291285 : const FieldVariablePhiGradient & gradPhiFaceNeighbor() const override final
234 : {
235 291285 : return _neighbor_data->gradPhiFace();
236 : }
237 364 : const MappedArrayVariablePhiGradient & arrayGradPhiFaceNeighbor() const
238 : {
239 364 : return _neighbor_data->arrayGradPhiFace();
240 : }
241 : const FieldVariablePhiSecond & secondPhiFaceNeighbor() const override final;
242 : const FieldVariablePhiCurl & curlPhiFaceNeighbor() const;
243 : const FieldVariablePhiDivergence & divPhiFaceNeighbor() const;
244 :
245 100648 : virtual const FieldVariablePhiValue & phiLower() const override { return _lower_data->phi(); }
246 92488 : const FieldVariablePhiGradient & gradPhiLower() const { return _lower_data->gradPhi(); }
247 :
248 4535 : const ADTemplateVariableTestGradient<OutputShape> & adGradPhi() const
249 : {
250 4535 : return _element_data->adGradPhi();
251 : }
252 :
253 1859 : const ADTemplateVariableTestGradient<OutputShape> & adGradPhiFace() const
254 : {
255 1859 : return _element_data->adGradPhiFace();
256 : }
257 :
258 0 : const ADTemplateVariableTestGradient<OutputShape> & adGradPhiFaceNeighbor() const
259 : {
260 0 : return _neighbor_data->adGradPhiFace();
261 : }
262 :
263 : // damping
264 151 : const FieldVariableValue & increment() const { return _element_data->increment(); }
265 :
266 607 : const FieldVariableValue & vectorTagValue(TagID tag) const override
267 : {
268 607 : return _element_data->vectorTagValue(tag);
269 : }
270 26 : const FieldVariableGradient & vectorTagGradient(TagID tag) const
271 : {
272 26 : return _element_data->vectorTagGradient(tag);
273 : }
274 13 : const DoFValue & vectorTagDofValue(TagID tag) const override
275 : {
276 13 : return _element_data->vectorTagDofValue(tag);
277 : }
278 13 : const FieldVariableValue & matrixTagValue(TagID tag) const override
279 : {
280 13 : return _element_data->matrixTagValue(tag);
281 : }
282 :
283 : /// element solutions
284 257312 : const FieldVariableValue & sln() const override { return _element_data->sln(Moose::Current); }
285 8657 : const FieldVariableValue & slnOld() const override { return _element_data->sln(Moose::Old); }
286 7384 : const FieldVariableValue & slnOlder() const override { return _element_data->sln(Moose::Older); }
287 78 : const FieldVariableValue & slnPreviousNL() const { return _element_data->sln(Moose::PreviousNL); }
288 :
289 : /// element gradients
290 118411 : const FieldVariableGradient & gradSln() const override
291 : {
292 118411 : return _element_data->gradSln(Moose::Current);
293 : }
294 933 : const FieldVariableGradient & gradSlnOld() const override
295 : {
296 933 : return _element_data->gradSln(Moose::Old);
297 : }
298 13 : const FieldVariableGradient & gradSlnOlder() const
299 : {
300 13 : return _element_data->gradSln(Moose::Older);
301 : }
302 0 : const FieldVariableGradient & gradSlnPreviousNL() const
303 : {
304 0 : return _element_data->gradSln(Moose::PreviousNL);
305 : }
306 :
307 : /// element gradient dots
308 37 : const FieldVariableGradient & gradSlnDot() const { return _element_data->gradSlnDot(); }
309 0 : const FieldVariableGradient & gradSlnDotDot() const { return _element_data->gradSlnDotDot(); }
310 :
311 : /// element seconds
312 148 : const FieldVariableSecond & secondSln() const { return _element_data->secondSln(Moose::Current); }
313 0 : const FieldVariableSecond & secondSlnOld() const { return _element_data->secondSln(Moose::Old); }
314 0 : const FieldVariableSecond & secondSlnOlder() const
315 : {
316 0 : return _element_data->secondSln(Moose::Older);
317 : }
318 0 : const FieldVariableSecond & secondSlnPreviousNL() const
319 : {
320 0 : return _element_data->secondSln(Moose::PreviousNL);
321 : }
322 :
323 : /// element curls
324 159 : const FieldVariableCurl & curlSln() const { return _element_data->curlSln(Moose::Current); }
325 0 : const FieldVariableCurl & curlSlnOld() const { return _element_data->curlSln(Moose::Old); }
326 0 : const FieldVariableCurl & curlSlnOlder() const { return _element_data->curlSln(Moose::Older); }
327 :
328 : /// element divergence
329 312 : const FieldVariableDivergence & divSln() const { return _element_data->divSln(Moose::Current); }
330 0 : const FieldVariableDivergence & divSlnOld() const { return _element_data->divSln(Moose::Old); }
331 0 : const FieldVariableDivergence & divSlnOlder() const
332 : {
333 0 : return _element_data->divSln(Moose::Older);
334 : }
335 :
336 : /// AD
337 12098 : const ADTemplateVariableValue<OutputType> & adSln() const override
338 : {
339 12098 : return _element_data->adSln();
340 : }
341 :
342 8715 : const ADTemplateVariableGradient<OutputType> & adGradSln() const override
343 : {
344 8715 : return _element_data->adGradSln();
345 : }
346 0 : const ADTemplateVariableSecond<OutputType> & adSecondSln() const override
347 : {
348 0 : return _element_data->adSecondSln();
349 : }
350 499 : const ADTemplateVariableValue<OutputType> & adUDot() const override
351 : {
352 499 : return _element_data->adUDot();
353 : }
354 39 : const ADTemplateVariableValue<OutputType> & adUDotDot() const override
355 : {
356 39 : return _element_data->adUDotDot();
357 : }
358 0 : const ADTemplateVariableGradient<OutputType> & adGradSlnDot() const override
359 : {
360 0 : return _element_data->adGradSlnDot();
361 : }
362 50 : const ADTemplateVariableCurl<OutputType> & adCurlSln() const override
363 : {
364 50 : return _element_data->adCurlSln();
365 : }
366 :
367 : /// neighbor AD
368 2036 : const ADTemplateVariableValue<OutputType> & adSlnNeighbor() const override
369 : {
370 2036 : return _neighbor_data->adSln();
371 : }
372 1057 : const ADTemplateVariableGradient<OutputType> & adGradSlnNeighbor() const override
373 : {
374 1057 : return _neighbor_data->adGradSln();
375 : }
376 0 : const ADTemplateVariableSecond<OutputType> & adSecondSlnNeighbor() const override
377 : {
378 0 : return _neighbor_data->adSecondSln();
379 : }
380 13 : const ADTemplateVariableValue<OutputType> & adUDotNeighbor() const override
381 : {
382 13 : return _neighbor_data->adUDot();
383 : }
384 13 : const ADTemplateVariableValue<OutputType> & adUDotDotNeighbor() const override
385 : {
386 13 : return _neighbor_data->adUDotDot();
387 : }
388 0 : const ADTemplateVariableGradient<OutputType> & adGradSlnNeighborDot() const override
389 : {
390 0 : return _neighbor_data->adGradSlnDot();
391 : }
392 0 : const ADTemplateVariableCurl<OutputType> & adCurlSlnNeighbor() const override
393 : {
394 0 : return _neighbor_data->adCurlSln();
395 : }
396 :
397 : /// element dots
398 15830 : const FieldVariableValue & uDot() const { return _element_data->uDot(); }
399 165 : const FieldVariableValue & uDotDot() const { return _element_data->uDotDot(); }
400 0 : const FieldVariableValue & uDotOld() const { return _element_data->uDotOld(); }
401 0 : const FieldVariableValue & uDotDotOld() const { return _element_data->uDotDotOld(); }
402 15752 : const VariableValue & duDotDu() const { return _element_data->duDotDu(); }
403 104 : const VariableValue & duDotDotDu() const { return _element_data->duDotDotDu(); }
404 :
405 : /// neighbor solutions
406 6194 : const FieldVariableValue & slnNeighbor() const override
407 : {
408 6194 : return _neighbor_data->sln(Moose::Current);
409 : }
410 3847 : const FieldVariableValue & slnOldNeighbor() const override
411 : {
412 3847 : return _neighbor_data->sln(Moose::Old);
413 : }
414 3705 : const FieldVariableValue & slnOlderNeighbor() const { return _neighbor_data->sln(Moose::Older); }
415 0 : const FieldVariableValue & slnPreviousNLNeighbor() const
416 : {
417 0 : return _neighbor_data->sln(Moose::PreviousNL);
418 : }
419 :
420 : /// neighbor solution gradients
421 3904 : const FieldVariableGradient & gradSlnNeighbor() const override
422 : {
423 3904 : return _neighbor_data->gradSln(Moose::Current);
424 : }
425 13 : const FieldVariableGradient & gradSlnOldNeighbor() const override
426 : {
427 13 : return _neighbor_data->gradSln(Moose::Old);
428 : }
429 0 : const FieldVariableGradient & gradSlnOlderNeighbor() const
430 : {
431 0 : return _neighbor_data->gradSln(Moose::Older);
432 : }
433 0 : const FieldVariableGradient & gradSlnPreviousNLNeighbor() const
434 : {
435 0 : return _neighbor_data->gradSln(Moose::PreviousNL);
436 : }
437 :
438 : /// neighbor grad dots
439 0 : const FieldVariableGradient & gradSlnNeighborDot() const { return _neighbor_data->gradSlnDot(); }
440 0 : const FieldVariableGradient & gradSlnNeighborDotDot() const
441 : {
442 0 : return _neighbor_data->gradSlnDotDot();
443 : }
444 :
445 : /// neighbor solution seconds
446 39 : const FieldVariableSecond & secondSlnNeighbor() const
447 : {
448 39 : return _neighbor_data->secondSln(Moose::Current);
449 : }
450 0 : const FieldVariableSecond & secondSlnOldNeighbor() const
451 : {
452 0 : return _neighbor_data->secondSln(Moose::Old);
453 : }
454 0 : const FieldVariableSecond & secondSlnOlderNeighbor() const
455 : {
456 0 : return _neighbor_data->secondSln(Moose::Older);
457 : }
458 0 : const FieldVariableSecond & secondSlnPreviousNLNeighbor() const
459 : {
460 0 : return _neighbor_data->secondSln(Moose::PreviousNL);
461 : }
462 :
463 : /// neighbor solution curls
464 0 : const FieldVariableCurl & curlSlnNeighbor() const
465 : {
466 0 : return _neighbor_data->curlSln(Moose::Current);
467 : }
468 0 : const FieldVariableCurl & curlSlnOldNeighbor() const
469 : {
470 0 : return _neighbor_data->curlSln(Moose::Old);
471 : }
472 0 : const FieldVariableCurl & curlSlnOlderNeighbor() const
473 : {
474 0 : return _neighbor_data->curlSln(Moose::Older);
475 : }
476 :
477 : /// neighbor solution divergence
478 0 : const FieldVariableDivergence & divSlnNeighbor() const
479 : {
480 0 : return _neighbor_data->divSln(Moose::Current);
481 : }
482 0 : const FieldVariableDivergence & divSlnOldNeighbor() const
483 : {
484 0 : return _neighbor_data->divSln(Moose::Old);
485 : }
486 0 : const FieldVariableDivergence & divSlnOlderNeighbor() const
487 : {
488 0 : return _neighbor_data->divSln(Moose::Older);
489 : }
490 :
491 : /// neighbor dots
492 135 : const FieldVariableValue & uDotNeighbor() const { return _neighbor_data->uDot(); }
493 39 : const FieldVariableValue & uDotDotNeighbor() const { return _neighbor_data->uDotDot(); }
494 0 : const FieldVariableValue & uDotOldNeighbor() const { return _neighbor_data->uDotOld(); }
495 0 : const FieldVariableValue & uDotDotOldNeighbor() const { return _neighbor_data->uDotDotOld(); }
496 124 : const VariableValue & duDotDuNeighbor() const { return _neighbor_data->duDotDu(); }
497 52 : const VariableValue & duDotDotDuNeighbor() const { return _neighbor_data->duDotDotDu(); }
498 :
499 : /// lower-d element solution
500 649 : const ADTemplateVariableValue<OutputType> & adSlnLower() const { return _lower_data->adSln(); }
501 577 : const FieldVariableValue & slnLower() const { return _lower_data->sln(Moose::Current); }
502 0 : const FieldVariableValue & slnLowerOld() const { return _lower_data->sln(Moose::Old); }
503 :
504 : /// Actually compute variable values from the solution vectors
505 : virtual void computeElemValues() override;
506 : virtual void computeElemValuesFace() override;
507 : virtual void computeNeighborValuesFace() override;
508 : virtual void computeNeighborValues() override;
509 : virtual void computeLowerDValues() override;
510 :
511 : virtual void setNodalValue(const OutputType & value, unsigned int idx = 0) override;
512 :
513 : virtual void setDofValue(const OutputData & value, unsigned int index) override;
514 :
515 : /**
516 : * Set local DOF values and evaluate the values on quadrature points
517 : */
518 : virtual void setDofValues(const DenseVector<OutputData> & values) override;
519 : virtual void setLowerDofValues(const DenseVector<OutputData> & values) override;
520 :
521 : /**
522 : * Write a nodal value to the passed-in solution vector
523 : */
524 : void insertNodalValue(libMesh::NumericVector<libMesh::Number> & residual, const OutputData & v);
525 :
526 : /**
527 : * Get the value of this variable at given node
528 : */
529 : OutputData getNodalValue(const Node & node) const;
530 : /**
531 : * Get the old value of this variable at given node
532 : */
533 : OutputData getNodalValueOld(const Node & node) const;
534 : /**
535 : * Get the t-2 value of this variable at given node
536 : */
537 : OutputData getNodalValueOlder(const Node & node) const;
538 : /**
539 : * Get the current value of this variable on an element
540 : * @param[in] elem Element at which to get value
541 : * @param[in] idx Local index of this variable's element DoFs
542 : * @return Variable value
543 : */
544 : OutputData getElementalValue(const Elem * elem, unsigned int idx = 0) const;
545 : /**
546 : * Get the old value of this variable on an element
547 : * @param[in] elem Element at which to get value
548 : * @param[in] idx Local index of this variable's element DoFs
549 : * @return Variable value
550 : */
551 : OutputData getElementalValueOld(const Elem * elem, unsigned int idx = 0) const;
552 : /**
553 : * Get the older value of this variable on an element
554 : * @param[in] elem Element at which to get value
555 : * @param[in] idx Local index of this variable's element DoFs
556 : * @return Variable value
557 : */
558 : OutputData getElementalValueOlder(const Elem * elem, unsigned int idx = 0) const;
559 :
560 : /**
561 : * Set the current local DOF values to the input vector
562 : */
563 : virtual void insert(libMesh::NumericVector<libMesh::Number> & vector) override;
564 : virtual void insertLower(libMesh::NumericVector<libMesh::Number> & vector) override;
565 :
566 : /**
567 : * Add the current local DOF values to the input vector
568 : */
569 : virtual void add(libMesh::NumericVector<libMesh::Number> & vector) override;
570 :
571 : /**
572 : * Add passed in local DOF values onto the current solution
573 : */
574 : void addSolution(const DenseVector<libMesh::Number> & v);
575 :
576 : /**
577 : * Add passed in local neighbor DOF values onto the current solution
578 : */
579 : void addSolutionNeighbor(const DenseVector<libMesh::Number> & v);
580 :
581 : const DoFValue & dofValue() const;
582 : const DoFValue & dofValues() const override;
583 : const DoFValue & dofValuesOld() const override;
584 : const DoFValue & dofValuesOlder() const override;
585 : const DoFValue & dofValuesPreviousNL() const override;
586 : const DoFValue & dofValuesNeighbor() const override;
587 : const DoFValue & dofValuesOldNeighbor() const override;
588 : const DoFValue & dofValuesOlderNeighbor() const override;
589 : const DoFValue & dofValuesPreviousNLNeighbor() const override;
590 : const DoFValue & dofValuesDot() const override;
591 : const DoFValue & dofValuesDotNeighbor() const override;
592 : const DoFValue & dofValuesDotNeighborResidual() const;
593 : const DoFValue & dofValuesDotOld() const override;
594 : const DoFValue & dofValuesDotOldNeighbor() const override;
595 : const DoFValue & dofValuesDotDot() const override;
596 : const DoFValue & dofValuesDotDotNeighbor() const override;
597 : const DoFValue & dofValuesDotDotNeighborResidual() const;
598 : const DoFValue & dofValuesDotDotOld() const override;
599 : const DoFValue & dofValuesDotDotOldNeighbor() const override;
600 : const MooseArray<libMesh::Number> & dofValuesDuDotDu() const override;
601 : const MooseArray<libMesh::Number> & dofValuesDuDotDuNeighbor() const override;
602 : const MooseArray<libMesh::Number> & dofValuesDuDotDotDu() const override;
603 : const MooseArray<libMesh::Number> & dofValuesDuDotDotDuNeighbor() const override;
604 :
605 : const MooseArray<ADReal> & adDofValues() const override;
606 : const MooseArray<ADReal> & adDofValuesNeighbor() const override;
607 : const MooseArray<ADReal> & adDofValuesDot() const override;
608 :
609 : /**
610 : * Compute and store incremental change in solution at QPs based on increment_vec
611 : */
612 : void computeIncrementAtQps(const libMesh::NumericVector<libMesh::Number> & increment_vec);
613 :
614 : /**
615 : * Compute and store incremental change at the current node based on increment_vec
616 : */
617 : void computeIncrementAtNode(const libMesh::NumericVector<libMesh::Number> & increment_vec);
618 :
619 : /**
620 : * Compute the variable value at a point on an element
621 : * @param elem The element we are computing on
622 : * @param phi Evaluated shape functions at a point
623 : * @return The variable value
624 : */
625 : OutputType getValue(const Elem * elem, const std::vector<std::vector<OutputShape>> & phi) const;
626 :
627 : /**
628 : * Compute the variable gradient value at a point on an element
629 : * @param elem The element we are computing on
630 : * @param phi Evaluated shape functions at a point
631 : * @return The variable gradient value
632 : */
633 : typename OutputTools<OutputType>::OutputGradient getGradient(
634 : const Elem * elem,
635 : const std::vector<std::vector<typename OutputTools<OutputType>::OutputShapeGradient>> &
636 : grad_phi) const;
637 :
638 : /**
639 : * Return phi size
640 : */
641 473312 : virtual std::size_t phiSize() const final { return _element_data->phiSize(); }
642 : /**
643 : * Return phiFace size
644 : */
645 0 : virtual std::size_t phiFaceSize() const final { return _element_data->phiFaceSize(); }
646 : /**
647 : * Return phiNeighbor size
648 : */
649 0 : virtual std::size_t phiNeighborSize() const final { return _neighbor_data->phiSize(); }
650 : /**
651 : * Return phiFaceNeighbor size
652 : */
653 0 : virtual std::size_t phiFaceNeighborSize() const final { return _neighbor_data->phiFaceSize(); }
654 :
655 0 : std::size_t phiLowerSize() const final { return _lower_data->phiSize(); }
656 :
657 : /**
658 : * Methods for retrieving values of variables at the nodes
659 : */
660 : const OutputType & nodalValue() const;
661 : const OutputType & nodalValueOld() const;
662 : const OutputType & nodalValueOlder() const;
663 : const OutputType & nodalValuePreviousNL() const;
664 : const OutputType & nodalValueDot() const;
665 : const OutputType & nodalValueDotDot() const;
666 : const OutputType & nodalValueDotOld() const;
667 : const OutputType & nodalValueDotDotOld() const;
668 : const OutputType & nodalValueDuDotDu() const;
669 : const OutputType & nodalValueDuDotDotDu() const;
670 : const OutputType & nodalValueNeighbor() const;
671 : const OutputType & nodalValueOldNeighbor() const;
672 : const OutputType & nodalValueOlderNeighbor() const;
673 : const OutputType & nodalValuePreviousNLNeighbor() const;
674 : const OutputType & nodalValueDotNeighbor() const;
675 : const OutputType & nodalValueDotNeighborResidual() const;
676 : const OutputType & nodalValueDotDotNeighbor() const;
677 : const OutputType & nodalValueDotDotNeighborResidual() const;
678 : const OutputType & nodalValueDotOldNeighbor() const;
679 : const OutputType & nodalValueDotDotOldNeighbor() const;
680 : const OutputType & nodalValueDuDotDuNeighbor() const;
681 : const OutputType & nodalValueDuDotDotDuNeighbor() const;
682 :
683 22085 : const MooseArray<OutputType> & nodalValueArray() const override
684 : {
685 22085 : return _element_data->nodalValueArray(Moose::Current);
686 : }
687 130 : const MooseArray<OutputType> & nodalValueOldArray() const override
688 : {
689 130 : return _element_data->nodalValueArray(Moose::Old);
690 : }
691 13 : const MooseArray<OutputType> & nodalValueOlderArray() const override
692 : {
693 13 : return _element_data->nodalValueArray(Moose::Older);
694 : }
695 :
696 : const DoFValue & nodalVectorTagValue(TagID tag) const override;
697 : const DoFValue & nodalMatrixTagValue(TagID tag) const override;
698 :
699 : const typename Moose::ADType<OutputType>::type & adNodalValue() const;
700 :
701 : virtual void computeNodalValues() override;
702 : virtual void computeNodalNeighborValues() override;
703 :
704 : unsigned int oldestSolutionStateRequested() const override final;
705 :
706 : void setActiveTags(const std::set<TagID> & vtags) override;
707 :
708 : virtual void meshChanged() override;
709 : virtual void residualSetup() override;
710 : virtual void jacobianSetup() override;
711 :
712 0 : bool supportsFaceArg() const override final { return true; }
713 0 : bool supportsElemSideQpArg() const override final { return true; }
714 :
715 : protected:
716 : usingMooseVariableFieldMembers;
717 :
718 : /// Holder for all the data associated with the "main" element
719 : std::unique_ptr<MooseVariableData<OutputType>> _element_data;
720 :
721 : /// Holder for all the data associated with the neighbor element
722 : std::unique_ptr<MooseVariableData<OutputType>> _neighbor_data;
723 :
724 : /// Holder for all the data associated with the lower dimeensional element
725 : std::unique_ptr<MooseVariableData<OutputType>> _lower_data;
726 :
727 : using MooseVariableField<OutputType>::evaluate;
728 : using MooseVariableField<OutputType>::evaluateGradient;
729 : using MooseVariableField<OutputType>::evaluateDot;
730 : using MooseVariableField<OutputType>::evaluateGradDot;
731 : using ElemArg = Moose::ElemArg;
732 : using ElemQpArg = Moose::ElemQpArg;
733 : using ElemSideQpArg = Moose::ElemSideQpArg;
734 : using FaceArg = Moose::FaceArg;
735 : using StateArg = Moose::StateArg;
736 : using NodeArg = Moose::NodeArg;
737 : using ElemPointArg = Moose::ElemPointArg;
738 :
739 : /**
740 : * A common method that both evaluate(FaceArg) and evaluateDot(FaceArg) can call. A value
741 : * evaluation vs dot evaluation is delineated via the passed-in \p cache_data, e.g. if the
742 : * passed-in cache data is the sln data member then this will return a value evaluation and if the
743 : * cache data is the dot data member then this will return a dot evaluation
744 : */
745 : ValueType
746 : faceEvaluate(const FaceArg &, const StateArg &, const std::vector<ValueType> & cache_data) const;
747 :
748 : ValueType evaluate(const ElemQpArg & elem_qp, const StateArg & state) const override final;
749 : ValueType evaluate(const ElemSideQpArg & elem_side_qp,
750 : const StateArg & state) const override final;
751 : ValueType evaluate(const ElemArg &, const StateArg &) const override final;
752 : ValueType evaluate(const ElemPointArg &, const StateArg &) const override final;
753 : ValueType evaluate(const NodeArg & node_arg, const StateArg & state) const override final;
754 : ValueType evaluate(const FaceArg &, const StateArg &) const override final;
755 :
756 : GradientType evaluateGradient(const ElemQpArg & elem_qp, const StateArg & state) const override;
757 : GradientType evaluateGradient(const ElemSideQpArg & elem_side_qp,
758 : const StateArg & state) const override final;
759 : GradientType evaluateGradient(const ElemArg &, const StateArg &) const override final;
760 :
761 : DotType evaluateDot(const ElemQpArg & elem_qp, const StateArg & state) const override final;
762 : DotType evaluateDot(const ElemSideQpArg & elem_side_qp,
763 : const StateArg & state) const override final;
764 : DotType evaluateDot(const ElemArg &, const StateArg &) const override final;
765 : DotType evaluateDot(const FaceArg &, const StateArg &) const override final;
766 :
767 : GradientType evaluateGradDot(const ElemArg &, const StateArg &) const override final;
768 :
769 : private:
770 : /**
771 : * Compute the solution, gradient, time derivative, and gradient of the time derivative with
772 : * provided shape functions
773 : */
774 : template <typename Shapes, typename Solution, typename GradShapes, typename GradSolution>
775 : void computeSolution(const Elem * elem,
776 : unsigned int n_qp,
777 : const StateArg & state,
778 : const Shapes & phi,
779 : Solution & local_soln,
780 : const GradShapes & grad_phi,
781 : GradSolution & grad_local_soln,
782 : Solution & dot_local_soln,
783 : GradSolution & grad_dot_local_soln) const;
784 :
785 : /**
786 : * Evaluate solution and gradient for the \p elem_qp argument
787 : */
788 : void
789 : evaluateOnElement(const ElemQpArg & elem_qp, const StateArg & state, bool cache_eligible) const;
790 :
791 : /**
792 : * Evaluate solution and gradient for the \p elem_side_qp argument
793 : */
794 : void evaluateOnElementSide(const ElemSideQpArg & elem_side_qp,
795 : const StateArg & state,
796 : bool cache_eligible) const;
797 :
798 : /// Keep track of the current elem-qp functor element in order to enable local caching (e.g. if we
799 : /// call evaluate on the same element, but just with a different quadrature point, we can return
800 : /// previously computed results indexed at the different qp
801 : mutable const Elem * _current_elem_qp_functor_elem = nullptr;
802 :
803 : /// The values of the solution for the \p _current_elem_qp_functor_elem
804 : mutable std::vector<ValueType> _current_elem_qp_functor_sln;
805 :
806 : /// The values of the gradient for the \p _current_elem_qp_functor_elem
807 : mutable std::vector<GradientType> _current_elem_qp_functor_gradient;
808 :
809 : /// The values of the time derivative for the \p _current_elem_qp_functor_elem
810 : mutable std::vector<DotType> _current_elem_qp_functor_dot;
811 :
812 : /// The values of the gradient of the time derivative for the \p _current_elem_qp_functor_elem
813 : mutable std::vector<GradientType> _current_elem_qp_functor_grad_dot;
814 :
815 : /// Keep track of the current elem-side-qp functor element and side in order to enable local
816 : /// caching (e.g. if we call evaluate with the same element and side, but just with a different
817 : /// quadrature point, we can return previously computed results indexed at the different qp
818 : mutable std::pair<const Elem *, unsigned int> _current_elem_side_qp_functor_elem_side{
819 : nullptr, libMesh::invalid_uint};
820 :
821 : /// The values of the solution for the \p _current_elem_side_qp_functor_elem_side
822 : mutable std::vector<ValueType> _current_elem_side_qp_functor_sln;
823 :
824 : /// The values of the gradient for the \p _current_elem_side_qp_functor_elem_side
825 : mutable std::vector<GradientType> _current_elem_side_qp_functor_gradient;
826 :
827 : /// The values of the time derivative for the \p _current_elem_side_qp_functor_elem_side
828 : mutable std::vector<DotType> _current_elem_side_qp_functor_dot;
829 :
830 : /// The values of the gradient of the time derivative for the \p
831 : /// _current_elem_side_qp_functor_elem_side
832 : mutable std::vector<GradientType> _current_elem_side_qp_functor_grad_dot;
833 : };
834 :
835 : template <typename OutputType>
836 : inline const MooseArray<ADReal> &
837 362 : MooseVariableFE<OutputType>::adDofValues() const
838 : {
839 362 : return _element_data->adDofValues();
840 : }
841 :
842 : template <typename OutputType>
843 : inline const MooseArray<ADReal> &
844 0 : MooseVariableFE<OutputType>::adDofValuesNeighbor() const
845 : {
846 0 : return _neighbor_data->adDofValues();
847 : }
848 :
849 : template <typename OutputType>
850 : inline const MooseArray<ADReal> &
851 13 : MooseVariableFE<OutputType>::adDofValuesDot() const
852 : {
853 13 : return _element_data->adDofValuesDot();
854 : }
855 :
856 : template <typename OutputType>
857 : inline const typename Moose::ADType<OutputType>::type &
858 1770 : MooseVariableFE<OutputType>::adNodalValue() const
859 : {
860 1770 : return _element_data->adNodalValue();
861 : }
862 :
863 : template <typename OutputType>
864 : void
865 17438256 : MooseVariableFE<OutputType>::setActiveTags(const std::set<TagID> & vtags)
866 : {
867 17438256 : _element_data->setActiveTags(vtags);
868 17438256 : _neighbor_data->setActiveTags(vtags);
869 17438256 : _lower_data->setActiveTags(vtags);
870 17438256 : }
871 :
872 : // Declare all the specializations, as the template specialization declarations below must know
873 : template <>
874 : InputParameters MooseVariableFE<Real>::validParams();
875 : template <>
876 : InputParameters MooseVariableFE<RealVectorValue>::validParams();
877 : template <>
878 : InputParameters MooseVariableFE<RealEigenVector>::validParams();
879 : template <>
880 : RealEigenVector
881 : MooseVariableFE<RealEigenVector>::getValue(const Elem * elem,
882 : const std::vector<std::vector<Real>> & phi) const;
883 : template <>
884 : RealVectorArrayValue MooseVariableFE<RealEigenVector>::getGradient(
885 : const Elem * elem, const std::vector<std::vector<RealVectorValue>> & grad_phi) const;
886 : template <>
887 : void MooseVariableFE<RealEigenVector>::evaluateOnElement(const ElemQpArg &,
888 : const StateArg &,
889 : bool) const;
890 : template <>
891 : void MooseVariableFE<RealEigenVector>::evaluateOnElementSide(const ElemSideQpArg &,
892 : const StateArg &,
893 : bool) const;
894 : template <>
895 : typename MooseVariableFE<RealEigenVector>::ValueType
896 : MooseVariableFE<RealEigenVector>::evaluate(const ElemQpArg &, const StateArg &) const;
897 : template <>
898 : typename MooseVariableFE<RealEigenVector>::ValueType
899 : MooseVariableFE<RealEigenVector>::evaluate(const ElemSideQpArg &, const StateArg &) const;
900 : template <>
901 : typename MooseVariableFE<RealEigenVector>::GradientType
902 : MooseVariableFE<RealEigenVector>::evaluateGradient(const ElemQpArg &, const StateArg &) const;
903 : template <>
904 : typename MooseVariableFE<RealEigenVector>::GradientType
905 : MooseVariableFE<RealEigenVector>::evaluateGradient(const ElemSideQpArg &, const StateArg &) const;
906 : template <>
907 : typename MooseVariableFE<RealEigenVector>::DotType
908 : MooseVariableFE<RealEigenVector>::evaluateDot(const ElemQpArg &, const StateArg &) const;
909 : template <>
910 : typename MooseVariableFE<RealEigenVector>::DotType
911 : MooseVariableFE<RealEigenVector>::evaluateDot(const ElemSideQpArg &, const StateArg &) const;
912 :
913 : // Prevent implicit instantiation in other translation units where these classes are used
914 : extern template class MooseVariableFE<Real>;
915 : extern template class MooseVariableFE<RealVectorValue>;
916 : extern template class MooseVariableFE<RealEigenVector>;
|