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::Kokkos
15 : {
16 :
17 : /**
18 : * The base class for a user to derive their own Kokkos nodal kernels.
19 : *
20 : * The user should define computeQpResidual(), computeQpJacobian(), and computeQpOffDiagJacobian()
21 : * as inlined public methods in their derived class (not virtual override). The signature of
22 : * computeQpResidual() expected to be defined in the derived class is as follows:
23 : *
24 : * @tparam Derived The object type
25 : * @param qp The dummy quadrature point index (= 0)
26 : * @param datum The AssemblyDatum object of the current thread
27 : * @returns The residual contribution
28 : *
29 : * template <typename Derived>
30 : * KOKKOS_FUNCTION Real computeQpResidual(const unsigned int qp, AssemblyDatum & datum) const;
31 : *
32 : * The signatures of computeQpJacobian() and computeQpOffDiagJacobian() 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 : * @tparam Derived The object type
63 : * @param qp The dummy quadrature point index (= 0)
64 : * @param datum The AssemblyDatum object of the current thread
65 : * @returns The diagonal Jacobian contribution
66 : */
67 : template <typename Derived>
68 0 : KOKKOS_FUNCTION Real computeQpJacobian(const unsigned int /* qp */,
69 : AssemblyDatum & /* datum */) const
70 : {
71 0 : ::Kokkos::abort("Default computeQpJacobian() should never be called. Make sure you properly "
72 : "redefined this method in your class without typos.");
73 :
74 : return 0;
75 : }
76 : /**
77 : * Compute off-diagonal Jacobian contribution on a node
78 : * @tparam Derived The object type
79 : * @param jvar The variable number for column
80 : * @param qp The dummy quadrature point index (= 0)
81 : * @param datum The AssemblyDatum object of the current thread
82 : * @returns The off-diagonal Jacobian contribution
83 : */
84 : template <typename Derived>
85 0 : KOKKOS_FUNCTION Real computeQpOffDiagJacobian(const unsigned int /* jvar */,
86 : const unsigned int /* qp */,
87 : AssemblyDatum & /* datum */) const
88 : {
89 0 : ::Kokkos::abort(
90 : "Default computeQpOffDiagJacobian() should never be called. Make sure you properly "
91 : "redefined this method in your class without typos.");
92 :
93 : return 0;
94 : }
95 : ///@}
96 :
97 : /**
98 : * Functions used to check if users have overriden the hook methods, whose calculations can be
99 : * skipped when not overriden
100 : * @returns The function pointer of the default hook method
101 : */
102 : ///@{
103 : template <typename Derived>
104 282460 : static auto defaultJacobian()
105 : {
106 282460 : return &NodalKernel::computeQpJacobian<Derived>;
107 : }
108 : template <typename Derived>
109 282460 : static auto defaultOffDiagJacobian()
110 : {
111 282460 : return &NodalKernel::computeQpOffDiagJacobian<Derived>;
112 : }
113 : ///@}
114 :
115 : /**
116 : * The parallel computation entry functions called by Kokkos
117 : */
118 : ///@{
119 : template <typename Derived>
120 : KOKKOS_FUNCTION void operator()(ResidualLoop, const ThreadID tid, const Derived & kernel) const;
121 : template <typename Derived>
122 : KOKKOS_FUNCTION void operator()(JacobianLoop, const ThreadID tid, const Derived & kernel) const;
123 : template <typename Derived>
124 : KOKKOS_FUNCTION void
125 : operator()(OffDiagJacobianLoop, const ThreadID tid, const Derived & kernel) const;
126 : ///@}
127 :
128 : protected:
129 : /**
130 : * Current solution at nodes
131 : */
132 : const VariableValue _u;
133 :
134 : private:
135 : /**
136 : * Flag whether this kernel is boundary-restricted
137 : */
138 : const bool _boundary_restricted;
139 : };
140 :
141 : template <typename Derived>
142 : KOKKOS_FUNCTION void
143 1265482 : NodalKernel::operator()(ResidualLoop, const ThreadID tid, const Derived & kernel) const
144 : {
145 1265482 : auto node = _boundary_restricted ? kokkosBoundaryNodeID(tid) : kokkosBlockNodeID(tid);
146 1265482 : auto & sys = kokkosSystem(_kokkos_var.sys());
147 :
148 1265482 : if (!sys.isNodalDefined(node, _kokkos_var.var()))
149 0 : return;
150 :
151 1265482 : AssemblyDatum datum(node, kokkosAssembly(), kokkosSystems(), _kokkos_var, _kokkos_var.var());
152 :
153 1265482 : Real local_re = kernel.template computeQpResidual<Derived>(0, datum);
154 :
155 1265482 : accumulateTaggedNodalResidual(true, local_re, node);
156 : }
157 :
158 : template <typename Derived>
159 : KOKKOS_FUNCTION void
160 194664 : NodalKernel::operator()(JacobianLoop, const ThreadID tid, const Derived & kernel) const
161 : {
162 194664 : auto node = _boundary_restricted ? kokkosBoundaryNodeID(tid) : kokkosBlockNodeID(tid);
163 194664 : auto & sys = kokkosSystem(_kokkos_var.sys());
164 :
165 194664 : if (!sys.isNodalDefined(node, _kokkos_var.var()))
166 0 : return;
167 :
168 194664 : AssemblyDatum datum(node, kokkosAssembly(), kokkosSystems(), _kokkos_var, _kokkos_var.var());
169 :
170 194664 : Real local_ke = kernel.template computeQpJacobian<Derived>(0, datum);
171 :
172 194664 : accumulateTaggedNodalMatrix(true, local_ke, node, _kokkos_var.var());
173 : }
174 :
175 : template <typename Derived>
176 : KOKKOS_FUNCTION void
177 249100 : NodalKernel::operator()(OffDiagJacobianLoop, const ThreadID tid, const Derived & kernel) const
178 : {
179 249100 : auto node = _boundary_restricted ? kokkosBoundaryNodeID(_thread(tid, 1))
180 249100 : : kokkosBlockNodeID(_thread(tid, 1));
181 249100 : auto & sys = kokkosSystem(_kokkos_var.sys());
182 249100 : auto jvar = sys.getCoupling(_kokkos_var.var())[_thread(tid, 0)];
183 :
184 249100 : if (!sys.isNodalDefined(node, _kokkos_var.var()))
185 0 : return;
186 :
187 249100 : AssemblyDatum datum(node, kokkosAssembly(), kokkosSystems(), _kokkos_var, jvar);
188 :
189 249100 : Real local_ke = kernel.template computeQpOffDiagJacobian<Derived>(jvar, 0, datum);
190 :
191 249100 : accumulateTaggedNodalMatrix(true, local_ke, node, jvar);
192 : }
193 :
194 : } // namespace Moose::Kokkos
|