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.
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 NodalBC : public NodalBCBase
37 : {
38 : public:
39 : static InputParameters validParams();
40 :
41 : /**
42 : * Constructor
43 : */
44 : NodalBC(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 55183 : KOKKOS_FUNCTION Real computeQpJacobian(const unsigned int /* qp */,
69 : AssemblyDatum & /* datum */) const
70 : {
71 55183 : return 1;
72 : }
73 : /**
74 : * Compute off-diagonal Jacobian contribution on a node
75 : * @tparam Derived The object type
76 : * @param jvar The variable number for column
77 : * @param qp The dummy quadrature point index (= 0)
78 : * @param datum The AssemblyDatum object of the current thread
79 : * @returns The off-diagonal Jacobian contribution
80 : */
81 : template <typename Derived>
82 0 : KOKKOS_FUNCTION Real computeQpOffDiagJacobian(const unsigned int /* jvar */,
83 : const unsigned int /* qp */,
84 : AssemblyDatum & /* datum */) const
85 : {
86 0 : ::Kokkos::abort(
87 : "Default computeQpOffDiagJacobian() should never be called. Make sure you properly "
88 : "redefined this method in your class without typos.");
89 :
90 : return 0;
91 : }
92 : ///@}
93 :
94 : /**
95 : * Functions used to check if users have overriden the hook methods, whose calculations can be
96 : * skipped when not overriden
97 : * @returns The function pointer of the default hook method
98 : */
99 : ///@{
100 : template <typename Derived>
101 161395 : static auto defaultJacobian()
102 : {
103 161395 : return &NodalBC::computeQpJacobian<Derived>;
104 : }
105 : template <typename Derived>
106 161395 : static auto defaultOffDiagJacobian()
107 : {
108 161395 : return &NodalBC::computeQpOffDiagJacobian<Derived>;
109 : }
110 : ///@}
111 :
112 : /**
113 : * The parallel computation entry functions called by Kokkos
114 : */
115 : ///@{
116 : template <typename Derived>
117 : KOKKOS_FUNCTION void operator()(ResidualLoop, const ThreadID tid, const Derived & bc) const;
118 : template <typename Derived>
119 : KOKKOS_FUNCTION void operator()(JacobianLoop, const ThreadID tid, const Derived & bc) const;
120 : template <typename Derived>
121 : KOKKOS_FUNCTION void
122 : operator()(OffDiagJacobianLoop, const ThreadID tid, const Derived & bc) const;
123 : ///@}
124 :
125 : protected:
126 : /**
127 : * Current solution at nodes
128 : */
129 : const VariableValue _u;
130 : };
131 :
132 : template <typename Derived>
133 : KOKKOS_FUNCTION void
134 397000 : NodalBC::operator()(ResidualLoop, const ThreadID tid, const Derived & bc) const
135 : {
136 397000 : auto node = kokkosBoundaryNodeID(tid);
137 397000 : auto & sys = kokkosSystem(_kokkos_var.sys());
138 :
139 397000 : if (!sys.isNodalDefined(node, _kokkos_var.var()))
140 0 : return;
141 :
142 397000 : AssemblyDatum datum(node, kokkosAssembly(), kokkosSystems(), _kokkos_var, _kokkos_var.var());
143 :
144 397000 : Real local_re = bc.template computeQpResidual<Derived>(0, datum);
145 :
146 397000 : accumulateTaggedNodalResidual(false, local_re, node);
147 : }
148 :
149 : template <typename Derived>
150 : KOKKOS_FUNCTION void
151 55579 : NodalBC::operator()(JacobianLoop, const ThreadID tid, const Derived & bc) const
152 : {
153 55579 : auto node = kokkosBoundaryNodeID(tid);
154 55579 : auto & sys = kokkosSystem(_kokkos_var.sys());
155 :
156 55579 : if (!sys.isNodalDefined(node, _kokkos_var.var()))
157 0 : return;
158 :
159 55579 : AssemblyDatum datum(node, kokkosAssembly(), kokkosSystems(), _kokkos_var, _kokkos_var.var());
160 :
161 55579 : Real local_ke = bc.template computeQpJacobian<Derived>(0, datum);
162 :
163 : // This initializes the row to zero except the diagonal
164 55579 : accumulateTaggedNodalMatrix(false, local_ke, node, _kokkos_var.var());
165 : }
166 :
167 : template <typename Derived>
168 : KOKKOS_FUNCTION void
169 414 : NodalBC::operator()(OffDiagJacobianLoop, const ThreadID tid, const Derived & bc) const
170 : {
171 414 : auto node = kokkosBoundaryNodeID(_thread(tid, 1));
172 414 : auto & sys = kokkosSystem(_kokkos_var.sys());
173 414 : auto jvar = sys.getCoupling(_kokkos_var.var())[_thread(tid, 0)];
174 :
175 414 : if (!sys.isNodalDefined(node, _kokkos_var.var()))
176 0 : return;
177 :
178 414 : AssemblyDatum datum(node, kokkosAssembly(), kokkosSystems(), _kokkos_var, jvar);
179 :
180 414 : Real local_ke = bc.template computeQpOffDiagJacobian<Derived>(jvar, 0, datum);
181 :
182 414 : accumulateTaggedNodalMatrix(true, local_ke, node, jvar);
183 : }
184 :
185 : } // namespace Moose::Kokkos
|