Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MPAssembly/BoxElemFixture.hpp
Go to the documentation of this file.
1 //@HEADER
2 // ************************************************************************
3 //
4 // Kokkos v. 4.0
5 // Copyright (2022) National Technology & Engineering
6 // Solutions of Sandia, LLC (NTESS).
7 //
8 // Under the terms of Contract DE-NA0003525 with NTESS,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions.
12 // See https://kokkos.org/LICENSE for license information.
13 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
14 //
15 //@HEADER
16 
17 #ifndef KOKKOS_EXAMPLE_BOXELEMFIXTURE_HPP
18 #define KOKKOS_EXAMPLE_BOXELEMFIXTURE_HPP
19 
20 #include <stdio.h>
21 #include <utility>
22 
23 #include <Kokkos_Core.hpp>
24 
25 #include <HexElement.hpp>
26 #include <BoxElemPart.hpp>
27 
28 //----------------------------------------------------------------------------
29 
30 namespace Kokkos {
31 namespace Example {
32 
36 struct MapGridUnitCube {
37 
38  const double m_a ;
39  const double m_b ;
40  const double m_c ;
41  const size_t m_max_x ;
42  const size_t m_max_y ;
43  const size_t m_max_z ;
44 
45  MapGridUnitCube( const size_t grid_max_x ,
46  const size_t grid_max_y ,
47  const size_t grid_max_z ,
48  const double bubble_x ,
49  const double bubble_y ,
50  const double bubble_z )
51  : m_a( bubble_x )
52  , m_b( bubble_y )
53  , m_c( bubble_z )
54  , m_max_x( grid_max_x )
55  , m_max_y( grid_max_y )
56  , m_max_z( grid_max_z )
57  {}
58 
59  template< typename Scalar >
60  KOKKOS_INLINE_FUNCTION
61  void operator()( int grid_x ,
62  int grid_y ,
63  int grid_z ,
64  Scalar & coord_x ,
65  Scalar & coord_y ,
66  Scalar & coord_z ) const
67  {
68  // Map to a unit cube [0,1]^3
69 
70  const double x = double(grid_x) / double(m_max_x);
71  const double y = double(grid_y) / double(m_max_y);
72  const double z = double(grid_z) / double(m_max_z);
73 
74  coord_x = x + x * x * ( x - 1 ) * ( x - 1 ) * m_a ;
75  coord_y = y + y * y * ( y - 1 ) * ( y - 1 ) * m_b ;
76  coord_z = z + z * z * ( z - 1 ) * ( z - 1 ) * m_c ;
77  }
78 };
79 
80 } // namespace Example
81 } // namespace Kokkos
82 
83 //----------------------------------------------------------------------------
84 
85 namespace Kokkos {
86 namespace Example {
87 
94 template< class Device ,
96  class CoordinateMap = MapGridUnitCube >
97 class BoxElemFixture {
98 public:
99 
100  typedef Device execution_space ;
101 
102  enum { SpaceDim = 3 };
103  enum { ElemNode = Order == BoxElemPart::ElemLinear ? 8 :
104  Order == BoxElemPart::ElemQuadratic ? 27 : 0 };
105 
106 private:
107 
109 
111  CoordinateMap m_coord_map ;
112 
113  Kokkos::View< double *[SpaceDim] , Device > m_node_coord ;
114  Kokkos::View< size_t *[SpaceDim] , Device > m_node_grid ;
115  Kokkos::View< size_t *[ElemNode] , Device > m_elem_node ;
116  Kokkos::View< size_t *[2] , Device > m_recv_node ;
117  Kokkos::View< size_t *[2] , Device > m_send_node ;
118  Kokkos::View< size_t * , Device > m_send_node_id ;
119 
120  unsigned char m_elem_node_local[ ElemNode ][4] ;
121 
122 public:
123 
124  typedef Kokkos::View< const size_t * [ElemNode], Device > elem_node_type ;
125  typedef Kokkos::View< const double * [SpaceDim], Device > node_coord_type ;
126  typedef Kokkos::View< const size_t * [SpaceDim], Device > node_grid_type ;
127  typedef Kokkos::View< const size_t * [2] , Device > comm_list_type ;
128  typedef Kokkos::View< const size_t * , Device > send_nodeid_type ;
129 
130  inline bool ok() const { return m_box_part.ok(); }
131 
132  KOKKOS_INLINE_FUNCTION
133  size_t node_count() const { return m_node_grid.extent(0); }
134 
135  KOKKOS_INLINE_FUNCTION
136  size_t node_count_owned() const { return m_box_part.owns_node_count(); }
137 
138  KOKKOS_INLINE_FUNCTION
139  size_t node_count_global() const { return m_box_part.global_node_count(); }
140 
141  KOKKOS_INLINE_FUNCTION
142  size_t elem_count() const { return m_elem_node.extent(0); }
143 
144  KOKKOS_INLINE_FUNCTION
145  size_t elem_count_global() const { return m_box_part.global_elem_count(); }
146 
147  KOKKOS_INLINE_FUNCTION
148  size_t elem_node_local( size_t inode , int k ) const
149  { return m_elem_node_local[inode][k] ; }
150 
151  KOKKOS_INLINE_FUNCTION
152  size_t node_grid( size_t inode , int iaxis ) const
153  { return m_node_grid(inode,iaxis); }
154 
155  KOKKOS_INLINE_FUNCTION
156  size_t node_global_index( size_t local ) const
157  {
158  const size_t nodeGrid[SpaceDim] =
159  { m_node_grid(local,0) , m_node_grid(local,1) , m_node_grid(local,2) };
160  return m_box_part.global_node_id( nodeGrid );
161  }
162 
163  KOKKOS_INLINE_FUNCTION
164  double node_coord( size_t inode , int iaxis ) const
165  { return m_node_coord(inode,iaxis); }
166 
167  KOKKOS_INLINE_FUNCTION
168  size_t node_grid_max( int iaxis ) const
169  { return m_box_part.global_coord_max(iaxis); }
170 
171  KOKKOS_INLINE_FUNCTION
172  size_t elem_node( size_t ielem , size_t inode ) const
173  { return m_elem_node(ielem,inode); }
174 
175  elem_node_type elem_node() const { return m_elem_node ; }
177  node_grid_type node_grid() const { return m_node_grid ; }
178  comm_list_type recv_node() const { return m_recv_node ; }
179  comm_list_type send_node() const { return m_send_node ; }
181 
182  KOKKOS_INLINE_FUNCTION
184  : m_box_part( rhs.m_box_part )
185  , m_coord_map( rhs.m_coord_map )
186  , m_node_coord( rhs.m_node_coord )
187  , m_node_grid( rhs.m_node_grid )
188  , m_elem_node( rhs.m_elem_node )
189  , m_recv_node( rhs.m_recv_node )
190  , m_send_node( rhs.m_send_node )
192  {
193  for ( int i = 0 ; i < ElemNode ; ++i ) {
194  m_elem_node_local[i][0] = rhs.m_elem_node_local[i][0] ;
195  m_elem_node_local[i][1] = rhs.m_elem_node_local[i][1] ;
196  m_elem_node_local[i][2] = rhs.m_elem_node_local[i][2] ;
197  m_elem_node_local[i][3] = 0 ;
198  }
199  }
200 
202  {
203  m_box_part = rhs.m_box_part ;
204  m_coord_map = rhs.m_coord_map ;
205  m_node_coord = rhs.m_node_coord ;
206  m_node_grid = rhs.m_node_grid ;
207  m_elem_node = rhs.m_elem_node ;
208  m_recv_node = rhs.m_recv_node ;
209  m_send_node = rhs.m_send_node ;
210  m_send_node_id = rhs.m_send_node_id ;
211 
212  for ( int i = 0 ; i < ElemNode ; ++i ) {
213  m_elem_node_local[i][0] = rhs.m_elem_node_local[i][0] ;
214  m_elem_node_local[i][1] = rhs.m_elem_node_local[i][1] ;
215  m_elem_node_local[i][2] = rhs.m_elem_node_local[i][2] ;
216  m_elem_node_local[i][3] = 0 ;
217  }
218  return *this ;
219  }
220 
222  const size_t global_size ,
223  const size_t global_rank ,
224  const size_t elem_nx ,
225  const size_t elem_ny ,
226  const size_t elem_nz ,
227  const double bubble_x = 1.1 ,
228  const double bubble_y = 1.2 ,
229  const double bubble_z = 1.3 )
230  : m_box_part( Order , decompose , global_size , global_rank , elem_nx , elem_ny , elem_nz )
231  , m_coord_map( m_box_part.global_coord_max(0) ,
232  m_box_part.global_coord_max(1) ,
233  m_box_part.global_coord_max(2) ,
234  bubble_x ,
235  bubble_y ,
236  bubble_z )
237  , m_node_coord( "fixture_node_coord" , m_box_part.uses_node_count() )
238  , m_node_grid( "fixture_node_grid" , m_box_part.uses_node_count() )
239  , m_elem_node( "fixture_elem_node" , m_box_part.uses_elem_count() )
240  , m_recv_node( "fixture_recv_node" , m_box_part.recv_node_msg_count() )
241  , m_send_node( "fixture_send_node" , m_box_part.send_node_msg_count() )
242  , m_send_node_id( "fixture_send_node_id" , m_box_part.send_node_id_count() )
243  {
244  {
245  const hex_data elem_data ;
246 
247  for ( int i = 0 ; i < ElemNode ; ++i ) {
248  m_elem_node_local[i][0] = elem_data.eval_map[i][0] ;
249  m_elem_node_local[i][1] = elem_data.eval_map[i][1] ;
250  m_elem_node_local[i][2] = elem_data.eval_map[i][2] ;
251  m_elem_node_local[i][3] = 0 ;
252  }
253  }
254 
255  const size_t nwork =
256  std::max( m_recv_node.extent(0) ,
257  std::max( m_send_node.extent(0) ,
258  std::max( m_send_node_id.extent(0) ,
259  std::max( m_node_grid.extent(0) ,
260  m_elem_node.extent(0) * m_elem_node.extent(1) ))));
261 
262  Kokkos::parallel_for( nwork , *this );
263  }
264 
265 
266  // Initialization:
267 
268  KOKKOS_INLINE_FUNCTION
269  void operator()( size_t i ) const
270  {
271  if ( i < m_elem_node.extent(0) * m_elem_node.extent(1) ) {
272 
273  const size_t ielem = i / ElemNode ;
274  const size_t inode = i % ElemNode ;
275 
276  size_t elem_grid[SpaceDim] ;
277  size_t nodeGrid[SpaceDim] ;
278 
279  m_box_part.uses_elem_coord( ielem , elem_grid );
280 
281  enum { elem_node_scale = Order == BoxElemPart::ElemLinear ? 1 :
282  Order == BoxElemPart::ElemQuadratic ? 2 : 0 };
283 
284  nodeGrid[0] = elem_node_scale * elem_grid[0] + m_elem_node_local[inode][0] ;
285  nodeGrid[1] = elem_node_scale * elem_grid[1] + m_elem_node_local[inode][1] ;
286  nodeGrid[2] = elem_node_scale * elem_grid[2] + m_elem_node_local[inode][2] ;
287 
288  m_elem_node(ielem,inode) = m_box_part.local_node_id( nodeGrid );
289  }
290 
291  if ( i < m_node_grid.extent(0) ) {
292  size_t nodeGrid[SpaceDim] ;
293  m_box_part.local_node_coord( i , nodeGrid );
294  m_node_grid(i,0) = nodeGrid[0] ;
295  m_node_grid(i,1) = nodeGrid[1] ;
296  m_node_grid(i,2) = nodeGrid[2] ;
297 
298  m_coord_map( nodeGrid[0] ,
299  nodeGrid[1] ,
300  nodeGrid[2] ,
301  m_node_coord(i,0) ,
302  m_node_coord(i,1) ,
303  m_node_coord(i,2) );
304  }
305 
306  if ( i < m_recv_node.extent(0) ) {
309  }
310 
311  if ( i < m_send_node.extent(0) ) {
314  }
315 
316  if ( i < m_send_node_id.extent(0) ) {
318  }
319  }
320 };
321 
322 } // namespace Example
323 } // namespace Kokkos
324 
325 //----------------------------------------------------------------------------
326 
327 #endif /* #ifndef KOKKOS_EXAMPLE_BOXELEMFIXTURE_HPP */
Kokkos::View< size_t *[SpaceDim], Device > m_node_grid
KOKKOS_INLINE_FUNCTION void uses_elem_coord(size_t lid, unsigned c[]) const
Kokkos::View< const unsigned *[2], Device > comm_list_type
Kokkos::View< size_t *[ElemNode], Device > m_elem_node
KOKKOS_INLINE_FUNCTION size_t elem_node_local(size_t inode, int k) const
Kokkos::View< const size_t *[SpaceDim], Device > node_grid_type
KOKKOS_INLINE_FUNCTION unsigned send_node_count(unsigned msg) const
KOKKOS_INLINE_FUNCTION size_t elem_node(size_t ielem, size_t inode) const
Kokkos::View< const size_t *[2], Device > comm_list_type
KOKKOS_INLINE_FUNCTION unsigned local_node_id(const unsigned c[]) const
KOKKOS_INLINE_FUNCTION void operator()(int grid_x, int grid_y, int grid_z, Scalar &coord_x, Scalar &coord_y, Scalar &coord_z) const
KOKKOS_INLINE_FUNCTION size_t global_node_id(const unsigned c[]) const
KOKKOS_INLINE_FUNCTION size_t global_elem_count() const
Kokkos::View< size_t *[2], Device > m_recv_node
Kokkos::View< const double *[SpaceDim], Device > node_coord_type
BoxElemFixture & operator=(const BoxElemFixture &rhs)
Kokkos::View< const unsigned *[ElemNode], Device > elem_node_type
KOKKOS_INLINE_FUNCTION double node_coord(size_t inode, int iaxis) const
Kokkos::View< unsigned *[2], Device > m_recv_node
Kokkos::View< const unsigned *[SpaceDim], Device > node_grid_type
KOKKOS_INLINE_FUNCTION unsigned send_node_id(unsigned item) const
KOKKOS_INLINE_FUNCTION size_t elem_count_global() const
Kokkos::View< unsigned *[2], Device > m_send_node
KOKKOS_INLINE_FUNCTION size_t node_grid(size_t inode, int iaxis) const
KOKKOS_INLINE_FUNCTION size_t node_grid_max(int iaxis) const
KOKKOS_INLINE_FUNCTION void local_node_coord(size_t lid, unsigned coord[]) const
Kokkos::View< const size_t *[ElemNode], Device > elem_node_type
Kokkos::View< const unsigned *, Device > send_nodeid_type
Kokkos::Example::HexElement_TensorData< ElemNode > hex_data
KOKKOS_INLINE_FUNCTION PCE< Storage > max(const typename PCE< Storage >::value_type &a, const PCE< Storage > &b)
BoxElemFixture(const BoxElemPart::Decompose decompose, const size_t global_size, const size_t global_rank, const size_t elem_nx, const size_t elem_ny, const size_t elem_nz, const double bubble_x=1.1, const double bubble_y=1.2, const double bubble_z=1.3)
KOKKOS_INLINE_FUNCTION size_t owns_node_count() const
Kokkos::View< unsigned *[ElemNode], Device > m_elem_node
KOKKOS_INLINE_FUNCTION size_t node_count_owned() const
KOKKOS_INLINE_FUNCTION void operator()(size_t i) const
KOKKOS_INLINE_FUNCTION size_t node_count() const
Kokkos::View< double *[SpaceDim], Device > m_node_coord
KOKKOS_INLINE_FUNCTION size_t node_count_global() const
KOKKOS_INLINE_FUNCTION size_t node_global_index(size_t local) const
Kokkos::View< size_t *, Device > m_send_node_id
MapGridUnitCube(const size_t grid_max_x, const size_t grid_max_y, const size_t grid_max_z, const double bubble_x, const double bubble_y, const double bubble_z)
KOKKOS_INLINE_FUNCTION unsigned send_node_rank(unsigned msg) const
Kokkos::View< const size_t *, Device > send_nodeid_type
KOKKOS_INLINE_FUNCTION unsigned recv_node_count(unsigned msg) const
KOKKOS_INLINE_FUNCTION unsigned global_coord_max(unsigned axis) const
KOKKOS_INLINE_FUNCTION unsigned recv_node_rank(unsigned msg) const
Partition a box of hexahedral elements among subdomains.
KOKKOS_INLINE_FUNCTION size_t elem_count() const
Kokkos::View< size_t *[2], Device > m_send_node
Kokkos::View< unsigned *[SpaceDim], Device > m_node_grid
KOKKOS_INLINE_FUNCTION size_t global_node_count() const
KOKKOS_INLINE_FUNCTION BoxElemFixture(const BoxElemFixture &rhs)
Generate a distributed unstructured finite element mesh from a partitioned NX*NY*NZ box of elements...
Kokkos::View< unsigned *, Device > m_send_node_id