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 "KokkosNodalBCBase.h"
13 :
14 : namespace Moose::Kokkos
15 : {
16 :
17 : /**
18 : * The base class for a user to derive their own Kokkos nodal boundary conditions on vector
19 : * variables.
20 : */
21 : class VectorNodalBC : public NodalBCBase
22 : {
23 : public:
24 : static InputParameters validParams();
25 :
26 : /**
27 : * Constructor
28 : */
29 : VectorNodalBC(const InputParameters & parameters);
30 :
31 : /**
32 : * Dispatch residual calculation
33 : */
34 : virtual void computeResidual() override;
35 : /**
36 : * Dispatch diagonal and off-diagonal Jacobian calculation
37 : */
38 : virtual void computeJacobian() override;
39 :
40 : /**
41 : * Default methods to prevent compile errors even when these methods were not defined in the
42 : * derived class
43 : */
44 : ///@{
45 : template <typename Derived>
46 4864 : KOKKOS_FUNCTION Real3 computeQpJacobian(const unsigned int /* qp */,
47 : AssemblyDatum & /* datum */) const
48 : {
49 4864 : return Real3(1);
50 : }
51 : template <typename Derived>
52 0 : KOKKOS_FUNCTION Real computeQpOffDiagJacobian(const unsigned int /* jvar */,
53 : const unsigned int /* qp */,
54 : AssemblyDatum & /* datum */) const
55 : {
56 0 : ::Kokkos::abort(
57 : "Default computeQpOffDiagJacobian() should never be called. Make sure you properly "
58 : "redefined this method in your class without typos.");
59 :
60 : return 0;
61 : }
62 : ///@}
63 :
64 : /**
65 : * Functions used to check if users have overriden the hook methods, whose calculations can be
66 : * skipped when not overriden
67 : */
68 : ///@{
69 : template <typename Derived>
70 82815 : static auto defaultJacobian()
71 : {
72 82815 : return &VectorNodalBC::computeQpJacobian<Derived>;
73 : }
74 : template <typename Derived>
75 82815 : static auto defaultOffDiagJacobian()
76 : {
77 82815 : return &VectorNodalBC::computeQpOffDiagJacobian<Derived>;
78 : }
79 : ///@}
80 :
81 : /**
82 : * The parallel computation entry functions called by Kokkos
83 : */
84 : ///@{
85 : template <typename Derived>
86 : KOKKOS_FUNCTION void operator()(ResidualLoop, const ThreadID tid, const Derived & bc) const;
87 : template <typename Derived>
88 : KOKKOS_FUNCTION void operator()(JacobianLoop, const ThreadID tid, const Derived & bc) const;
89 : template <typename Derived>
90 : KOKKOS_FUNCTION void
91 : operator()(OffDiagJacobianLoop, const ThreadID tid, const Derived & bc) const;
92 : ///@}
93 :
94 : protected:
95 : /**
96 : * Current vector solution at nodes
97 : */
98 : const VectorVariableValue _u;
99 : };
100 :
101 : template <typename Derived>
102 : KOKKOS_FUNCTION void
103 54120 : VectorNodalBC::operator()(ResidualLoop, const ThreadID tid, const Derived & bc) const
104 : {
105 54120 : auto node = kokkosBoundaryNodeID(tid);
106 54120 : auto & sys = kokkosSystem(_kokkos_var.sys());
107 :
108 54120 : if (!sys.isNodalDefined(node, _kokkos_var.var()))
109 0 : return;
110 :
111 54120 : AssemblyDatum datum(node, kokkosAssembly(), kokkosSystems(), _kokkos_var, _kokkos_var.var());
112 :
113 54120 : Real3 local_re = bc.template computeQpResidual<Derived>(0, datum);
114 :
115 162236 : for (unsigned int comp = 0; comp < _dimension; ++comp)
116 108116 : accumulateTaggedVectorNodalResidual(false, local_re(comp), node, comp);
117 : }
118 :
119 : template <typename Derived>
120 : KOKKOS_FUNCTION void
121 4864 : VectorNodalBC::operator()(JacobianLoop, const ThreadID tid, const Derived & bc) const
122 : {
123 4864 : auto node = kokkosBoundaryNodeID(tid);
124 4864 : auto & sys = kokkosSystem(_kokkos_var.sys());
125 :
126 4864 : if (!sys.isNodalDefined(node, _kokkos_var.var()))
127 0 : return;
128 :
129 4864 : AssemblyDatum datum(node, kokkosAssembly(), kokkosSystems(), _kokkos_var, _kokkos_var.var());
130 :
131 4864 : Real3 local_ke = bc.template computeQpJacobian<Derived>(0, datum);
132 :
133 14560 : for (unsigned int comp = 0; comp < _dimension; ++comp)
134 9696 : accumulateTaggedVectorNodalMatrix(false, local_ke(comp), node, comp, comp, _kokkos_var.var());
135 : }
136 :
137 : template <typename Derived>
138 : KOKKOS_FUNCTION void
139 0 : VectorNodalBC::operator()(OffDiagJacobianLoop, const ThreadID tid, const Derived & bc) const
140 : {
141 0 : auto node = kokkosBoundaryNodeID(_thread(tid, 1));
142 0 : auto & sys = kokkosSystem(_kokkos_var.sys());
143 0 : auto jvar = sys.getCoupling(_kokkos_var.var())[_thread(tid, 0)];
144 :
145 0 : if (!sys.isNodalDefined(node, _kokkos_var.var()))
146 0 : return;
147 :
148 0 : AssemblyDatum datum(node, kokkosAssembly(), kokkosSystems(), _kokkos_var, jvar);
149 :
150 0 : Real3 local_ke = bc.template computeQpOffDiagJacobian<Derived>(jvar, 0, datum);
151 :
152 0 : for (unsigned int comp = 0; comp < _dimension; ++comp)
153 0 : accumulateTaggedVectorNodalMatrix(true, local_ke(comp), node, comp, 0, jvar);
154 : }
155 :
156 : } // namespace Moose::Kokkos
|