Sacado Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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
comm_list_type send_node() const
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
Definition: BoxElemPart.hpp:98
node_coord_type node_coord() const
Kokkos::View< unsigned *, Device > m_send_node_id
Kokkos::View< const double *[SpaceDim], Device > node_coord_type
BoxElemFixture & operator=(const BoxElemFixture &rhs)
Kokkos::View< const unsigned *[ElemNode], Device > elem_node_type
unsigned char m_elem_node_local[ElemNode][4]
Map a grid onto a unit cube with smooth nonlinear grading of the map.
Kokkos::View< unsigned *[2], Device > m_send_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 *[ElemNode], Device > m_elem_node
KOKKOS_INLINE_FUNCTION unsigned elem_count() const
Kokkos::Example::BoxElemPart m_box_part
elem_node_type elem_node() const
Kokkos::View< unsigned *[2], Device > m_recv_node
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 unsigned node_grid_max(unsigned iaxis) const
KOKKOS_INLINE_FUNCTION size_t owns_node_count() const
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
node_grid_type node_grid() const
KOKKOS_INLINE_FUNCTION unsigned elem_count_global() const
KOKKOS_INLINE_FUNCTION size_t node_global_index(unsigned local) const
Kokkos::View< unsigned *[SpaceDim], Device > m_node_grid
send_nodeid_type send_nodeid() const
Uncopyable z
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
SimpleFad< ValueT > max(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
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.
Definition: BoxElemPart.hpp:83
comm_list_type recv_node() const
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...
const double y