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 "KokkosIntegratedBCBase.h"
13 :
14 : namespace Moose::Kokkos
15 : {
16 :
17 : /**
18 : * The base class for a user to derive their own Kokkos integrated boundary conditions.
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 i The element-local DOF index
26 : * @param qp The local quadrature point index
27 : * @param datum The AssemblyDatum object of the current thread
28 : * @returns The residual contribution
29 : *
30 : * template <typename Derived>
31 : * KOKKOS_FUNCTION Real computeQpResidual(const unsigned int i,
32 : * const unsigned int qp,
33 : * AssemblyDatum & datum) const;
34 : *
35 : * The signatures of computeQpJacobian() and computeQpOffDiagJacobian() can be found in the code
36 : * below, and their definition in the derived class is optional. If they are defined in the derived
37 : * class, they will hide the default definitions in the base class.
38 : */
39 : class IntegratedBC : public IntegratedBCBase
40 : {
41 : public:
42 : static InputParameters validParams();
43 :
44 : /**
45 : * Constructor
46 : */
47 : IntegratedBC(const InputParameters & parameters);
48 :
49 : /**
50 : * Dispatch residual calculation
51 : */
52 : virtual void computeResidual() override;
53 : /**
54 : * Dispatch diagonal and off-diagonal Jacobian calculation
55 : */
56 : virtual void computeJacobian() override;
57 :
58 : /**
59 : * Default methods to prevent compile errors even when these methods were not defined in the
60 : * derived class
61 : */
62 : ///@{
63 : /**
64 : * Compute diagonal Jacobian contribution on a quadrature point
65 : * @tparam Derived The object type
66 : * @param i The test function DOF index
67 : * @param j The trial function DOF index
68 : * @param qp The local quadrature point index
69 : * @param datum The AssemblyDatum object of the current thread
70 : * @returns The diagonal Jacobian contribution
71 : */
72 : template <typename Derived>
73 0 : KOKKOS_FUNCTION Real computeQpJacobian(const unsigned int /* i */,
74 : const unsigned int /* j */,
75 : const unsigned int /* qp */,
76 : AssemblyDatum & /* datum */) const
77 : {
78 0 : ::Kokkos::abort("Default computeQpJacobian() should never be called. Make sure you properly "
79 : "redefined this method in your class without typos.");
80 :
81 : return 0;
82 : }
83 : /**
84 : * Compute off-diagonal Jacobian contribution on a quadrature point
85 : * @tparam Derived The object type
86 : * @param i The test function DOF index
87 : * @param j The trial function DOF index
88 : * @param jvar The variable number for column
89 : * @param qp The local quadrature point index
90 : * @param datum The AssemblyDatum object of the current thread
91 : * @returns The off-diagonal Jacobian contribution
92 : */
93 : template <typename Derived>
94 0 : KOKKOS_FUNCTION Real computeQpOffDiagJacobian(const unsigned int /* i */,
95 : const unsigned int /* j */,
96 : const unsigned int /* jvar */,
97 : const unsigned int /* qp */,
98 : AssemblyDatum & /* datum */) const
99 : {
100 0 : ::Kokkos::abort(
101 : "Default computeQpOffDiagJacobian() should never be called. Make sure you properly "
102 : "redefined this method in your class without typos.");
103 :
104 : return 0;
105 : }
106 : ///@}
107 :
108 : /**
109 : * Functions used to check if users have overriden the hook methods, whose calculations can be
110 : * skipped when not overriden
111 : * @returns The function pointer of the default hook method
112 : */
113 : ///@{
114 : template <typename Derived>
115 80660 : static auto defaultJacobian()
116 : {
117 80660 : return &IntegratedBC::computeQpJacobian<Derived>;
118 : }
119 : template <typename Derived>
120 80660 : static auto defaultOffDiagJacobian()
121 : {
122 80660 : return &IntegratedBC::computeQpOffDiagJacobian<Derived>;
123 : }
124 : ///@}
125 :
126 : /**
127 : * The parallel computation entry functions called by Kokkos
128 : */
129 : ///@{
130 : template <typename Derived>
131 : KOKKOS_FUNCTION void operator()(ResidualLoop, const ThreadID tid, const Derived & bc) const;
132 : template <typename Derived>
133 : KOKKOS_FUNCTION void operator()(JacobianLoop, const ThreadID tid, const Derived & bc) const;
134 : template <typename Derived>
135 : KOKKOS_FUNCTION void
136 : operator()(OffDiagJacobianLoop, const ThreadID tid, const Derived & bc) const;
137 : ///@}
138 :
139 : /**
140 : * The parallel computation bodies that can be customized in the derived class by defining
141 : * them in the derived class with the same signature.
142 : * Make sure to define them as inlined public methods if to be defined in the derived class.
143 : */
144 : ///@{
145 : /**
146 : * Compute residual
147 : * @param bc The boundary condition object of the final derived type
148 : * @param datum The AssemblyDatum object of the current thread
149 : */
150 : template <typename Derived>
151 : KOKKOS_FUNCTION void computeResidualInternal(const Derived & bc, AssemblyDatum & datum) const;
152 : /**
153 : * Compute diagonal Jacobian
154 : * @param bc The boundary condition object of the final derived type
155 : * @param datum The AssemblyDatum object of the current thread
156 : */
157 : template <typename Derived>
158 : KOKKOS_FUNCTION void computeJacobianInternal(const Derived & bc, AssemblyDatum & datum) const;
159 : /**
160 : * Compute off-diagonal Jacobian
161 : * @param bc The boundary condition object of the final derived type
162 : * @param datum The AssemblyDatum object of the current thread
163 : */
164 : template <typename Derived>
165 : KOKKOS_FUNCTION void computeOffDiagJacobianInternal(const Derived & bc,
166 : AssemblyDatum & datum) const;
167 : ///@}
168 :
169 : protected:
170 : /**
171 : * Current test function
172 : */
173 : const VariableTestValue _test;
174 : /**
175 : * Gradient of the current test function
176 : */
177 : const VariableTestGradient _grad_test;
178 : /**
179 : * Current shape function
180 : */
181 : const VariablePhiValue _phi;
182 : /**
183 : * Gradient of the current shape function
184 : */
185 : const VariablePhiGradient _grad_phi;
186 : /**
187 : * Current solution at quadrature points
188 : */
189 : const VariableValue _u;
190 : /**
191 : * Gradient of the current solution at quadrature points
192 : */
193 : const VariableGradient _grad_u;
194 : };
195 :
196 : template <typename Derived>
197 : KOKKOS_FUNCTION void
198 465032 : IntegratedBC::operator()(ResidualLoop, const ThreadID tid, const Derived & bc) const
199 : {
200 465032 : auto [elem, side] = kokkosBoundaryElementSideID(_thread(tid, 1));
201 :
202 930064 : AssemblyDatum datum(
203 465032 : elem, side, kokkosAssembly(), kokkosSystems(), _kokkos_var, _kokkos_var.var());
204 :
205 465032 : datum.set_local_parallel(_thread(tid, 0), _thread.size(0));
206 :
207 465032 : bc.computeResidualInternal(bc, datum);
208 465032 : }
209 :
210 : template <typename Derived>
211 : KOKKOS_FUNCTION void
212 5360 : IntegratedBC::operator()(JacobianLoop, const ThreadID tid, const Derived & bc) const
213 : {
214 5360 : auto [elem, side] = kokkosBoundaryElementSideID(_thread(tid, 1));
215 :
216 10720 : AssemblyDatum datum(
217 5360 : elem, side, kokkosAssembly(), kokkosSystems(), _kokkos_var, _kokkos_var.var());
218 :
219 5360 : datum.set_local_parallel(_thread(tid, 0), _thread.size(0));
220 :
221 5360 : bc.computeJacobianInternal(bc, datum);
222 5360 : }
223 :
224 : template <typename Derived>
225 : KOKKOS_FUNCTION void
226 80 : IntegratedBC::operator()(OffDiagJacobianLoop, const ThreadID tid, const Derived & bc) const
227 : {
228 80 : auto [elem, side] = kokkosBoundaryElementSideID(_thread(tid, 2));
229 :
230 80 : auto & sys = kokkosSystem(_kokkos_var.sys());
231 80 : auto jvar = sys.getCoupling(_kokkos_var.var())[_thread(tid, 1)];
232 :
233 80 : if (!sys.isVariableActive(jvar, kokkosMesh().getElementInfo(elem).subdomain))
234 0 : return;
235 :
236 80 : AssemblyDatum datum(elem, side, kokkosAssembly(), kokkosSystems(), _kokkos_var, jvar);
237 :
238 80 : datum.set_local_parallel(_thread(tid, 0), _thread.size(0));
239 :
240 80 : bc.computeOffDiagJacobianInternal(bc, datum);
241 : }
242 :
243 : template <typename Derived>
244 : KOKKOS_FUNCTION void
245 138720 : IntegratedBC::computeResidualInternal(const Derived & bc, AssemblyDatum & datum) const
246 : {
247 138720 : ResidualObject::computeResidualInternal(
248 : datum,
249 277440 : [&](Real * local_re, const unsigned int ib, const unsigned int ie)
250 : {
251 476960 : for (unsigned int qp = 0; qp < datum.n_qps(); ++qp)
252 676480 : for (unsigned int i = ib; i < ie; ++i)
253 338240 : local_re[i] += datum.JxW(qp) * bc.template computeQpResidual<Derived>(i, qp, datum);
254 : });
255 138720 : }
256 :
257 : template <typename Derived>
258 : KOKKOS_FUNCTION void
259 4880 : IntegratedBC::computeJacobianInternal(const Derived & bc, AssemblyDatum & datum) const
260 : {
261 4880 : ResidualObject::computeJacobianInternal(
262 : datum,
263 9760 : [&](Real * local_ke, const unsigned int ib, const unsigned int ie, const unsigned int j)
264 : {
265 14640 : for (unsigned int qp = 0; qp < datum.n_qps(); ++qp)
266 48800 : for (unsigned int i = ib; i < ie; ++i)
267 39040 : local_ke[i] += datum.JxW(qp) * bc.template computeQpJacobian<Derived>(i, j, qp, datum);
268 : });
269 4880 : }
270 :
271 : template <typename Derived>
272 : KOKKOS_FUNCTION void
273 0 : IntegratedBC::computeOffDiagJacobianInternal(const Derived & bc, AssemblyDatum & datum) const
274 : {
275 0 : ResidualObject::computeJacobianInternal(
276 : datum,
277 0 : [&](Real * local_ke, const unsigned int ib, const unsigned int ie, const unsigned int j)
278 : {
279 0 : for (unsigned int qp = 0; qp < datum.n_qps(); ++qp)
280 0 : for (unsigned int i = ib; i < ie; ++i)
281 0 : local_ke[i] += datum.JxW(qp) * bc.template computeQpOffDiagJacobian<Derived>(
282 : i, j, datum.jvar(), qp, datum);
283 : });
284 0 : }
285 :
286 : } // namespace Moose::Kokkos
|