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 "KokkosTypes.h"
13 : #include "KokkosAssembly.h"
14 : #include "KokkosSystem.h"
15 : #include "KokkosVariable.h"
16 :
17 : namespace Moose::Kokkos
18 : {
19 :
20 : /**
21 : * The Kokkos object that holds thread-private data in the parallel operations of any Kokkos object
22 : */
23 : class Datum
24 : {
25 : public:
26 : /**
27 : * Constructor for element and side data
28 : * @param elem The contiguous element ID of the current thread
29 : * @param side The side index of the current thread
30 : * @param assembly The Kokkos assembly
31 : * @param systems The Kokkos systems
32 : */
33 : KOKKOS_FUNCTION
34 22753706 : Datum(const ContiguousElementID elem,
35 : const unsigned int side,
36 : const Assembly & assembly,
37 : const Array<System> & systems)
38 22753706 : : _assembly(assembly),
39 22753706 : _systems(systems),
40 22753706 : _mesh(assembly.kokkosMesh()),
41 22753706 : _elem(_mesh.getElementInfo(elem)),
42 22753706 : _side(side),
43 22753706 : _neighbor(!isSide() ? libMesh::DofObject::invalid_id : _mesh.getNeighbor(_elem.id, side)),
44 22753706 : _n_qps(!isSide() ? assembly.getNumQps(_elem) : assembly.getNumFaceQps(_elem, side)),
45 22753706 : _qp_offset(!isSide() ? assembly.getQpOffset(_elem) : assembly.getQpFaceOffset(_elem, side)),
46 22753706 : _elem_property_idx(!isSide()
47 22753706 : ? _elem.id - _mesh.getStartingContiguousElementID(_elem.subdomain)
48 45507412 : : assembly.getElemFacePropertyIndex(_elem, _side))
49 : {
50 22753706 : }
51 : /**
52 : * Constructor for node data
53 : * @param node The contiguous node ID of the current thread
54 : * @param assembly The Kokkos assembly
55 : * @param systems The Kokkos systems
56 : */
57 : KOKKOS_FUNCTION
58 3442344 : Datum(const ContiguousNodeID node, const Assembly & assembly, const Array<System> & systems)
59 3442344 : : _assembly(assembly), _systems(systems), _mesh(assembly.kokkosMesh()), _node(node)
60 : {
61 3442344 : }
62 :
63 : /**
64 : * Get the Kokkos assembly
65 : * @returns The Kokkos assembly
66 : */
67 211708800 : KOKKOS_FUNCTION const Assembly & assembly() const { return _assembly; }
68 : /**
69 : * Get the Kokkos system
70 : * @param sys The system number
71 : * @returns The Kokkos system
72 : */
73 83442670 : KOKKOS_FUNCTION const System & system(unsigned int sys) const { return _systems[sys]; }
74 : /**
75 : * Get the Kokkos mesh
76 : * @returns The Kokkos mesh
77 : */
78 : KOKKOS_FUNCTION const Mesh & mesh() const { return _mesh; }
79 :
80 : /**
81 : * Get the element information object
82 : * @returns The element information object
83 : */
84 320179901 : KOKKOS_FUNCTION const ElementInfo & elem() const { return _elem; }
85 : /**
86 : * Get the contiguous element ID
87 : * @returns The contiguous element ID
88 : */
89 307272 : KOKKOS_FUNCTION ContiguousElementID elemID() const { return _elem.id; }
90 : /**
91 : * Get the extra element ID
92 : * @param index The extra element ID index
93 : * @returns The extra element ID
94 : */
95 500 : KOKKOS_FUNCTION dof_id_type extraElemID(unsigned int index) const
96 : {
97 500 : return isNodal() ? libMesh::DofObject::invalid_id : _mesh.getExtraElementID(_elem.id, index);
98 : }
99 : /**
100 : * Get the contiguous subdomain ID
101 : * @returns The contiguous subdomain ID
102 : */
103 80934610 : KOKKOS_FUNCTION ContiguousSubdomainID subdomain() const { return _elem.subdomain; }
104 : /**
105 : * Get the side index
106 : * @returns The side index
107 : */
108 290796160 : KOKKOS_FUNCTION unsigned int side() const { return _side; }
109 : /**
110 : * Get the contiguous node ID
111 : * @returns The contiguous node ID
112 : */
113 5718882 : KOKKOS_FUNCTION ContiguousNodeID node() const { return _node; }
114 : /**
115 : * Get the number of local quadrature points
116 : * @returns The number of local quadrature points
117 : */
118 112741497 : KOKKOS_FUNCTION unsigned int n_qps() const { return _n_qps; }
119 : /**
120 : * Get the starting offset into the global quadrature point index
121 : * @returns The starting offset
122 : */
123 78806948 : KOKKOS_FUNCTION dof_id_type qpOffset() const { return _qp_offset; }
124 : /**
125 : * Get the index into the property data storage
126 : * @param constant_option The property constant option
127 : * @param qp The local quadrature point index
128 : * @returns The index
129 : */
130 : KOKKOS_FUNCTION dof_id_type propertyIdx(const PropertyConstantOption constant_option,
131 : const unsigned int qp) const;
132 : /**
133 : * Get whether the current side has a neighbor
134 : * @returns Whether the current side has a neighbor
135 : */
136 : KOKKOS_FUNCTION bool hasNeighbor() const { return _neighbor != libMesh::DofObject::invalid_id; }
137 : /**
138 : * Get whether the current datum is on a side
139 : * @returns Whether the current datum is on a side
140 : */
141 181293272 : KOKKOS_FUNCTION bool isSide() const { return _side != libMesh::invalid_uint; }
142 : /**
143 : * Get whether the current datum is on a node
144 : * @returns Whether the current datum is on a node
145 : */
146 235987810 : KOKKOS_FUNCTION bool isNodal() const { return _node != libMesh::DofObject::invalid_id; }
147 : /**
148 : * Get whether the a variable is defined on the current node
149 : * @param var The variable
150 : * @returns Whether the variable is defined on the current node
151 : */
152 : KOKKOS_FUNCTION bool isNodalDefined(const Variable & var) const;
153 :
154 : /**
155 : * Get the inverse of Jacobian matrix
156 : * | dxi/dx deta/dx dzeta/dx |
157 : * | dxi/dy deta/dy dzeta/dy |
158 : * | dxi/dz deta/dz dzeta/dz |
159 : * @param qp The local quadrature point index
160 : * @returns The Jacobian matrix
161 : */
162 : KOKKOS_FUNCTION const Real33 & J(const unsigned int qp);
163 : /**
164 : * Get the transformed Jacobian weight
165 : * @param qp The local quadrature point index
166 : * @returns The transformed Jacobian weights
167 : */
168 : KOKKOS_FUNCTION Real JxW(const unsigned int qp);
169 : /**
170 : * Get the physical quadrature point coordinate
171 : * @param qp The local quadrature point index
172 : * @returns The physical quadrature point coordinate
173 : */
174 : KOKKOS_FUNCTION Real3 q_point(const unsigned int qp);
175 : /**
176 : * Get the normal vector on surface
177 : * @param qp The local quadrature point index
178 : * @returns The normal vector
179 : */
180 : KOKKOS_FUNCTION Real3 normals(const unsigned int qp);
181 :
182 : /**
183 : * Set local parallelization option
184 : * @param local_thread_id The current local thread ID
185 : * @param num_local_threads The number of local threads
186 : */
187 20773492 : KOKKOS_FUNCTION void set_local_parallel(const unsigned int local_thread_id,
188 : const unsigned int num_local_threads)
189 : {
190 20773492 : _local_thread_id = local_thread_id;
191 20773492 : _num_local_threads = num_local_threads;
192 20773492 : }
193 : /**
194 : * Get the current local thread ID
195 : * @returns The current local thread ID
196 : */
197 20773492 : KOKKOS_FUNCTION unsigned int local_thread_id() const { return _local_thread_id; }
198 : /**
199 : * Get the number of local threads
200 : * @returns The number of local threads
201 : */
202 54302784 : KOKKOS_FUNCTION unsigned int num_local_threads() const { return _num_local_threads; }
203 :
204 : protected:
205 : /**
206 : * Reference of the Kokkos assembly
207 : */
208 : const Assembly & _assembly;
209 : /**
210 : * Reference of the Kokkos systems
211 : */
212 : const Array<System> & _systems;
213 : /**
214 : * Reference of the Kokkos mesh
215 : */
216 : const Mesh & _mesh;
217 : /**
218 : * Current element information object
219 : */
220 : const ElementInfo _elem;
221 : /**
222 : * Current side index
223 : */
224 : const unsigned int _side = libMesh::invalid_uint;
225 : /**
226 : * Current contiguous node ID
227 : */
228 : const ContiguousNodeID _node = libMesh::DofObject::invalid_id;
229 : /**
230 : * Current contiguous element ID of neighbor
231 : */
232 : const ContiguousElementID _neighbor = libMesh::DofObject::invalid_id;
233 : /**
234 : * Number of local quadrature points
235 : */
236 : const unsigned int _n_qps = 1;
237 : /**
238 : * Starting offset into the global quadrature point index
239 : */
240 : const dof_id_type _qp_offset = libMesh::DofObject::invalid_id;
241 : /**
242 : * Index for element-constant material properties
243 : */
244 : const dof_id_type _elem_property_idx = libMesh::DofObject::invalid_id;
245 :
246 : private:
247 : /**
248 : * Compute and cache the physical transformation data
249 : * @param qp The local quadrature point index
250 : */
251 : KOKKOS_FUNCTION void reinitTransform(const unsigned int qp);
252 :
253 : /**
254 : * Cached quadrature point index for checking whether the physical transformation data should be
255 : * recomputed
256 : */
257 : unsigned int _cached_qp = libMesh::invalid_uint;
258 : /**
259 : * Cached physical transformation data
260 : */
261 : ///@{
262 : Real33 _J;
263 : Real _JxW;
264 : Real3 _xyz;
265 : Real3 _normal;
266 : ///@}
267 : /**
268 : * Thread ID for local parallelization
269 : */
270 : unsigned int _local_thread_id = 0;
271 : /**
272 : * Number of threads for local parallelization
273 : */
274 : unsigned int _num_local_threads = 1;
275 : };
276 :
277 : KOKKOS_FUNCTION inline dof_id_type
278 40059305 : Datum::propertyIdx(const PropertyConstantOption constant_option, const unsigned int qp) const
279 : {
280 40059305 : dof_id_type idx = 0;
281 :
282 40059305 : if (constant_option == PropertyConstantOption::NONE)
283 39491900 : idx = _qp_offset + qp;
284 567405 : else if (constant_option == PropertyConstantOption::ELEMENT)
285 263250 : idx = _elem_property_idx;
286 :
287 40059305 : return idx;
288 : }
289 :
290 : KOKKOS_FUNCTION inline bool
291 152946 : Datum::isNodalDefined(const Variable & var) const
292 : {
293 152946 : if (!isNodal() || !var.nodal())
294 0 : return false;
295 :
296 152946 : return _systems[var.sys()].isNodalDefined(_node, var.var());
297 : }
298 :
299 : KOKKOS_FUNCTION inline const Real33 &
300 95970496 : Datum::J(const unsigned int qp)
301 : {
302 95970496 : if (!isNodal())
303 95970496 : reinitTransform(qp);
304 : else
305 0 : _J.identity(_assembly.getDimension());
306 :
307 95970496 : return _J;
308 : }
309 :
310 : KOKKOS_FUNCTION inline Real
311 117907320 : Datum::JxW(const unsigned int qp)
312 : {
313 117907320 : if (!isNodal())
314 117907320 : reinitTransform(qp);
315 : else
316 0 : _JxW = 1;
317 :
318 117907320 : return _JxW;
319 : }
320 :
321 : KOKKOS_FUNCTION inline Real3
322 17601190 : Datum::q_point(const unsigned int qp)
323 : {
324 17601190 : if (!isNodal())
325 17160824 : reinitTransform(qp);
326 : else
327 440366 : _xyz = _assembly.kokkosMesh().getNodePoint(_node);
328 :
329 17601190 : return _xyz;
330 : }
331 :
332 : KOKKOS_FUNCTION inline Real3
333 8416 : Datum::normals(const unsigned int qp)
334 : {
335 : KOKKOS_ASSERT(isSide());
336 :
337 8416 : if (isSide())
338 8416 : reinitTransform(qp);
339 :
340 8416 : return _normal;
341 : }
342 :
343 : KOKKOS_FUNCTION inline void
344 231047056 : Datum::reinitTransform(const unsigned int qp)
345 : {
346 231047056 : if (_cached_qp == qp)
347 140777024 : return;
348 :
349 90270032 : if (!isSide())
350 : {
351 89206752 : _J = _assembly.getJacobian(_elem, qp);
352 89206752 : _JxW = _assembly.getJxW(_elem, qp);
353 89206752 : _xyz = _assembly.getQPoint(_elem, qp);
354 : }
355 : else
356 1063280 : _assembly.computePhysicalMap(_elem, _side, qp, &_J, &_JxW, &_xyz, &_normal);
357 :
358 90270032 : _cached_qp = qp;
359 : }
360 :
361 : /**
362 : * The Kokkos object that holds thread-private data in the parallel operations of Kokkos kernels
363 : */
364 : class AssemblyDatum : public Datum
365 : {
366 : public:
367 : /**
368 : * Constructor for element and side data
369 : * @param elem The contiguous element ID of the current thread
370 : * @param side The side index of the current thread
371 : * @param assembly The Kokkos assembly
372 : * @param systems The Kokkos systems
373 : * @param ivar The Kokkos variable
374 : * @param jvar The coupled variable number
375 : * @param comp The variable component
376 : */
377 : KOKKOS_FUNCTION
378 21007292 : AssemblyDatum(const ContiguousElementID elem,
379 : const unsigned int side,
380 : const Assembly & assembly,
381 : const Array<System> & systems,
382 : const Variable & ivar,
383 : const unsigned int jvar,
384 : const unsigned int comp = 0)
385 21007292 : : Datum(elem, side, assembly, systems),
386 21007292 : _tag(ivar.tag()),
387 21007292 : _sys(ivar.sys(comp)),
388 21007292 : _ivar(ivar.var(comp)),
389 21007292 : _jvar(jvar),
390 21007292 : _ife(systems[ivar.sys(comp)].getFETypeID(_ivar)),
391 21007292 : _jfe(systems[ivar.sys(comp)].getFETypeID(_jvar)),
392 21007292 : _n_idofs(assembly.getNumDofs(_elem.type, _ife)),
393 42014584 : _n_jdofs(assembly.getNumDofs(_elem.type, _jfe))
394 : {
395 21007292 : }
396 : /**
397 : * Constructor for node data
398 : * @param elem The contiguous element ID of the current thread
399 : * @param assembly The Kokkos assembly
400 : * @param systems The Kokkos systems
401 : * @param ivar The Kokkos variable
402 : * @param jvar The coupled variable number
403 : * @param comp The variable component
404 : */
405 : KOKKOS_FUNCTION
406 3288576 : AssemblyDatum(const ContiguousNodeID node,
407 : const Assembly & assembly,
408 : const Array<System> & systems,
409 : const Variable & ivar,
410 : const unsigned int jvar,
411 : const unsigned int comp = 0)
412 3288576 : : Datum(node, assembly, systems),
413 3288576 : _tag(ivar.tag()),
414 3288576 : _sys(ivar.sys(comp)),
415 3288576 : _ivar(ivar.var(comp)),
416 3288576 : _jvar(jvar),
417 3288576 : _ife(systems[ivar.sys(comp)].getFETypeID(_ivar)),
418 6577152 : _jfe(systems[ivar.sys(comp)].getFETypeID(_jvar))
419 : {
420 3288576 : }
421 :
422 : /**
423 : * Get the number of local DOFs
424 : * @returns The number of local DOFs
425 : */
426 177059260 : KOKKOS_FUNCTION unsigned int n_dofs() const { return _n_idofs; }
427 : /**
428 : * Get the number of local DOFs
429 : * @returns The number of local DOFs
430 : */
431 7374972 : KOKKOS_FUNCTION unsigned int n_idofs() const { return _n_idofs; }
432 : /**
433 : * Get the number of local DOFs for the coupled variable
434 : * @returns The number of local DOFs
435 : */
436 5121848 : KOKKOS_FUNCTION unsigned int n_jdofs() const { return _n_jdofs; }
437 : /**
438 : * Get the system number of variable
439 : * @returns The system number of variable
440 : */
441 4381978 : KOKKOS_FUNCTION unsigned int sys() const { return _sys; }
442 : /**
443 : * Get the variable number
444 : * @returns The variable number
445 : */
446 : KOKKOS_FUNCTION unsigned int var() const { return _ivar; }
447 : /**
448 : * Get the variable number
449 : * @returns The variable number
450 : */
451 : KOKKOS_FUNCTION unsigned int ivar() const { return _ivar; }
452 : /**
453 : * Get the coupled variable number
454 : * @returns The variable number
455 : */
456 10015672 : KOKKOS_FUNCTION unsigned int jvar() const { return _jvar; }
457 : /**
458 : * Get the variable FE type ID
459 : * @returns The variable FE type ID
460 : */
461 : KOKKOS_FUNCTION unsigned int fe() const { return _ife; }
462 : /**
463 : * Get the variable FE type ID
464 : * @returns The variable FE type ID
465 : */
466 181415928 : KOKKOS_FUNCTION unsigned int ife() const { return _ife; }
467 : /**
468 : * Get the coupled variable FE type ID
469 : * @returns The variable FE type ID
470 : */
471 30292872 : KOKKOS_FUNCTION unsigned int jfe() const { return _jfe; }
472 : /**
473 : * Set whether to compute derivatives for automatic differentiation (AD)
474 : * @param flag Whether to compute derivatives
475 : */
476 1292796 : KOKKOS_FUNCTION void do_derivatives(const bool flag) { _do_derivatives = flag; }
477 : /**
478 : * Get whether to compute derivatives for automatic differentiation (AD)
479 : * @returns Whether to compute derivatives
480 : */
481 4738908 : KOKKOS_FUNCTION bool do_derivatives() const { return _do_derivatives; }
482 :
483 : protected:
484 : /**
485 : * Solution tag ID
486 : */
487 : const TagID _tag;
488 : /**
489 : * System number
490 : */
491 : const unsigned int _sys;
492 : /**
493 : * Variable numbers
494 : */
495 : const unsigned int _ivar, _jvar;
496 : /**
497 : * FE type IDs of variables
498 : */
499 : const unsigned int _ife, _jfe;
500 : /**
501 : * Number of local DOFs
502 : */
503 : const unsigned int _n_idofs = 1, _n_jdofs = 1;
504 : /**
505 : * Whether to compute derivatives for automatic differentiation (AD)
506 : */
507 : bool _do_derivatives = true;
508 : };
509 :
510 : } // namespace Moose::Kokkos
511 :
512 : using Datum = Moose::Kokkos::Datum;
513 : using AssemblyDatum = Moose::Kokkos::AssemblyDatum;
|