https://mooseframework.inl.gov
KokkosAssembly.h
Go to the documentation of this file.
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 
14 #include "MooseMesh.h"
15 
16 #include "libmesh/elem_range.h"
17 #include "libmesh/fe_base.h"
18 #include "libmesh/fe_type.h"
19 
20 class FEProblemBase;
21 
22 namespace Moose::Kokkos
23 {
24 
28 class Assembly : public MeshHolder
29 {
30 public:
35  Assembly(FEProblemBase & problem);
39  void init();
40 
41 #ifdef MOOSE_KOKKOS_SCOPE
42 
47  unsigned int getFETypeID(FEType type) const { return libmesh_map_find(_fe_type_map, type); }
52  KOKKOS_FUNCTION unsigned int getDimension() const { return _dimension; }
57  KOKKOS_FUNCTION unsigned int getMaxQpsPerElem() const { return _max_qps_per_elem; }
63  KOKKOS_FUNCTION dof_id_type getNumQps(ContiguousSubdomainID subdomain) const
64  {
65  return _n_subdomain_qps[subdomain];
66  }
72  KOKKOS_FUNCTION unsigned int getNumQps(ElementInfo info) const { return _n_qps[info.id]; }
80  KOKKOS_FUNCTION dof_id_type getNumFaceQps(ContiguousSubdomainID subdomain) const
81  {
82  return _n_subdomain_qps_face[subdomain];
83  }
90  KOKKOS_FUNCTION unsigned int getNumFaceQps(ElementInfo info, unsigned int side) const
91  {
92  return _n_qps_face(side, info.id);
93  }
100  KOKKOS_FUNCTION dof_id_type getQpOffset(ElementInfo info) const { return _qp_offset[info.id]; }
108  KOKKOS_FUNCTION dof_id_type getQpFaceOffset(ElementInfo info, unsigned int side) const
109  {
110  return _qp_offset_face(side, info.id);
111  }
118  KOKKOS_FUNCTION dof_id_type getElemFacePropertyIndex(ElementInfo info, unsigned int side) const
119  {
120  return _elem_face_property_idx(side, info.id);
121  }
128  {
129  return _n_elem_face_properties[subdomain];
130  }
137  KOKKOS_FUNCTION unsigned int getNumDofs(unsigned int elem_type, unsigned int fe_type) const
138  {
139  return _n_dofs(elem_type, fe_type);
140  }
148  KOKKOS_FUNCTION const auto &
149  getPhi(ContiguousSubdomainID subdomain, unsigned int elem_type, unsigned int fe_type) const
150  {
151  return _phi(subdomain, elem_type, fe_type);
152  }
160  KOKKOS_FUNCTION const auto &
161  getPhiFace(ContiguousSubdomainID subdomain, unsigned int elem_type, unsigned int fe_type) const
162  {
163  return _phi_face(subdomain, elem_type, fe_type);
164  }
172  KOKKOS_FUNCTION const auto &
173  getGradPhi(ContiguousSubdomainID subdomain, unsigned int elem_type, unsigned int fe_type) const
174  {
175  return _grad_phi(subdomain, elem_type, fe_type);
176  }
184  KOKKOS_FUNCTION const auto & getGradPhiFace(ContiguousSubdomainID subdomain,
185  unsigned int elem_type,
186  unsigned int fe_type) const
187  {
188  return _grad_phi_face(subdomain, elem_type, fe_type);
189  }
197  KOKKOS_FUNCTION const auto &
198  getVectorPhi(ContiguousSubdomainID subdomain, unsigned int elem_type, unsigned int fe_type) const
199  {
200  return _vector_phi(subdomain, elem_type, fe_type);
201  }
209  KOKKOS_FUNCTION const auto & getVectorPhiFace(ContiguousSubdomainID subdomain,
210  unsigned int elem_type,
211  unsigned int fe_type) const
212  {
213  return _vector_phi_face(subdomain, elem_type, fe_type);
214  }
222  KOKKOS_FUNCTION const auto & getVectorGradPhi(ContiguousSubdomainID subdomain,
223  unsigned int elem_type,
224  unsigned int fe_type) const
225  {
226  return _vector_grad_phi(subdomain, elem_type, fe_type);
227  }
235  KOKKOS_FUNCTION const auto & getVectorGradPhiFace(ContiguousSubdomainID subdomain,
236  unsigned int elem_type,
237  unsigned int fe_type) const
238  {
239  return _vector_grad_phi_face(subdomain, elem_type, fe_type);
240  }
246  KOKKOS_FUNCTION bool isVectorFEType(unsigned int fe_type) const
247  {
248  return _is_vector_fe_type[fe_type];
249  }
256  KOKKOS_FUNCTION Real33 getJacobian(ElementInfo info, unsigned int qp) const
257  {
258  return _jacobian[info.subdomain][getQpOffset(info) + qp];
259  }
266  KOKKOS_FUNCTION Real getJxW(ElementInfo info, unsigned int qp) const
267  {
268  return _jxw[info.subdomain][getQpOffset(info) + qp];
269  }
276  KOKKOS_FUNCTION Real3 getQPoint(ElementInfo info, unsigned int qp) const
277  {
278  return _xyz[info.subdomain][getQpOffset(info) + qp];
279  }
280 
287  KOKKOS_FUNCTION Real coordTransformFactor(const ContiguousSubdomainID subdomain,
288  const Real3 point) const;
297  KOKKOS_FUNCTION void computePhysicalMap(const ElementInfo info,
298  const unsigned int qp,
299  Real33 * const jacobian,
300  Real * const JxW,
301  Real3 * const q_points) const;
312  KOKKOS_FUNCTION void computePhysicalMap(const ElementInfo info,
313  const unsigned int side,
314  const unsigned int qp,
315  Real33 * const jacobian,
316  Real * const JxW,
317  Real3 * const q_points,
318  Real3 * const normal) const;
319 
323  KOKKOS_FUNCTION void operator()(const ThreadID tid) const;
324 
329  const auto & getMaterialBoundaries() const { return _material_boundaries; }
330 #endif
331 
332 private:
336  void initQuadrature();
340  void initShape();
344  void cachePhysicalMap();
345 
357  std::map<FEType, unsigned int> _fe_type_map;
358 
362  const unsigned int _dimension;
375 
384 
390 
391  unsigned int _max_qps_per_elem = 0;
392 
396 
403 
412 
427 
438 
445 
453 
457  std::set<BoundaryID> _material_boundaries;
458 };
459 
460 #ifdef MOOSE_KOKKOS_SCOPE
461 KOKKOS_FUNCTION inline Real
463 {
464  switch (_coord_type[subdomain])
465  {
466  case Moose::COORD_XYZ:
467  return 1;
468  case Moose::COORD_RZ:
470  return 2 * M_PI *
471  (point - _rz_axis[subdomain].first).cross_product(_rz_axis[subdomain].second).norm();
472  else
473  return 2 * M_PI * point(_rz_radial_coord);
475  return 4 * M_PI * point(0) * point(0);
476  default:
477  return 0;
478  }
479 }
480 
481 KOKKOS_FUNCTION inline void
483  const unsigned int qp,
484  Real33 * const jacobian,
485  Real * const JxW,
486  Real3 * const q_points) const
487 {
488  auto sid = info.subdomain;
489  auto eid = info.id;
490  auto elem_type = info.type;
491  auto num_nodes = kokkosMesh().getNumNodes(elem_type);
492 
493  auto & phi = _map_phi(sid, elem_type);
494  auto & grad_phi = _map_grad_phi(sid, elem_type);
495 
496  Real33 J;
497  Real3 xyz;
498 
499  for (unsigned int node = 0; node < num_nodes; ++node)
500  {
501  auto points = kokkosMesh().getNodePoint(kokkosMesh().getContiguousNodeID(eid, node));
502 
503  if (jacobian || JxW)
504  J += grad_phi(node, qp).cartesian_product(points);
505 
506  xyz += phi(node, qp) * points;
507  }
508 
509  if (jacobian)
510  *jacobian = J.inverse(_dimension);
511 
512  if (JxW)
513  *JxW =
514  J.determinant(_dimension) * _weights(sid, elem_type)[qp] * coordTransformFactor(sid, xyz);
515 
516  if (q_points)
517  *q_points = xyz;
518 }
519 
520 KOKKOS_FUNCTION inline void
522  const unsigned int side,
523  const unsigned int qp,
524  Real33 * const jacobian,
525  Real * const JxW,
526  Real3 * const q_points,
527  Real3 * const normal) const
528 {
529  auto sid = info.subdomain;
530  auto eid = info.id;
531  auto elem_type = info.type;
532  auto num_nodes = kokkosMesh().getNumNodes(elem_type);
533  auto num_side_nodes = kokkosMesh().getNumNodes(elem_type, side);
534 
535  auto & phi = _map_phi_face(sid, elem_type)(side);
536  auto & grad_phi = _map_grad_phi_face(sid, elem_type)(side);
537 
538  auto & normal_dx_dxi = _normal_dx_dxi(sid, elem_type)(side);
539  auto & normal_dx_deta = _normal_dx_deta(sid, elem_type)(side);
540 
541  Real33 J;
542  Real3 xyz;
543 
544  Real3 dxyz_dxi;
545  Real3 dxyz_deta;
546 
547  for (unsigned int node = 0; node < num_nodes; ++node)
548  {
549  auto points = kokkosMesh().getNodePoint(kokkosMesh().getContiguousNodeID(eid, node));
550 
551  if (jacobian)
552  J += grad_phi(node, qp).cartesian_product(points);
553 
554  if (JxW || q_points)
555  xyz += phi(node, qp) * points;
556 
557  if (normal)
558  {
559  if (_dimension < 3)
560  dxyz_dxi += normal_dx_dxi(node, qp) * points;
561  if (_dimension == 2)
562  dxyz_deta += normal_dx_deta(node, qp) * points;
563  }
564  }
565 
566  if (jacobian)
567  *jacobian = J.inverse(_dimension);
568 
569  if (q_points)
570  *q_points = xyz;
571 
572  if (JxW || (normal && _dimension > 1))
573  {
574  J = 0;
575 
576  auto & grad_psi = _map_grad_psi_face(sid, elem_type)(side);
577 
578  for (unsigned int node = 0; node < num_side_nodes; ++node)
579  {
580  auto points = kokkosMesh().getNodePoint(kokkosMesh().getContiguousNodeID(info, side, node));
581 
582  J += grad_psi(node, qp).cartesian_product(points);
583  }
584  }
585 
586  if (JxW)
587  *JxW = ::Kokkos::sqrt((J * J.transpose()).determinant(_dimension - 1)) *
588  _weights_face(sid, elem_type)[side][qp] * coordTransformFactor(sid, xyz);
589 
590  if (normal)
591  {
592  if (_dimension == 3)
593  *normal = J.row(0).cross_product(J.row(1));
594  else if (_dimension == 2)
595  *normal = J.row(0).cross_product(dxyz_dxi.cross_product(dxyz_deta));
596  else
597  *normal = side ? dxyz_dxi : -dxyz_dxi;
598 
599  *normal *= 1.0 / normal->norm();
600  }
601 }
602 #endif
603 
611 {
612 public:
617  AssemblyHolder(const Assembly & assembly) : _assembly_host(assembly), _assembly_device(assembly)
618  {
619  }
625  {
626  }
627 
628 #ifdef MOOSE_KOKKOS_SCOPE
629 
634  KOKKOS_FUNCTION const Assembly & kokkosAssembly() const
635  {
636  KOKKOS_IF_ON_HOST(return _assembly_host;)
637 
638  return _assembly_device;
639  }
640 #endif
641 
642 private:
651 };
652 
653 } // namespace Moose::Kokkos
Array2D< Array< Real > > _weights
KOKKOS_FUNCTION const auto & getPhi(ContiguousSubdomainID subdomain, unsigned int elem_type, unsigned int fe_type) const
Get the shape functions of a FE type for an element type and subdomain.
std::map< FEType, unsigned int > _fe_type_map
FE type ID map.
AssemblyHolder(const AssemblyHolder &holder)
Copy constructor.
Array2D< Array< Array2D< Real3 > > > _map_grad_psi_face
unsigned int _rz_radial_coord
Radial coordinate index in cylindrical coordinate system.
Array2D< Array< Array2D< Real > > > _map_phi_face
The Kokkos assembly class.
The Kokkos object that contains the information of an element The IDs used in Kokkos are different fr...
Definition: KokkosMesh.h:33
Assembly(FEProblemBase &problem)
Constructor.
Array2D< unsigned int > _n_qps_face
const unsigned int invalid_uint
KOKKOS_FUNCTION dof_id_type getQpOffset(ElementInfo info) const
Get the starting offset of quadrature points of an element into the global quadrature point index...
KOKKOS_FUNCTION const Assembly & kokkosAssembly() const
Get the const reference of the Kokkos assembly.
FEProblemBase & _problem
Reference of the MOOSE problem.
KOKKOS_FUNCTION unsigned int getNumQps(ElementInfo info) const
Get the number of quadrature points of an element.
MPI_Info info
Array3D< Array< Array2D< Real > > > _phi_face
Array< Array< Real > > _jxw
Array2D< dof_id_type > _qp_offset_face
KOKKOS_INLINE_FUNCTION Real33 inverse(const unsigned int dim=3) const
Definition: KokkosTypes.h:415
Array2D< Array< Array2D< Real > > > _normal_dx_deta
Array< dof_id_type > _n_subdomain_qps_face
KOKKOS_FUNCTION const auto & getVectorPhiFace(ContiguousSubdomainID subdomain, unsigned int elem_type, unsigned int fe_type) const
Get the face vector shape functions of a FE type for an element type and subdomain.
KOKKOS_FUNCTION unsigned int getDimension() const
Get the mesh dimension.
KOKKOS_FUNCTION void operator()(const ThreadID tid) const
Kokkos function for caching physical maps on element quadrature points.
const unsigned int _dimension
Mesh dimension.
KOKKOS_FUNCTION const auto & getGradPhiFace(ContiguousSubdomainID subdomain, unsigned int elem_type, unsigned int fe_type) const
Get the gradient of face shape functions of a FE type for an element type and subdomain.
KOKKOS_FUNCTION const auto & getGradPhi(ContiguousSubdomainID subdomain, unsigned int elem_type, unsigned int fe_type) const
Get the gradient of shape functions of a FE type for an element type and subdomain.
Array3D< Array< Array2D< Real33 > > > _vector_grad_phi_face
Array3D< Array< Array2D< Real3 > > > _vector_phi_face
unsigned int getFETypeID(FEType type) const
Get the FE type ID.
KOKKOS_FUNCTION unsigned int getNumDofs(unsigned int elem_type, unsigned int fe_type) const
Get the number of DOFs of a FE type for an element type.
Array2D< Array< Array< Real > > > _weights_face
The Kokkos interface that holds the host reference of the Kokkos mesh and copies it to device during ...
Definition: KokkosMesh.h:629
KOKKOS_FUNCTION Real coordTransformFactor(const ContiguousSubdomainID subdomain, const Real3 point) const
Get the coordinate transform factor for a point in a subdomain.
Array< unsigned int > _n_qps
Number of quadrature points.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
Array2D< unsigned int > _n_dofs
Array2D< Array2D< Real > > _map_phi
Shape functions for computing reference-to-physical maps.
KOKKOS_INLINE_FUNCTION Real norm() const
KOKKOS_FUNCTION const auto & getPhiFace(ContiguousSubdomainID subdomain, unsigned int elem_type, unsigned int fe_type) const
Get the face shape functions of a FE type for an element type and subdomain.
void cachePhysicalMap()
Cache physical maps on element quadrature points.
Array2D< Array< Array2D< Real3 > > > _map_grad_phi_face
Array< Pair< Real3, Real3 > > _rz_axis
General axisymmetric axis of each subdomain in cylindrical coordinate system.
Array< bool > _is_vector_fe_type
KOKKOS_FUNCTION unsigned int getNumNodes(unsigned int elem_type) const
Get the number of nodes of an element type.
Definition: KokkosMesh.h:363
KOKKOS_FUNCTION unsigned int getMaxQpsPerElem() const
Get the maximum number of quadrature points per element in the current partition. ...
MOOSE_KOKKOS_INDEX_TYPE ThreadID
Definition: KokkosThread.h:22
KOKKOS_FUNCTION const auto & getVectorPhi(ContiguousSubdomainID subdomain, unsigned int elem_type, unsigned int fe_type) const
Get the vector shape functions of a FE type for an element type and subdomain.
Array2D< Array< Array2D< Real > > > _normal_dx_dxi
Shape functions for computing normal vectors.
Array< Array< Real33 > > _jacobian
Cached physical maps on element quadrature points.
Array2D< Array< Real3 > > _q_points
Quadrature points and weights for reference elements.
KOKKOS_FUNCTION const auto & getVectorGradPhiFace(ContiguousSubdomainID subdomain, unsigned int elem_type, unsigned int fe_type) const
Get the gradient of face vector shape functions of a FE type for an element type and subdomain...
KOKKOS_FUNCTION const auto & getVectorGradPhi(ContiguousSubdomainID subdomain, unsigned int elem_type, unsigned int fe_type) const
Get the gradient of vector shape functions of a FE type for an element type and subdomain.
Array3D< Array2D< Real3 > > _vector_phi
KOKKOS_INLINE_FUNCTION Real3 cross_product(const Real3 vector) const
Array3D< Array< Array2D< Real3 > > > _grad_phi_face
KOKKOS_FUNCTION bool isVectorFEType(unsigned int fe_type) const
Get whether a cached FE type is vector-valued.
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition: MooseMesh.h:94
The Kokkos interface that holds the host reference of the Kokkos assembly and copies it to device dur...
Array3D< Array2D< Real > > _phi
Shape functions for reference elements.
KOKKOS_INLINE_FUNCTION Real33 transpose() const
Definition: KokkosTypes.h:448
KOKKOS_FUNCTION dof_id_type getNumFaceQps(ContiguousSubdomainID subdomain) const
Get the total number of facial quadrature points in a subdomain NOTE: This number does not represent ...
unsigned int _max_qps_per_elem
Array2D< Array< Array< Real3 > > > _q_points_face
void initQuadrature()
Initialize quadrature data.
KOKKOS_FUNCTION Real3 getNodePoint(ContiguousNodeID node) const
Get the coordinate of a node.
Definition: KokkosMesh.h:428
Array3D< Array2D< Real3 > > _grad_phi
KOKKOS_FUNCTION Real getJxW(ElementInfo info, unsigned int qp) const
Get the transformed Jacobian weight of an element quadrature point.
KOKKOS_INLINE_FUNCTION Real determinant(const unsigned int dim=3) const
Definition: KokkosTypes.h:396
KOKKOS_FUNCTION dof_id_type getElemFacePropertySize(ContiguousSubdomainID subdomain) const
Get the size of element-constant face material property data storage of a subdomain.
KOKKOS_FUNCTION const Mesh & kokkosMesh() const
Get the const reference of the Kokkos mesh.
Definition: KokkosMesh.h:651
MooseMesh & _mesh
Reference of the MOOSE mesh.
const auto & getMaterialBoundaries() const
Get the list of boundaries to cache face material properties.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
KOKKOS_FUNCTION dof_id_type getQpFaceOffset(ElementInfo info, unsigned int side) const
Get the starting offset of quadrature points of a side of an element into the global quadrature point...
void initShape()
Initialize shape data.
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
Array2D< Array2D< Real3 > > _map_grad_phi
Array< dof_id_type > _qp_offset
Starting offset into the global quadrature point index NOTE: The global quadrature point index is sub...
KOKKOS_FUNCTION dof_id_type getNumQps(ContiguousSubdomainID subdomain) const
Get the total number of elemental quadrature points in a subdomain.
std::set< BoundaryID > _material_boundaries
Boundaries to cache face material properties.
Array< Moose::CoordinateSystemType > _coord_type
Coordinate system type of each subdomain.
Array< Array< Real3 > > _xyz
Array< dof_id_type > _n_subdomain_qps
Array2D< Array< Array2D< Real > > > _map_psi_face
KOKKOS_FUNCTION dof_id_type getElemFacePropertyIndex(ElementInfo info, unsigned int side) const
Get the index of a side of an element into the element-constant face material property data...
KOKKOS_INLINE_FUNCTION Real3 row(const unsigned int i) const
Definition: KokkosTypes.h:460
void init()
Initialize assembly.
AssemblyHolder(const Assembly &assembly)
Constructor.
const Assembly _assembly_device
Device copy of the Kokkos assembly.
Array< dof_id_type > _n_elem_face_properties
const Assembly & _assembly_host
Host reference of the Kokkos assembly.
Array2D< dof_id_type > _elem_face_property_idx
Index into the element-constant face material property data.
KOKKOS_FUNCTION Real33 getJacobian(ElementInfo info, unsigned int qp) const
Get the inverse of Jacobian matrix of an element quadrature point.
Array3D< Array2D< Real33 > > _vector_grad_phi
uint8_t dof_id_type
KOKKOS_FUNCTION void computePhysicalMap(const ElementInfo info, const unsigned int qp, Real33 *const jacobian, Real *const JxW, Real3 *const q_points) const
Compute physical transformation data for an element.
KOKKOS_FUNCTION unsigned int getNumFaceQps(ElementInfo info, unsigned int side) const
Get the number of quadrature points of a side of an element.
KOKKOS_FUNCTION Real3 getQPoint(ElementInfo info, unsigned int qp) const
Get the coordinate of an element quadrature point.