Line data Source code
1 : //* This file is part of the MOOSE framework
2 : //* https://www.mooseframework.org
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 "KokkosDatum.h"
13 :
14 : #include "MooseError.h"
15 : #include "MooseVariableFieldBase.h"
16 : #include "SystemBase.h"
17 :
18 : namespace Moose::Kokkos
19 : {
20 :
21 : inline void
22 17750 : checkVariable(const Variable & var, bool expect_vector, const std::string & wrapper_name)
23 : {
24 17750 : if (!var.initialized())
25 0 : mooseError("Attempted to construct Kokkos ", wrapper_name, " with an uninitialized variable.");
26 :
27 17750 : if (var.vector() != expect_vector)
28 0 : mooseError("Kokkos ",
29 : wrapper_name,
30 : " cannot be constructed with ",
31 0 : var.vector() ? "vector" : "scalar",
32 : " variables.");
33 17750 : }
34 :
35 : /**
36 : * The Kokkos wrapper classes for MOOSE-like shape function access
37 : */
38 : ///@{
39 : template <bool is_test>
40 : class VariableShapeValue
41 : {
42 : public:
43 : /**
44 : * Get the current shape function
45 : * @param datum The AssemblyDatum object of the current thread
46 : * @param i The element-local DOF index
47 : * @param qp The local quadrature point index
48 : * @returns The shape function
49 : */
50 119035616 : KOKKOS_FUNCTION Real operator()(AssemblyDatum & datum, unsigned int i, unsigned int qp) const
51 : {
52 119035616 : auto & elem = datum.elem();
53 119035616 : auto side = datum.side();
54 119035616 : auto fe = is_test ? datum.ife() : datum.jfe();
55 :
56 0 : return side == libMesh::invalid_uint
57 119035616 : ? datum.assembly().getPhi(elem.subdomain, elem.type, fe)(i, qp)
58 119035616 : : datum.assembly().getPhiFace(elem.subdomain, elem.type, fe)(side)(i, qp);
59 : }
60 : };
61 :
62 : template <bool is_test>
63 : class VariableShapeGradient
64 : {
65 : public:
66 : /**
67 : * Get the gradient of the current shape function in reference space
68 : * @param datum The AssemblyDatum object of the current thread
69 : * @param i The element-local DOF index
70 : * @param qp The local quadrature point index
71 : * @returns The reference-space gradient of the shape function
72 : */
73 : KOKKOS_FUNCTION const Real3 &
74 : reference(AssemblyDatum & datum, unsigned int i, unsigned int qp) const;
75 :
76 : /**
77 : * Get the gradient of the current shape function
78 : * @param datum The AssemblyDatum object of the current thread
79 : * @param i The element-local DOF index
80 : * @param qp The local quadrature point index
81 : * @returns The gradient of the shape function
82 : */
83 98124900 : KOKKOS_FUNCTION Real3 operator()(AssemblyDatum & datum, unsigned int i, unsigned int qp) const
84 : {
85 98124900 : return datum.J(qp) * reference(datum, i, qp);
86 : }
87 : };
88 :
89 : template <bool is_test>
90 : KOKKOS_FUNCTION const Real3 &
91 98127972 : VariableShapeGradient<is_test>::reference(AssemblyDatum & datum,
92 : unsigned int i,
93 : unsigned int qp) const
94 : {
95 98127972 : auto & elem = datum.elem();
96 98127972 : auto side = datum.side();
97 98127972 : auto fe = is_test ? datum.ife() : datum.jfe();
98 :
99 0 : return side == libMesh::invalid_uint
100 98127972 : ? datum.assembly().getGradPhi(elem.subdomain, elem.type, fe)(i, qp)
101 196255944 : : datum.assembly().getGradPhiFace(elem.subdomain, elem.type, fe)(side)(i, qp);
102 : }
103 :
104 : using VariablePhiValue = VariableShapeValue<false>;
105 : using VariablePhiGradient = VariableShapeGradient<false>;
106 : using VariableTestValue = VariableShapeValue<true>;
107 : using VariableTestGradient = VariableShapeGradient<true>;
108 : using ADVariablePhiValue = VariablePhiValue;
109 : using ADVariablePhiGradient = VariablePhiGradient;
110 : using ADVariableTestValue = VariableTestValue;
111 : using ADVariableTestGradient = VariableTestGradient;
112 :
113 : template <bool is_test>
114 : class VectorVariableShapeValue
115 : {
116 : public:
117 : /**
118 : * Get the current vector shape function
119 : * @param datum The AssemblyDatum object of the current thread
120 : * @param i The element-local DOF index
121 : * @param qp The local quadrature point index
122 : * @returns The vector shape function
123 : */
124 31071704 : KOKKOS_FUNCTION Real3 operator()(AssemblyDatum & datum, unsigned int i, unsigned int qp) const
125 : {
126 31071704 : auto & elem = datum.elem();
127 31071704 : auto side = datum.side();
128 31071704 : auto fe = is_test ? datum.ife() : datum.jfe();
129 :
130 0 : return side == libMesh::invalid_uint
131 31071704 : ? datum.assembly().getVectorPhi(elem.subdomain, elem.type, fe)(i, qp)
132 31071704 : : datum.assembly().getVectorPhiFace(elem.subdomain, elem.type, fe)(side)(i, qp);
133 : }
134 : };
135 :
136 : template <bool is_test>
137 : class VectorVariableShapeGradient
138 : {
139 : public:
140 : /**
141 : * Get the gradient of the current vector shape function in reference space
142 : * @param datum The AssemblyDatum object of the current thread
143 : * @param i The element-local DOF index
144 : * @param qp The local quadrature point index
145 : * @returns The reference-space gradient of the vector shape function
146 : */
147 : KOKKOS_FUNCTION const Real33 &
148 : reference(AssemblyDatum & datum, unsigned int i, unsigned int qp) const;
149 :
150 : /**
151 : * Get the gradient of the current vector shape function
152 : * @param datum The AssemblyDatum object of the current thread
153 : * @param i The element-local DOF index
154 : * @param qp The local quadrature point index
155 : * @returns The gradient of the vector shape function
156 : */
157 4205016 : KOKKOS_FUNCTION Real33 operator()(AssemblyDatum & datum, unsigned int i, unsigned int qp) const
158 : {
159 4205016 : return reference(datum, i, qp) * datum.J(qp).transpose();
160 : }
161 : };
162 :
163 : template <bool is_test>
164 : KOKKOS_FUNCTION const Real33 &
165 39218080 : VectorVariableShapeGradient<is_test>::reference(AssemblyDatum & datum,
166 : unsigned int i,
167 : unsigned int qp) const
168 : {
169 39218080 : auto & elem = datum.elem();
170 39218080 : auto side = datum.side();
171 39218080 : auto fe = is_test ? datum.ife() : datum.jfe();
172 :
173 0 : return side == libMesh::invalid_uint
174 39218080 : ? datum.assembly().getVectorGradPhi(elem.subdomain, elem.type, fe)(i, qp)
175 78436160 : : datum.assembly().getVectorGradPhiFace(elem.subdomain, elem.type, fe)(side)(i, qp);
176 : }
177 :
178 : template <bool is_test>
179 : class VectorVariableShapeCurl
180 : {
181 : public:
182 : /**
183 : * Get the curl of the current vector shape function
184 : * @param datum The AssemblyDatum object of the current thread
185 : * @param i The element-local DOF index
186 : * @param qp The local quadrature point index
187 : * @returns The curl of the vector shape function
188 : */
189 5456896 : KOKKOS_FUNCTION Real3 operator()(AssemblyDatum & datum, unsigned int i, unsigned int qp) const
190 : {
191 5456896 : auto & elem = datum.elem();
192 5456896 : auto side = datum.side();
193 5456896 : auto fe = is_test ? datum.ife() : datum.jfe();
194 :
195 5456896 : auto grad =
196 : side == libMesh::invalid_uint
197 5456896 : ? datum.assembly().getVectorGradPhi(elem.subdomain, elem.type, fe)(i, qp)
198 0 : : datum.assembly().getVectorGradPhiFace(elem.subdomain, elem.type, fe)(side)(i, qp);
199 :
200 10913792 : return curlFromVectorGradient(grad * datum.J(qp).transpose(), datum.assembly().getDimension());
201 : }
202 : };
203 :
204 : using VectorVariablePhiValue = VectorVariableShapeValue<false>;
205 : using VectorVariablePhiGradient = VectorVariableShapeGradient<false>;
206 : using VectorVariablePhiCurl = VectorVariableShapeCurl<false>;
207 : using VectorVariableTestValue = VectorVariableShapeValue<true>;
208 : using VectorVariableTestGradient = VectorVariableShapeGradient<true>;
209 : using VectorVariableTestCurl = VectorVariableShapeCurl<true>;
210 : ///@}
211 :
212 : /**
213 : * The Kokkos wrapper classes for MOOSE-like variable value access
214 : */
215 : ///@{
216 : template <bool is_ad>
217 : class VariableValueTempl
218 : {
219 : using real_type = std::conditional_t<is_ad, ADReal, Real>;
220 :
221 : public:
222 : /**
223 : * Default constructor
224 : */
225 8867 : VariableValueTempl() = default;
226 : /**
227 : * Constructor
228 : * @param var The Kokkos variable
229 : * @param dof Whether to get DOF values
230 : */
231 2898 : VariableValueTempl(Variable var, bool dof = false) : _var(var), _dof(dof)
232 : {
233 2898 : checkVariable(_var, false, is_ad ? "ADVariableValue" : "VariableValue");
234 2898 : }
235 : /**
236 : * Constructor
237 : * @param var The MOOSE variable
238 : * @param tag The vector tag name
239 : * @param dof Whether to get DOF values
240 : */
241 9232 : VariableValueTempl(const MooseVariableFieldBase & var,
242 : const TagName & tag = Moose::SOLUTION_TAG,
243 4214 : bool dof = false)
244 5018 : : _var(var, tag), _dof(dof)
245 : {
246 9232 : checkVariable(_var, false, is_ad ? "ADVariableValue" : "VariableValue");
247 9232 : }
248 : /**
249 : * Constructor
250 : * @param vars The MOOSE variables
251 : * @param tag The vector tag name
252 : * @param dof Whether to get DOF values
253 : */
254 : ///@{
255 : VariableValueTempl(const std::vector<const MooseVariableFieldBase *> & vars,
256 : const TagName & tag = Moose::SOLUTION_TAG,
257 : bool dof = false)
258 : : _var(vars, tag), _dof(dof)
259 : {
260 : checkVariable(_var, false, is_ad ? "ADVariableValue" : "VariableValue");
261 : }
262 : VariableValueTempl(const std::vector<MooseVariableFieldBase *> & vars,
263 : const TagName & tag = Moose::SOLUTION_TAG,
264 : bool dof = false)
265 : : _var(vars, tag), _dof(dof)
266 : {
267 : checkVariable(_var, false, is_ad ? "ADVariableValue" : "VariableValue");
268 : }
269 : ///@}
270 :
271 : /**
272 : * Copy constructor for parallel dispatch
273 : */
274 : VariableValueTempl(const VariableValueTempl<is_ad> & object);
275 : /**
276 : * Copy assignment operator
277 : */
278 : VariableValueTempl<is_ad> & operator=(const VariableValueTempl<is_ad> & object);
279 :
280 : /**
281 : * Get whether the variable was coupled
282 : * @returns Whether the variable was coupled
283 : */
284 28032 : KOKKOS_FUNCTION operator bool() const { return _var.coupled(); }
285 :
286 : /**
287 : * Get the current variable value
288 : * @param datum The Datum object of the current thread
289 : * @param idx The local quadrature point or DOF index
290 : * @param comp The variable component
291 : * @returns The variable value
292 : */
293 2592739 : KOKKOS_FUNCTION auto operator()(Datum & datum, unsigned int idx, unsigned int comp = 0) const
294 : {
295 2592739 : return get(datum, idx, comp);
296 : }
297 :
298 : /**
299 : * Get the current variable value
300 : * @param datum The AssemblyDatum object of the current thread
301 : * @param idx The local quadrature point or DOF index
302 : * @param comp The variable component
303 : * @returns The variable value
304 : */
305 : KOKKOS_FUNCTION auto
306 : operator()(AssemblyDatum & datum, unsigned int idx, unsigned int comp = 0) const;
307 :
308 : /**
309 : * Get the Kokkos variable
310 : * @returns The Kokkos variable
311 : */
312 460146 : KOKKOS_FUNCTION const Variable & variable() const { return _var; }
313 :
314 : private:
315 : /**
316 : * Get the current variable value
317 : * @param datum The Datum object of the current thread
318 : * @param idx The local quadrature point or DOF index
319 : * @param comp The variable component
320 : * @param seed The derivative seed (only meaningful for AD)
321 : * @returns The variable value
322 : */
323 : KOKKOS_FUNCTION auto
324 : get(Datum & datum, unsigned int idx, unsigned int comp = 0, Real seed = 0) const;
325 :
326 : /**
327 : * Coupled Kokkos variable
328 : */
329 : Variable _var;
330 : /**
331 : * Derivative seed of each component for AD
332 : */
333 : Array<Real> _seed;
334 : /**
335 : * Flag whether DOF values are requested
336 : */
337 : bool _dof = false;
338 : };
339 :
340 : template <bool is_ad>
341 594137 : VariableValueTempl<is_ad>::VariableValueTempl(const VariableValueTempl<is_ad> & object)
342 338540 : : _var(object._var), _seed(object._seed), _dof(object._dof)
343 : {
344 : if constexpr (is_ad)
345 59361 : if (_var.coupled())
346 : {
347 57477 : if (!_seed.isAlloc())
348 57477 : _seed.create(_var.components());
349 :
350 114954 : for (unsigned int comp = 0; comp < _var.components(); ++comp)
351 57477 : _seed[comp] =
352 29002 : _var.dot() ? _var.mooseVar(comp)->sys().duDotDu(_var.var(comp)) : (_var.old() ? 0 : 1);
353 :
354 57477 : _seed.copyToDevice();
355 : }
356 594137 : }
357 :
358 : template <bool is_ad>
359 : VariableValueTempl<is_ad> &
360 8867 : VariableValueTempl<is_ad>::operator=(const VariableValueTempl<is_ad> & object)
361 : {
362 8867 : _var = object._var;
363 8867 : _dof = object._dof;
364 :
365 8867 : return *this;
366 : }
367 :
368 : template <bool is_ad>
369 : KOKKOS_FUNCTION auto
370 16042115 : VariableValueTempl<is_ad>::operator()(AssemblyDatum & datum,
371 : unsigned int idx,
372 : unsigned int comp) const
373 : {
374 : if constexpr (is_ad)
375 : {
376 2369536 : Real seed =
377 2369536 : datum.do_derivatives() && _var.coupled() && _var.sys(comp) == datum.sys() ? _seed[comp] : 0;
378 :
379 2369536 : return get(datum, idx, comp, seed);
380 : }
381 : else
382 13672579 : return get(datum, idx, comp);
383 : }
384 :
385 : template <bool is_ad>
386 : KOKKOS_FUNCTION auto
387 18634854 : VariableValueTempl<is_ad>::get(Datum & datum,
388 : unsigned int idx,
389 : unsigned int comp,
390 : [[maybe_unused]] Real seed) const
391 : {
392 : KOKKOS_ASSERT(_var.initialized());
393 :
394 2369536 : real_type value;
395 :
396 18634854 : if (_var.coupled())
397 : {
398 18615652 : auto & sys = datum.system(_var.sys(comp));
399 18615652 : auto var = _var.var(comp);
400 18615652 : auto tag = _var.tag();
401 :
402 18615652 : if (_dof)
403 : {
404 : unsigned int dof;
405 :
406 4361422 : if (datum.isNodal())
407 : {
408 4360782 : auto node = datum.node();
409 4360782 : dof = sys.getNodeLocalDofIndex(node, 0, var);
410 : }
411 : else
412 : {
413 640 : auto elem = datum.elem().id;
414 640 : dof = sys.getElemLocalDofIndex(elem, idx, var);
415 : }
416 :
417 : if constexpr (is_ad)
418 68840 : value = sys.getVectorDofADValue(dof, tag, seed);
419 : else
420 4292582 : value = sys.getVectorDofValue(dof, tag);
421 : }
422 : else
423 : {
424 14254230 : auto & elem = datum.elem();
425 14254230 : auto side = datum.side();
426 :
427 : if constexpr (is_ad)
428 2285548 : value = side == libMesh::invalid_uint
429 4571096 : ? sys.getVectorQpADValue(elem, datum.qpOffset(), idx, var, tag, seed)
430 : : sys.getVectorQpADValueFace(elem, side, idx, var, tag, seed);
431 : else
432 11968682 : value = side == libMesh::invalid_uint
433 11968682 : ? sys.getVectorQpValue(elem, datum.qpOffset() + idx, var, tag)
434 221890 : : sys.getVectorQpValueFace(elem, side, idx, var, tag);
435 : }
436 : }
437 : else
438 19202 : value = _var.value(comp);
439 :
440 18634854 : return value;
441 0 : }
442 :
443 : template <bool is_ad>
444 : class VariableGradientTempl
445 : {
446 : using real3_type = std::conditional_t<is_ad, ADReal3, Real3>;
447 :
448 : public:
449 : /**
450 : * Default constructor
451 : */
452 : VariableGradientTempl() = default;
453 : /**
454 : * Constructor
455 : * @param var The Kokkos variable
456 : */
457 680 : VariableGradientTempl(Variable var) : _var(var)
458 : {
459 680 : checkVariable(_var, false, is_ad ? "ADVariableGradient" : "VariableGradient");
460 680 : }
461 : /**
462 : * Constructor
463 : * @param var The MOOSE variable
464 : * @param tag The vector tag name
465 : */
466 3949 : VariableGradientTempl(const MooseVariableFieldBase & var,
467 1775 : const TagName & tag = Moose::SOLUTION_TAG)
468 2174 : : _var(var, tag)
469 : {
470 3949 : checkVariable(_var, false, is_ad ? "ADVariableGradient" : "VariableGradient");
471 3949 : }
472 : /**
473 : * Constructor
474 : * @param vars The MOOSE variables
475 : * @param tag The vector tag name
476 : */
477 : ///@{
478 : VariableGradientTempl(const std::vector<const MooseVariableFieldBase *> & vars,
479 : const TagName & tag = Moose::SOLUTION_TAG)
480 : : _var(vars, tag)
481 : {
482 : checkVariable(_var, false, is_ad ? "ADVariableGradient" : "VariableGradient");
483 : }
484 : VariableGradientTempl(const std::vector<MooseVariableFieldBase *> & vars,
485 : const TagName & tag = Moose::SOLUTION_TAG)
486 : : _var(vars, tag)
487 : {
488 : checkVariable(_var, false, is_ad ? "ADVariableGradient" : "VariableGradient");
489 : }
490 : ///@}
491 :
492 : /**
493 : * Copy constructor for parallel dispatch
494 : */
495 : VariableGradientTempl(const VariableGradientTempl<is_ad> & object);
496 : /**
497 : * Copy assignment operator
498 : */
499 : VariableGradientTempl<is_ad> & operator=(const VariableGradientTempl<is_ad> & object);
500 :
501 : /**
502 : * Get whether the variable was coupled
503 : * @returns Whether the variable was coupled
504 : */
505 : KOKKOS_FUNCTION operator bool() const { return _var.coupled(); }
506 :
507 : /**
508 : * Get the current variable gradient
509 : * @param datum The Datum object of the current thread
510 : * @param qp The local quadrature point index
511 : * @param comp The variable component
512 : * @returns The variable gradient
513 : */
514 : KOKKOS_FUNCTION auto operator()(Datum & datum, unsigned int qp, unsigned int comp = 0) const
515 : {
516 : return get(datum, qp, comp);
517 : }
518 :
519 : /**
520 : * Get the current variable gradient
521 : * @param datum The AssemblyDatum object of the current thread
522 : * @param qp The local quadrature point index
523 : * @param comp The variable component
524 : * @returns The variable gradient
525 : */
526 : KOKKOS_FUNCTION auto
527 : operator()(AssemblyDatum & datum, unsigned int qp, unsigned int comp = 0) const;
528 :
529 : /**
530 : * Get the Kokkos variable
531 : * @returns The Kokkos variable
532 : */
533 : KOKKOS_FUNCTION const Variable & variable() const { return _var; }
534 :
535 : private:
536 : /**
537 : * Get the current variable gradient
538 : * @param datum The Datum object of the current thread
539 : * @param qp The local quadrature point index
540 : * @param comp The variable component
541 : * @param seed The derivative seed (only meaningful for AD)
542 : * @returns The variable gradient
543 : */
544 : KOKKOS_FUNCTION auto
545 : get(Datum & datum, unsigned int qp, unsigned int comp = 0, Real seed = 0) const;
546 :
547 : /**
548 : * Coupled Kokkos variable
549 : */
550 : Variable _var;
551 : /**
552 : * Derivative seed of each component for AD
553 : */
554 : Array<Real> _seed;
555 : };
556 :
557 : template <bool is_ad>
558 190477 : VariableGradientTempl<is_ad>::VariableGradientTempl(const VariableGradientTempl<is_ad> & object)
559 112839 : : _var(object._var), _seed(object._seed)
560 : {
561 : if constexpr (is_ad)
562 17907 : if (_var.coupled())
563 : {
564 17907 : if (!_seed.isAlloc())
565 17907 : _seed.create(_var.components());
566 :
567 35814 : for (unsigned int comp = 0; comp < _var.components(); ++comp)
568 17907 : _seed[comp] =
569 9044 : _var.dot() ? _var.mooseVar(comp)->sys().duDotDu(_var.var(comp)) : (_var.old() ? 0 : 1);
570 :
571 17907 : _seed.copyToDevice();
572 : }
573 190477 : }
574 :
575 : template <bool is_ad>
576 : VariableGradientTempl<is_ad> &
577 : VariableGradientTempl<is_ad>::operator=(const VariableGradientTempl<is_ad> & object)
578 : {
579 : _var = object._var;
580 :
581 : return *this;
582 : }
583 :
584 : template <bool is_ad>
585 : KOKKOS_FUNCTION auto
586 43240260 : VariableGradientTempl<is_ad>::operator()(AssemblyDatum & datum,
587 : unsigned int qp,
588 : unsigned int comp) const
589 : {
590 : if constexpr (is_ad)
591 : {
592 2368704 : Real seed =
593 2368704 : datum.do_derivatives() && _var.coupled() && _var.sys(comp) == datum.sys() ? _seed[comp] : 0;
594 :
595 2368704 : return get(datum, qp, comp, seed);
596 : }
597 : else
598 40871556 : return get(datum, qp, comp);
599 : }
600 :
601 : template <bool is_ad>
602 : KOKKOS_FUNCTION auto
603 43240260 : VariableGradientTempl<is_ad>::get(Datum & datum,
604 : unsigned int qp,
605 : unsigned int comp,
606 : [[maybe_unused]] Real seed) const
607 : {
608 : KOKKOS_ASSERT(_var.initialized());
609 :
610 43240260 : real3_type grad;
611 :
612 43240260 : if (_var.coupled())
613 : {
614 : KOKKOS_ASSERT(!datum.isNodal());
615 :
616 43240260 : auto & elem = datum.elem();
617 43240260 : auto side = datum.side();
618 :
619 : if constexpr (is_ad)
620 2368704 : grad =
621 : side == libMesh::invalid_uint
622 4737408 : ? datum.system(_var.sys(comp))
623 : .getVectorQpADGrad(
624 2368704 : elem, datum.J(qp), datum.qpOffset(), qp, _var.var(comp), _var.tag(), seed)
625 0 : : datum.system(_var.sys(comp))
626 : .getVectorQpADGradFace(
627 0 : elem, side, datum.J(qp), qp, _var.var(comp), _var.tag(), seed);
628 : else
629 40871556 : grad =
630 : side == libMesh::invalid_uint
631 81743112 : ? datum.system(_var.sys(comp))
632 40871556 : .getVectorQpGrad(elem, datum.qpOffset() + qp, _var.var(comp), _var.tag())
633 0 : : datum.system(_var.sys(comp))
634 0 : .getVectorQpGradFace(elem, side, datum.J(qp), qp, _var.var(comp), _var.tag());
635 : }
636 :
637 43240260 : return grad;
638 0 : }
639 :
640 : using VariableValue = VariableValueTempl<false>;
641 : using ADVariableValue = VariableValueTempl<true>;
642 : using VariableGradient = VariableGradientTempl<false>;
643 : using ADVariableGradient = VariableGradientTempl<true>;
644 :
645 : class VectorVariableValue
646 : {
647 : public:
648 : /**
649 : * Default constructor
650 : */
651 : VectorVariableValue() = default;
652 : /**
653 : * Constructor
654 : * @param var The Kokkos variable
655 : * @param dof Whether to get DOF values
656 : */
657 70 : VectorVariableValue(Variable var, bool dof = false) : _var(var), _dof(dof)
658 : {
659 70 : checkVariable(_var, true, "VectorVariableValue");
660 70 : }
661 : /**
662 : * Constructor
663 : * @param var The MOOSE variable
664 : * @param tag The vector tag name
665 : * @param dof Whether to get DOF values
666 : */
667 526 : VectorVariableValue(const MooseVariableFieldBase & var,
668 : const TagName & tag = Moose::SOLUTION_TAG,
669 250 : bool dof = false)
670 276 : : _var(var, tag), _dof(dof)
671 : {
672 526 : checkVariable(_var, true, "VectorVariableValue");
673 526 : }
674 :
675 : /**
676 : * Get whether the variable was coupled
677 : * @returns Whether the variable was coupled
678 : */
679 : KOKKOS_FUNCTION operator bool() const { return _var.coupled(); }
680 :
681 : /**
682 : * Get the current vector variable value
683 : * @param datum The AssemblyDatum object of the current thread
684 : * @param idx The local quadrature point index or DOF index
685 : * @returns The vector variable value
686 : */
687 : KOKKOS_FUNCTION Real3 operator()(AssemblyDatum & datum,
688 : unsigned int idx,
689 : unsigned int comp = 0) const;
690 :
691 : /**
692 : * Get the Kokkos variable
693 : * @returns The Kokkos variable
694 : */
695 : KOKKOS_FUNCTION const Variable & variable() const { return _var; }
696 :
697 : private:
698 : /**
699 : * Coupled Kokkos variable
700 : */
701 : Variable _var;
702 : /**
703 : * Flag whether DOF values are requested
704 : */
705 : bool _dof = false;
706 : };
707 :
708 : class VectorVariableGradient
709 : {
710 : public:
711 : /**
712 : * Default constructor
713 : */
714 : VectorVariableGradient() = default;
715 : /**
716 : * Constructor
717 : * @param var The Kokkos variable
718 : */
719 51 : VectorVariableGradient(Variable var) : _var(var)
720 : {
721 51 : checkVariable(_var, true, "VectorVariableGradient");
722 51 : }
723 : /**
724 : * Constructor
725 : * @param var The MOOSE variable
726 : * @param tag The vector tag name
727 : */
728 315 : VectorVariableGradient(const MooseVariableFieldBase & var,
729 150 : const TagName & tag = Moose::SOLUTION_TAG)
730 165 : : _var(var, tag)
731 : {
732 315 : checkVariable(_var, true, "VectorVariableGradient");
733 315 : }
734 :
735 : /**
736 : * Get whether the variable was coupled
737 : * @returns Whether the variable was coupled
738 : */
739 : KOKKOS_FUNCTION operator bool() const { return _var.coupled(); }
740 :
741 : /**
742 : * Get the current vector variable gradient
743 : * @param datum The AssemblyDatum object of the current thread
744 : * @param qp The local quadrature point index
745 : * @returns The vector variable gradient
746 : */
747 : KOKKOS_FUNCTION Real33 operator()(AssemblyDatum & datum,
748 : unsigned int qp,
749 : unsigned int comp = 0) const;
750 :
751 : /**
752 : * Get the Kokkos variable
753 : * @returns The Kokkos variable
754 : */
755 : KOKKOS_FUNCTION const Variable & variable() const { return _var; }
756 :
757 : private:
758 : /**
759 : * Coupled Kokkos variable
760 : */
761 : Variable _var;
762 : };
763 :
764 : class VectorVariableCurl
765 : {
766 : public:
767 : /**
768 : * Default constructor
769 : */
770 : VectorVariableCurl() = default;
771 : /**
772 : * Constructor
773 : * @param var The Kokkos variable
774 : */
775 : VectorVariableCurl(Variable var) : _var(var) { checkVariable(_var, true, "VectorVariableCurl"); }
776 : /**
777 : * Constructor
778 : * @param var The MOOSE variable
779 : * @param tag The vector tag name
780 : */
781 29 : VectorVariableCurl(const MooseVariableFieldBase & var, const TagName & tag = Moose::SOLUTION_TAG)
782 15 : : _var(var, tag)
783 : {
784 29 : checkVariable(_var, true, "VectorVariableCurl");
785 29 : }
786 :
787 : /**
788 : * Get whether the variable was coupled
789 : * @returns Whether the variable was coupled
790 : */
791 : KOKKOS_FUNCTION operator bool() const { return _var.coupled(); }
792 :
793 : /**
794 : * Get the current vector variable curl
795 : * @param datum The AssemblyDatum object of the current thread
796 : * @param qp The local quadrature point index
797 : * @returns The vector variable curl
798 : */
799 : KOKKOS_FUNCTION Real3 operator()(AssemblyDatum & datum,
800 : unsigned int qp,
801 : unsigned int comp = 0) const;
802 :
803 : /**
804 : * Get the Kokkos variable
805 : * @returns The Kokkos variable
806 : */
807 : KOKKOS_FUNCTION const Variable & variable() const { return _var; }
808 :
809 : private:
810 : /**
811 : * Coupled Kokkos variable
812 : */
813 : Variable _var;
814 : };
815 :
816 : KOKKOS_FUNCTION inline Real3
817 1869208 : VectorVariableValue::operator()(AssemblyDatum & datum, unsigned int idx, unsigned int comp) const
818 : {
819 : KOKKOS_ASSERT(_var.initialized());
820 :
821 1869208 : Real3 value = 0;
822 :
823 1869208 : if (_var.coupled())
824 : {
825 1759384 : auto & sys = datum.system(_var.sys(comp));
826 1759384 : auto var = _var.var(comp);
827 1759384 : auto tag = _var.tag();
828 :
829 1759384 : if (_dof)
830 : {
831 54120 : auto dimension = datum.assembly().getDimension();
832 :
833 54120 : if (datum.isNodal())
834 : {
835 54120 : auto node = datum.node();
836 :
837 162236 : for (unsigned int c = 0; c < dimension; ++c)
838 108116 : value(c) = sys.getVectorDofValue(sys.getNodeLocalDofIndex(node, c, var), tag);
839 : }
840 : else
841 : {
842 0 : auto elem = datum.elem().id;
843 0 : auto offset = idx * dimension;
844 :
845 0 : for (unsigned int c = 0; c < dimension; ++c)
846 0 : value(c) = sys.getVectorDofValue(sys.getElemLocalDofIndex(elem, offset + c, var), tag);
847 : }
848 : }
849 : else
850 : {
851 : KOKKOS_ASSERT(!datum.isNodal());
852 :
853 1705264 : auto & elem = datum.elem();
854 1705264 : auto side = datum.side();
855 :
856 1705264 : if (side == libMesh::invalid_uint)
857 1651504 : value = sys.getVectorQpVectorValue(elem, datum.qpOffset() + idx, var, tag);
858 : else
859 53760 : value = sys.getVectorQpVectorValueFace(elem, side, idx, var, tag);
860 : }
861 : }
862 : else
863 109824 : value = _var.vectorValue(comp);
864 :
865 1869208 : return value;
866 : }
867 :
868 : KOKKOS_FUNCTION inline Real33
869 1666857 : VectorVariableGradient::operator()(AssemblyDatum & datum, unsigned int qp, unsigned int comp) const
870 : {
871 : KOKKOS_ASSERT(_var.initialized());
872 :
873 1666857 : Real33 grad = 0;
874 :
875 1666857 : if (_var.coupled())
876 : {
877 : KOKKOS_ASSERT(!datum.isNodal());
878 :
879 1666857 : auto & elem = datum.elem();
880 1666857 : auto side = datum.side();
881 1666857 : auto & sys = datum.system(_var.sys(comp));
882 1666857 : auto var = _var.var(comp);
883 1666857 : auto tag = _var.tag();
884 :
885 1666857 : if (side == libMesh::invalid_uint)
886 1666857 : grad = sys.getVectorQpVectorGrad(elem, datum.qpOffset() + qp, var, tag);
887 : else
888 0 : grad = sys.getVectorQpVectorGradFace(elem, side, datum.J(qp), qp, var, tag);
889 : }
890 :
891 1666857 : return grad;
892 : }
893 :
894 : KOKKOS_FUNCTION inline Real3
895 539648 : VectorVariableCurl::operator()(AssemblyDatum & datum, unsigned int qp, unsigned int comp) const
896 : {
897 : KOKKOS_ASSERT(_var.initialized());
898 :
899 539648 : Real3 curl = 0;
900 :
901 539648 : if (_var.coupled())
902 : {
903 : KOKKOS_ASSERT(!datum.isNodal());
904 :
905 539648 : auto & elem = datum.elem();
906 539648 : auto side = datum.side();
907 539648 : auto & sys = datum.system(_var.sys(comp));
908 539648 : auto var = _var.var(comp);
909 539648 : auto tag = _var.tag();
910 :
911 539648 : if (side == libMesh::invalid_uint)
912 539648 : curl = sys.getVectorQpVectorCurl(elem, datum.qpOffset() + qp, var, tag);
913 : else
914 : {
915 0 : auto fe = sys.getFETypeID(var);
916 0 : auto n_dofs = datum.assembly().getNumDofs(elem.type, fe);
917 0 : auto & grad_phi = datum.assembly().getVectorGradPhiFace(elem.subdomain, elem.type, fe)(side);
918 0 : auto jacobian = datum.J(qp);
919 0 : auto jacobian_transpose = jacobian.transpose();
920 0 : Real33 grad = 0;
921 :
922 0 : for (unsigned int i = 0; i < n_dofs; ++i)
923 0 : grad += sys.getVectorDofValue(sys.getElemLocalDofIndex(elem.id, i, var), tag) *
924 0 : (grad_phi(i, qp) * jacobian_transpose);
925 :
926 0 : curl = curlFromVectorGradient(grad, datum.assembly().getDimension());
927 : }
928 : }
929 :
930 539648 : return curl;
931 : }
932 :
933 : template <>
934 : struct ArrayDeepCopy<ADVariableValue>
935 : {
936 : static constexpr bool value = true;
937 : };
938 :
939 : template <>
940 : struct ArrayDeepCopy<ADVariableGradient>
941 : {
942 : static constexpr bool value = true;
943 : };
944 : ///@}
945 :
946 : } // namespace Moose::Kokkos
|