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 "KokkosNodalKernelBase.h"
13 :
14 : namespace Moose
15 : {
16 : namespace Kokkos
17 : {
18 :
19 : /**
20 : * The base class for a user to derive their own Kokkos nodal kernels.
21 : *
22 : * The user should define computeQpResidual(), computeQpJacobian(), and computeQpOffDiagJacobian()
23 : * as inlined public methods in their derived class (not virtual override). The signature of
24 : * computeQpResidual() expected to be defined in the derived class is as follows:
25 : *
26 : * @param qp The dummy quadrature point index (= 0)
27 : * @param datum The AssemblyDatum object of the current thread
28 : * @returns The residual contribution
29 : *
30 : * KOKKOS_FUNCTION Real computeQpResidual(const unsigned int qp, AssemblyDatum & datum) const;
31 : *
32 : * The signatures of computeQpJacobian() and computeOffDiagQpJacobian() can be found in the code
33 : * below, and their definition in the derived class is optional. If they are defined in the derived
34 : * class, they will hide the default definitions in the base class.
35 : */
36 : class NodalKernel : public NodalKernelBase
37 : {
38 : public:
39 : static InputParameters validParams();
40 :
41 : /**
42 : * Constructor
43 : */
44 : NodalKernel(const InputParameters & parameters);
45 :
46 : /**
47 : * Dispatch residual calculation
48 : */
49 : virtual void computeResidual() override;
50 : /**
51 : * Dispatch diagonal and off-diagonal Jacobian calculation
52 : */
53 : virtual void computeJacobian() override;
54 :
55 : /**
56 : * Default methods to prevent compile errors even when these methods were not defined in the
57 : * derived class
58 : */
59 : ///@{
60 : /**
61 : * Compute diagonal Jacobian contribution on a node
62 : * @param qp The dummy quadrature point index (= 0)
63 : * @param datum The AssemblyDatum object of the current thread
64 : * @returns The diagonal Jacobian contribution
65 : */
66 0 : KOKKOS_FUNCTION Real computeQpJacobian(const unsigned int /* qp */,
67 : AssemblyDatum & /* datum */) const
68 : {
69 0 : return 0;
70 : }
71 : /**
72 : * Compute off-diagonal Jacobian contribution on a node
73 : * @param jvar The variable number for column
74 : * @param qp The dummy quadrature point index (= 0)
75 : * @param datum The AssemblyDatum object of the current thread
76 : * @returns The off-diagonal Jacobian contribution
77 : */
78 0 : KOKKOS_FUNCTION Real computeQpOffDiagJacobian(const unsigned int /* jvar */,
79 : const unsigned int /* qp */,
80 : AssemblyDatum & /* datum */) const
81 : {
82 0 : return 0;
83 : }
84 : /**
85 : * Get the function pointer of the default computeQpJacobian()
86 : * @returns The function pointer
87 : */
88 264421 : static auto defaultJacobian() { return &NodalKernel::computeQpJacobian; }
89 : /**
90 : * Get the function pointer of the default computeQpOffDiagJacobian()
91 : * @returns The function pointer
92 : */
93 264421 : static auto defaultOffDiagJacobian() { return &NodalKernel::computeQpOffDiagJacobian; }
94 : ///@}
95 :
96 : /**
97 : * Shims for hook methods that can be leveraged to implement static polymorphism
98 : */
99 : ///{@
100 : template <typename Derived>
101 1265482 : KOKKOS_FUNCTION Real computeQpResidualShim(const Derived & kernel,
102 : const unsigned int qp,
103 : AssemblyDatum & datum) const
104 : {
105 1265482 : return kernel.computeQpResidual(qp, datum);
106 : }
107 : template <typename Derived>
108 194664 : KOKKOS_FUNCTION Real computeQpJacobianShim(const Derived & kernel,
109 : const unsigned int qp,
110 : AssemblyDatum & datum) const
111 : {
112 194664 : return kernel.computeQpJacobian(qp, datum);
113 : }
114 : template <typename Derived>
115 249100 : KOKKOS_FUNCTION Real computeQpOffDiagJacobianShim(const Derived & kernel,
116 : const unsigned int jvar,
117 : const unsigned int qp,
118 : AssemblyDatum & datum) const
119 : {
120 249100 : return kernel.computeQpOffDiagJacobian(jvar, qp, datum);
121 : }
122 : ///@}
123 :
124 : /**
125 : * The parallel computation entry functions called by Kokkos
126 : */
127 : ///@{
128 : template <typename Derived>
129 : KOKKOS_FUNCTION void operator()(ResidualLoop, const ThreadID tid, const Derived & kernel) const;
130 : template <typename Derived>
131 : KOKKOS_FUNCTION void operator()(JacobianLoop, const ThreadID tid, const Derived & kernel) const;
132 : template <typename Derived>
133 : KOKKOS_FUNCTION void
134 : operator()(OffDiagJacobianLoop, const ThreadID tid, const Derived & kernel) const;
135 : ///@}
136 :
137 : protected:
138 : /**
139 : * Current solution at nodes
140 : */
141 : const VariableValue _u;
142 :
143 : private:
144 : /**
145 : * Flag whether this kernel is boundary-restricted
146 : */
147 : const bool _boundary_restricted;
148 : };
149 :
150 : template <typename Derived>
151 : KOKKOS_FUNCTION void
152 1265482 : NodalKernel::operator()(ResidualLoop, const ThreadID tid, const Derived & kernel) const
153 : {
154 1265482 : auto node = _boundary_restricted ? kokkosBoundaryNodeID(tid) : kokkosBlockNodeID(tid);
155 1265482 : auto & sys = kokkosSystem(_kokkos_var.sys());
156 :
157 1265482 : if (!sys.isNodalDefined(node, _kokkos_var.var()))
158 0 : return;
159 :
160 1265482 : AssemblyDatum datum(node, kokkosAssembly(), kokkosSystems(), _kokkos_var, _kokkos_var.var());
161 :
162 1265482 : Real local_re = kernel.computeQpResidualShim(kernel, 0, datum);
163 :
164 1265482 : accumulateTaggedNodalResidual(true, local_re, node);
165 : }
166 :
167 : template <typename Derived>
168 : KOKKOS_FUNCTION void
169 194664 : NodalKernel::operator()(JacobianLoop, const ThreadID tid, const Derived & kernel) const
170 : {
171 194664 : auto node = _boundary_restricted ? kokkosBoundaryNodeID(tid) : kokkosBlockNodeID(tid);
172 194664 : auto & sys = kokkosSystem(_kokkos_var.sys());
173 :
174 194664 : if (!sys.isNodalDefined(node, _kokkos_var.var()))
175 0 : return;
176 :
177 194664 : AssemblyDatum datum(node, kokkosAssembly(), kokkosSystems(), _kokkos_var, _kokkos_var.var());
178 :
179 194664 : Real local_ke = kernel.computeQpJacobianShim(kernel, 0, datum);
180 :
181 194664 : accumulateTaggedNodalMatrix(true, local_ke, node, _kokkos_var.var());
182 : }
183 :
184 : template <typename Derived>
185 : KOKKOS_FUNCTION void
186 249100 : NodalKernel::operator()(OffDiagJacobianLoop, const ThreadID tid, const Derived & kernel) const
187 : {
188 249100 : auto node = _boundary_restricted ? kokkosBoundaryNodeID(_thread(tid, 1))
189 249100 : : kokkosBlockNodeID(_thread(tid, 1));
190 249100 : auto & sys = kokkosSystem(_kokkos_var.sys());
191 249100 : auto jvar = sys.getCoupling(_kokkos_var.var())[_thread(tid, 0)];
192 :
193 249100 : if (!sys.isNodalDefined(node, _kokkos_var.var()))
194 0 : return;
195 :
196 249100 : AssemblyDatum datum(node, kokkosAssembly(), kokkosSystems(), _kokkos_var, jvar);
197 :
198 249100 : Real local_ke = kernel.computeQpOffDiagJacobianShim(kernel, jvar, 0, datum);
199 :
200 249100 : accumulateTaggedNodalMatrix(true, local_ke, node, jvar);
201 : }
202 :
203 : } // namespace Kokkos
204 : } // namespace Moose
|