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 on vector
19 : * variables.
20 : */
21 : class VectorIntegratedBC : public IntegratedBCBase
22 : {
23 : public:
24 : static InputParameters validParams();
25 :
26 : /**
27 : * Constructor
28 : */
29 : VectorIntegratedBC(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 0 : KOKKOS_FUNCTION Real computeQpJacobian(const unsigned int /* i */,
47 : const unsigned int /* j */,
48 : const unsigned int /* qp */,
49 : AssemblyDatum & /* datum */) const
50 : {
51 0 : ::Kokkos::abort("Default computeQpJacobian() should never be called. Make sure you properly "
52 : "redefined this method in your class without typos.");
53 :
54 : return 0;
55 : }
56 : template <typename Derived>
57 0 : KOKKOS_FUNCTION Real computeQpOffDiagJacobian(const unsigned int /* i */,
58 : const unsigned int /* j */,
59 : const unsigned int /* jvar */,
60 : const unsigned int /* qp */,
61 : AssemblyDatum & /* datum */) const
62 : {
63 0 : ::Kokkos::abort(
64 : "Default computeQpOffDiagJacobian() should never be called. Make sure you properly "
65 : "redefined this method in your class without typos.");
66 :
67 : return 0;
68 : }
69 : ///@}
70 :
71 : /**
72 : * Functions used to check if users have overriden the hook methods, whose calculations can be
73 : * skipped when not overriden
74 : */
75 : ///@{
76 : template <typename Derived>
77 41399 : static auto defaultJacobian()
78 : {
79 41399 : return &VectorIntegratedBC::computeQpJacobian<Derived>;
80 : }
81 : template <typename Derived>
82 41399 : static auto defaultOffDiagJacobian()
83 : {
84 41399 : return &VectorIntegratedBC::computeQpOffDiagJacobian<Derived>;
85 : }
86 : ///@}
87 :
88 : /**
89 : * The parallel computation entry functions called by Kokkos
90 : */
91 : ///@{
92 : template <typename Derived>
93 : KOKKOS_FUNCTION void operator()(ResidualLoop, const ThreadID tid, const Derived & bc) const;
94 : template <typename Derived>
95 : KOKKOS_FUNCTION void operator()(JacobianLoop, const ThreadID tid, const Derived & bc) const;
96 : template <typename Derived>
97 : KOKKOS_FUNCTION void
98 : operator()(OffDiagJacobianLoop, const ThreadID tid, const Derived & bc) const;
99 : ///@}
100 :
101 : /**
102 : * The parallel computation bodies that can be customized in the derived class by defining
103 : * them in the derived class with the same signature.
104 : */
105 : ///@{
106 : template <typename Derived>
107 : KOKKOS_FUNCTION void computeResidualInternal(const Derived & bc, AssemblyDatum & datum) const;
108 : template <typename Derived>
109 : KOKKOS_FUNCTION void computeJacobianInternal(const Derived & bc, AssemblyDatum & datum) const;
110 : template <typename Derived>
111 : KOKKOS_FUNCTION void computeOffDiagJacobianInternal(const Derived & bc,
112 : AssemblyDatum & datum) const;
113 : ///@}
114 :
115 : protected:
116 : /**
117 : * Current vector test function
118 : */
119 : const VectorVariableTestValue _test;
120 : /**
121 : * Gradient of the current vector test function
122 : */
123 : const VectorVariableTestGradient _grad_test;
124 : /**
125 : * Current vector shape function
126 : */
127 : const VectorVariablePhiValue _phi;
128 : /**
129 : * Gradient of the current vector shape function
130 : */
131 : const VectorVariablePhiGradient _grad_phi;
132 : /**
133 : * Current vector solution at quadrature points
134 : */
135 : const VectorVariableValue _u;
136 : /**
137 : * Gradient of the current vector solution at quadrature points
138 : */
139 : const VectorVariableGradient _grad_u;
140 : };
141 :
142 : template <typename Derived>
143 : KOKKOS_FUNCTION void
144 3360 : VectorIntegratedBC::operator()(ResidualLoop, const ThreadID tid, const Derived & bc) const
145 : {
146 3360 : auto [elem, side] = kokkosBoundaryElementSideID(_thread(tid, 1));
147 :
148 6720 : AssemblyDatum datum(
149 3360 : elem, side, kokkosAssembly(), kokkosSystems(), _kokkos_var, _kokkos_var.var());
150 :
151 3360 : datum.set_local_parallel(_thread(tid, 0), _thread.size(0));
152 :
153 3360 : bc.computeResidualInternal(bc, datum);
154 3360 : }
155 :
156 : template <typename Derived>
157 : KOKKOS_FUNCTION void
158 1920 : VectorIntegratedBC::operator()(JacobianLoop, const ThreadID tid, const Derived & bc) const
159 : {
160 1920 : auto [elem, side] = kokkosBoundaryElementSideID(_thread(tid, 1));
161 :
162 3840 : AssemblyDatum datum(
163 1920 : elem, side, kokkosAssembly(), kokkosSystems(), _kokkos_var, _kokkos_var.var());
164 :
165 1920 : datum.set_local_parallel(_thread(tid, 0), _thread.size(0));
166 :
167 1920 : bc.computeJacobianInternal(bc, datum);
168 1920 : }
169 :
170 : template <typename Derived>
171 : KOKKOS_FUNCTION void
172 0 : VectorIntegratedBC::operator()(OffDiagJacobianLoop, const ThreadID tid, const Derived & bc) const
173 : {
174 0 : auto [elem, side] = kokkosBoundaryElementSideID(_thread(tid, 2));
175 :
176 0 : auto & sys = kokkosSystem(_kokkos_var.sys());
177 0 : auto jvar = sys.getCoupling(_kokkos_var.var())[_thread(tid, 1)];
178 :
179 0 : if (!sys.isVariableActive(jvar, kokkosMesh().getElementInfo(elem).subdomain))
180 0 : return;
181 :
182 0 : AssemblyDatum datum(elem, side, kokkosAssembly(), kokkosSystems(), _kokkos_var, jvar);
183 :
184 0 : datum.set_local_parallel(_thread(tid, 0), _thread.size(0));
185 :
186 0 : bc.computeOffDiagJacobianInternal(bc, datum);
187 : }
188 :
189 : template <typename Derived>
190 : KOKKOS_FUNCTION void
191 3360 : VectorIntegratedBC::computeResidualInternal(const Derived & bc, AssemblyDatum & datum) const
192 : {
193 3360 : ResidualObject::computeResidualInternal(
194 : datum,
195 6720 : [&](Real * local_re, const unsigned int ib, const unsigned int ie)
196 : {
197 10080 : for (unsigned int qp = 0; qp < datum.n_qps(); ++qp)
198 60480 : for (unsigned int i = ib; i < ie; ++i)
199 53760 : local_re[i] += datum.JxW(qp) * bc.template computeQpResidual<Derived>(i, qp, datum);
200 : });
201 3360 : }
202 :
203 : template <typename Derived>
204 : KOKKOS_FUNCTION void
205 1920 : VectorIntegratedBC::computeJacobianInternal(const Derived & bc, AssemblyDatum & datum) const
206 : {
207 1920 : ResidualObject::computeJacobianInternal(
208 : datum,
209 30720 : [&](Real * local_ke, const unsigned int ib, const unsigned int ie, const unsigned int j)
210 : {
211 46080 : for (unsigned int qp = 0; qp < datum.n_qps(); ++qp)
212 276480 : for (unsigned int i = ib; i < ie; ++i)
213 245760 : local_ke[i] += datum.JxW(qp) * bc.template computeQpJacobian<Derived>(i, j, qp, datum);
214 : });
215 1920 : }
216 :
217 : template <typename Derived>
218 : KOKKOS_FUNCTION void
219 0 : VectorIntegratedBC::computeOffDiagJacobianInternal(const Derived & bc, AssemblyDatum & datum) const
220 : {
221 0 : ResidualObject::computeJacobianInternal(
222 : datum,
223 0 : [&](Real * local_ke, const unsigned int ib, const unsigned int ie, const unsigned int j)
224 : {
225 0 : for (unsigned int qp = 0; qp < datum.n_qps(); ++qp)
226 0 : for (unsigned int i = ib; i < ie; ++i)
227 0 : local_ke[i] += datum.JxW(qp) * bc.template computeQpOffDiagJacobian<Derived>(
228 : i, j, datum.jvar(), qp, datum);
229 : });
230 0 : }
231 :
232 : } // namespace Moose::Kokkos
|