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