Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FadMPAssembly/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 
37 
38  const double m_a ;
39  const double m_b ;
40  const double m_c ;
41  const unsigned m_max_x ;
42  const unsigned m_max_y ;
43  const unsigned m_max_z ;
44 
45  MapGridUnitCube( const unsigned grid_max_x ,
46  const unsigned grid_max_y ,
47  const unsigned 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 >
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< unsigned*[SpaceDim] , Device > m_node_grid ;
115  Kokkos::View< unsigned*[ElemNode] , Device > m_elem_node ;
116  Kokkos::View< unsigned*[2] , Device > m_recv_node ;
117  Kokkos::View< unsigned*[2] , Device > m_send_node ;
118  Kokkos::View< unsigned* , Device > m_send_node_id ;
119 
120  unsigned char m_elem_node_local[ ElemNode ][4] ;
121 
122 public:
123 
124  typedef Kokkos::View< const unsigned * [ElemNode], Device > elem_node_type ;
125  typedef Kokkos::View< const double * [SpaceDim], Device > node_coord_type ;
126  typedef Kokkos::View< const unsigned * [SpaceDim], Device > node_grid_type ;
127  typedef Kokkos::View< const unsigned * [2] , Device > comm_list_type ;
128  typedef Kokkos::View< const unsigned * , Device > send_nodeid_type ;
129 
130  KOKKOS_INLINE_FUNCTION
131  unsigned node_count() const { return m_node_grid.extent(0); }
132 
133  KOKKOS_INLINE_FUNCTION
134  unsigned node_count_owned() const { return m_box_part.owns_node_count(); }
135 
136  KOKKOS_INLINE_FUNCTION
137  unsigned node_count_global() const { return m_box_part.global_node_count(); }
138 
139  KOKKOS_INLINE_FUNCTION
140  unsigned elem_count() const { return m_elem_node.extent(0); }
141 
142  KOKKOS_INLINE_FUNCTION
143  unsigned elem_count_global() const { return m_box_part.global_elem_count(); }
144 
145  KOKKOS_INLINE_FUNCTION
146  unsigned elem_node_local( unsigned inode , unsigned k ) const
147  { return m_elem_node_local[inode][k] ; }
148 
149  KOKKOS_INLINE_FUNCTION
150  unsigned node_grid( unsigned inode , unsigned iaxis ) const
151  { return m_node_grid(inode,iaxis); }
152 
153  KOKKOS_INLINE_FUNCTION
154  size_t node_global_index( unsigned local ) const
155  {
156  const unsigned node_grid[SpaceDim] =
157  { m_node_grid(local,0) , m_node_grid(local,1) , m_node_grid(local,2) };
158  return m_box_part.global_node_id( node_grid );
159  }
160 
161  KOKKOS_INLINE_FUNCTION
162  double node_coord( unsigned inode , unsigned iaxis ) const
163  { return m_node_coord(inode,iaxis); }
164 
165  KOKKOS_INLINE_FUNCTION
166  unsigned node_grid_max( unsigned iaxis ) const
167  { return m_box_part.global_coord_max(iaxis); }
168 
169  KOKKOS_INLINE_FUNCTION
170  unsigned elem_node( unsigned ielem , unsigned inode ) const
171  { return m_elem_node(ielem,inode); }
172 
173  elem_node_type elem_node() const { return m_elem_node ; }
175  node_grid_type node_grid() const { return m_node_grid ; }
176  comm_list_type recv_node() const { return m_recv_node ; }
177  comm_list_type send_node() const { return m_send_node ; }
179 
180  KOKKOS_INLINE_FUNCTION
182  : m_box_part( rhs.m_box_part )
183  , m_coord_map( rhs.m_coord_map )
184  , m_node_coord( rhs.m_node_coord )
185  , m_node_grid( rhs.m_node_grid )
186  , m_elem_node( rhs.m_elem_node )
187  , m_recv_node( rhs.m_recv_node )
188  , m_send_node( rhs.m_send_node )
190  {
191  for ( unsigned i = 0 ; i < ElemNode ; ++i ) {
192  m_elem_node_local[i][0] = rhs.m_elem_node_local[i][0] ;
193  m_elem_node_local[i][1] = rhs.m_elem_node_local[i][1] ;
194  m_elem_node_local[i][2] = rhs.m_elem_node_local[i][2] ;
195  m_elem_node_local[i][3] = 0 ;
196  }
197  }
198 
200  {
201  m_box_part = rhs.m_box_part ;
202  m_coord_map = rhs.m_coord_map ;
203  m_node_coord = rhs.m_node_coord ;
204  m_node_grid = rhs.m_node_grid ;
205  m_elem_node = rhs.m_elem_node ;
206  m_recv_node = rhs.m_recv_node ;
207  m_send_node = rhs.m_send_node ;
209 
210  for ( unsigned i = 0 ; i < ElemNode ; ++i ) {
211  m_elem_node_local[i][0] = rhs.m_elem_node_local[i][0] ;
212  m_elem_node_local[i][1] = rhs.m_elem_node_local[i][1] ;
213  m_elem_node_local[i][2] = rhs.m_elem_node_local[i][2] ;
214  m_elem_node_local[i][3] = 0 ;
215  }
216  return *this ;
217  }
218 
220  const unsigned global_size ,
221  const unsigned global_rank ,
222  const unsigned elem_nx ,
223  const unsigned elem_ny ,
224  const unsigned elem_nz ,
225  const double bubble_x = 1.1 ,
226  const double bubble_y = 1.2 ,
227  const double bubble_z = 1.3 )
228  : m_box_part( Order , decompose , global_size , global_rank , elem_nx , elem_ny , elem_nz )
229  , m_coord_map( m_box_part.global_coord_max(0) ,
230  m_box_part.global_coord_max(1) ,
231  m_box_part.global_coord_max(2) ,
232  bubble_x ,
233  bubble_y ,
234  bubble_z )
235  , m_node_coord( "fixture_node_coord" , m_box_part.uses_node_count() )
236  , m_node_grid( "fixture_node_grid" , m_box_part.uses_node_count() )
237  , m_elem_node( "fixture_elem_node" , m_box_part.uses_elem_count() )
238  , m_recv_node( "fixture_recv_node" , m_box_part.recv_node_msg_count() )
239  , m_send_node( "fixture_send_node" , m_box_part.send_node_msg_count() )
240  , m_send_node_id( "fixture_send_node_id" , m_box_part.send_node_id_count() )
241  {
242  {
243  const hex_data elem_data ;
244 
245  for ( unsigned i = 0 ; i < ElemNode ; ++i ) {
246  m_elem_node_local[i][0] = elem_data.eval_map[i][0] ;
247  m_elem_node_local[i][1] = elem_data.eval_map[i][1] ;
248  m_elem_node_local[i][2] = elem_data.eval_map[i][2] ;
249  m_elem_node_local[i][3] = 0 ;
250  }
251  }
252 
253  const size_t nwork =
254  std::max( m_recv_node.extent(0) ,
255  std::max( m_send_node.extent(0) ,
256  std::max( m_send_node_id.extent(0) ,
257  std::max( m_node_grid.extent(0) ,
258  m_elem_node.extent(0) * m_elem_node.extent(1) ))));
259 
260  Kokkos::parallel_for( nwork , *this );
261  }
262 
263 
264  // Initialization:
265 
266  KOKKOS_INLINE_FUNCTION
267  void operator()( size_t i ) const
268  {
269  if ( i < m_elem_node.extent(0) * m_elem_node.extent(1) ) {
270 
271  const size_t ielem = i / ElemNode ;
272  const size_t inode = i % ElemNode ;
273 
274  unsigned elem_grid[SpaceDim] ;
275  unsigned node_grid[SpaceDim] ;
276 
277  m_box_part.uses_elem_coord( ielem , elem_grid );
278 
279  enum { elem_node_scale = Order == BoxElemPart::ElemLinear ? 1 :
280  Order == BoxElemPart::ElemQuadratic ? 2 : 0 };
281 
282  node_grid[0] = elem_node_scale * elem_grid[0] + m_elem_node_local[inode][0] ;
283  node_grid[1] = elem_node_scale * elem_grid[1] + m_elem_node_local[inode][1] ;
284  node_grid[2] = elem_node_scale * elem_grid[2] + m_elem_node_local[inode][2] ;
285 
286  m_elem_node(ielem,inode) = m_box_part.local_node_id( node_grid );
287  }
288 
289  if ( i < m_node_grid.extent(0) ) {
290  unsigned node_grid[SpaceDim] ;
291  m_box_part.local_node_coord( i , node_grid );
292  m_node_grid(i,0) = node_grid[0] ;
293  m_node_grid(i,1) = node_grid[1] ;
294  m_node_grid(i,2) = node_grid[2] ;
295 
296  m_coord_map( node_grid[0] ,
297  node_grid[1] ,
298  node_grid[2] ,
299  m_node_coord(i,0) ,
300  m_node_coord(i,1) ,
301  m_node_coord(i,2) );
302  }
303 
304  if ( i < m_recv_node.extent(0) ) {
307  }
308 
309  if ( i < m_send_node.extent(0) ) {
312  }
313 
314  if ( i < m_send_node_id.extent(0) ) {
316  }
317  }
318 };
319 
320 } // namespace Example
321 } // namespace Kokkos
322 
323 //----------------------------------------------------------------------------
324 
325 #endif /* #ifndef KOKKOS_EXAMPLE_BOXELEMFIXTURE_HPP */
326 
KOKKOS_INLINE_FUNCTION unsigned elem_node_local(unsigned inode, unsigned k) const
KOKKOS_INLINE_FUNCTION void uses_elem_coord(size_t lid, unsigned c[]) const
Kokkos::View< const unsigned *[2], Device > comm_list_type
KOKKOS_INLINE_FUNCTION unsigned send_node_count(unsigned msg) const
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< const double *[SpaceDim], Device > node_coord_type
BoxElemFixture & operator=(const BoxElemFixture &rhs)
Kokkos::View< const unsigned *[ElemNode], Device > elem_node_type
Map a grid onto a unit cube with smooth nonlinear grading of the map.
Kokkos::View< unsigned *[2], Device > m_recv_node
Kokkos::View< const unsigned *[SpaceDim], Device > node_grid_type
KOKKOS_INLINE_FUNCTION unsigned node_count_global() const
KOKKOS_INLINE_FUNCTION unsigned send_node_id(unsigned item) const
KOKKOS_INLINE_FUNCTION unsigned node_count_owned() const
Kokkos::View< unsigned *[2], Device > m_send_node
KOKKOS_INLINE_FUNCTION unsigned elem_count() const
KOKKOS_INLINE_FUNCTION void local_node_coord(size_t lid, unsigned coord[]) const
Kokkos::View< const unsigned *, Device > send_nodeid_type
KOKKOS_INLINE_FUNCTION unsigned elem_node(unsigned ielem, unsigned inode) const
Kokkos::Example::HexElement_TensorData< ElemNode > hex_data
KOKKOS_INLINE_FUNCTION unsigned node_count() const
KOKKOS_INLINE_FUNCTION PCE< Storage > max(const typename PCE< Storage >::value_type &a, const PCE< Storage > &b)
KOKKOS_INLINE_FUNCTION unsigned node_grid_max(unsigned iaxis) const
KOKKOS_INLINE_FUNCTION size_t owns_node_count() const
Kokkos::View< unsigned *[ElemNode], Device > m_elem_node
KOKKOS_INLINE_FUNCTION void operator()(size_t i) const
KOKKOS_INLINE_FUNCTION double node_coord(unsigned inode, unsigned iaxis) const
Kokkos::View< double *[SpaceDim], Device > m_node_coord
KOKKOS_INLINE_FUNCTION unsigned elem_count_global() const
KOKKOS_INLINE_FUNCTION size_t node_global_index(unsigned local) const
BoxElemFixture(const BoxElemPart::Decompose decompose, const unsigned global_size, const unsigned global_rank, const unsigned elem_nx, const unsigned elem_ny, const unsigned elem_nz, const double bubble_x=1.1, const double bubble_y=1.2, const double bubble_z=1.3)
MapGridUnitCube(const unsigned grid_max_x, const unsigned grid_max_y, const unsigned 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_INLINE_FUNCTION unsigned node_grid(unsigned inode, unsigned iaxis) const
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::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