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