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 /*
2 //@HEADER
3 // ************************************************************************
4 //
5 // Kokkos: Manycore Performance-Portable Multidimensional Arrays
6 // Copyright (2012) Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
39 //
40 // ************************************************************************
41 //@HEADER
42 */
43 
44 #ifndef KOKKOS_EXAMPLE_BOXELEMFIXTURE_HPP
45 #define KOKKOS_EXAMPLE_BOXELEMFIXTURE_HPP
46 
47 #include <stdio.h>
48 #include <utility>
49 
50 #include <Kokkos_Core.hpp>
51 
52 #include <HexElement.hpp>
53 #include <BoxElemPart.hpp>
54 
55 //----------------------------------------------------------------------------
56 
57 namespace Kokkos {
58 namespace Example {
59 
64 
65  const double m_a ;
66  const double m_b ;
67  const double m_c ;
68  const unsigned m_max_x ;
69  const unsigned m_max_y ;
70  const unsigned m_max_z ;
71 
72  MapGridUnitCube( const unsigned grid_max_x ,
73  const unsigned grid_max_y ,
74  const unsigned grid_max_z ,
75  const double bubble_x ,
76  const double bubble_y ,
77  const double bubble_z )
78  : m_a( bubble_x )
79  , m_b( bubble_y )
80  , m_c( bubble_z )
81  , m_max_x( grid_max_x )
82  , m_max_y( grid_max_y )
83  , m_max_z( grid_max_z )
84  {}
85 
86  template< typename Scalar >
88  void operator()( int grid_x ,
89  int grid_y ,
90  int grid_z ,
91  Scalar & coord_x ,
92  Scalar & coord_y ,
93  Scalar & coord_z ) const
94  {
95  // Map to a unit cube [0,1]^3
96 
97  const double x = double(grid_x) / double(m_max_x);
98  const double y = double(grid_y) / double(m_max_y);
99  const double z = double(grid_z) / double(m_max_z);
100 
101  coord_x = x + x * x * ( x - 1 ) * ( x - 1 ) * m_a ;
102  coord_y = y + y * y * ( y - 1 ) * ( y - 1 ) * m_b ;
103  coord_z = z + z * z * ( z - 1 ) * ( z - 1 ) * m_c ;
104  }
105 };
106 
107 } // namespace Example
108 } // namespace Kokkos
109 
110 //----------------------------------------------------------------------------
111 
112 namespace Kokkos {
113 namespace Example {
114 
121 template< class Device ,
122  BoxElemPart::ElemOrder Order ,
123  class CoordinateMap = MapGridUnitCube >
125 public:
126 
127  typedef Device execution_space ;
128 
129  enum { SpaceDim = 3 };
130  enum { ElemNode = Order == BoxElemPart::ElemLinear ? 8 :
131  Order == BoxElemPart::ElemQuadratic ? 27 : 0 };
132 
133 private:
134 
136 
138  CoordinateMap m_coord_map ;
139 
140  Kokkos::View< double *[SpaceDim] , Device > m_node_coord ;
141  Kokkos::View< unsigned*[SpaceDim] , Device > m_node_grid ;
142  Kokkos::View< unsigned*[ElemNode] , Device > m_elem_node ;
143  Kokkos::View< unsigned*[2] , Device > m_recv_node ;
144  Kokkos::View< unsigned*[2] , Device > m_send_node ;
145  Kokkos::View< unsigned* , Device > m_send_node_id ;
146 
147  unsigned char m_elem_node_local[ ElemNode ][4] ;
148 
149 public:
150 
151  typedef Kokkos::View< const unsigned * [ElemNode], Device > elem_node_type ;
152  typedef Kokkos::View< const double * [SpaceDim], Device > node_coord_type ;
153  typedef Kokkos::View< const unsigned * [SpaceDim], Device > node_grid_type ;
154  typedef Kokkos::View< const unsigned * [2] , Device > comm_list_type ;
155  typedef Kokkos::View< const unsigned * , Device > send_nodeid_type ;
156 
158  unsigned node_count() const { return m_node_grid.extent(0); }
159 
161  unsigned node_count_owned() const { return m_box_part.owns_node_count(); }
162 
164  unsigned node_count_global() const { return m_box_part.global_node_count(); }
165 
167  unsigned elem_count() const { return m_elem_node.extent(0); }
168 
170  unsigned elem_count_global() const { return m_box_part.global_elem_count(); }
171 
173  unsigned elem_node_local( unsigned inode , unsigned k ) const
174  { return m_elem_node_local[inode][k] ; }
175 
177  unsigned node_grid( unsigned inode , unsigned iaxis ) const
178  { return m_node_grid(inode,iaxis); }
179 
181  size_t node_global_index( unsigned local ) const
182  {
183  const unsigned node_grid[SpaceDim] =
184  { m_node_grid(local,0) , m_node_grid(local,1) , m_node_grid(local,2) };
185  return m_box_part.global_node_id( node_grid );
186  }
187 
189  double node_coord( unsigned inode , unsigned iaxis ) const
190  { return m_node_coord(inode,iaxis); }
191 
193  unsigned node_grid_max( unsigned iaxis ) const
194  { return m_box_part.global_coord_max(iaxis); }
195 
197  unsigned elem_node( unsigned ielem , unsigned inode ) const
198  { return m_elem_node(ielem,inode); }
199 
200  elem_node_type elem_node() const { return m_elem_node ; }
202  node_grid_type node_grid() const { return m_node_grid ; }
203  comm_list_type recv_node() const { return m_recv_node ; }
204  comm_list_type send_node() const { return m_send_node ; }
206 
209  : m_box_part( rhs.m_box_part )
210  , m_coord_map( rhs.m_coord_map )
211  , m_node_coord( rhs.m_node_coord )
212  , m_node_grid( rhs.m_node_grid )
213  , m_elem_node( rhs.m_elem_node )
214  , m_recv_node( rhs.m_recv_node )
215  , m_send_node( rhs.m_send_node )
217  {
218  for ( unsigned i = 0 ; i < ElemNode ; ++i ) {
219  m_elem_node_local[i][0] = rhs.m_elem_node_local[i][0] ;
220  m_elem_node_local[i][1] = rhs.m_elem_node_local[i][1] ;
221  m_elem_node_local[i][2] = rhs.m_elem_node_local[i][2] ;
222  m_elem_node_local[i][3] = 0 ;
223  }
224  }
225 
227  {
228  m_box_part = rhs.m_box_part ;
229  m_coord_map = rhs.m_coord_map ;
230  m_node_coord = rhs.m_node_coord ;
231  m_node_grid = rhs.m_node_grid ;
232  m_elem_node = rhs.m_elem_node ;
233  m_recv_node = rhs.m_recv_node ;
234  m_send_node = rhs.m_send_node ;
236 
237  for ( unsigned i = 0 ; i < ElemNode ; ++i ) {
238  m_elem_node_local[i][0] = rhs.m_elem_node_local[i][0] ;
239  m_elem_node_local[i][1] = rhs.m_elem_node_local[i][1] ;
240  m_elem_node_local[i][2] = rhs.m_elem_node_local[i][2] ;
241  m_elem_node_local[i][3] = 0 ;
242  }
243  return *this ;
244  }
245 
247  const unsigned global_size ,
248  const unsigned global_rank ,
249  const unsigned elem_nx ,
250  const unsigned elem_ny ,
251  const unsigned elem_nz ,
252  const double bubble_x = 1.1 ,
253  const double bubble_y = 1.2 ,
254  const double bubble_z = 1.3 )
255  : m_box_part( Order , decompose , global_size , global_rank , elem_nx , elem_ny , elem_nz )
256  , m_coord_map( m_box_part.global_coord_max(0) ,
257  m_box_part.global_coord_max(1) ,
258  m_box_part.global_coord_max(2) ,
259  bubble_x ,
260  bubble_y ,
261  bubble_z )
262  , m_node_coord( "fixture_node_coord" , m_box_part.uses_node_count() )
263  , m_node_grid( "fixture_node_grid" , m_box_part.uses_node_count() )
264  , m_elem_node( "fixture_elem_node" , m_box_part.uses_elem_count() )
265  , m_recv_node( "fixture_recv_node" , m_box_part.recv_node_msg_count() )
266  , m_send_node( "fixture_send_node" , m_box_part.send_node_msg_count() )
267  , m_send_node_id( "fixture_send_node_id" , m_box_part.send_node_id_count() )
268  {
269  {
270  const hex_data elem_data ;
271 
272  for ( unsigned i = 0 ; i < ElemNode ; ++i ) {
273  m_elem_node_local[i][0] = elem_data.eval_map[i][0] ;
274  m_elem_node_local[i][1] = elem_data.eval_map[i][1] ;
275  m_elem_node_local[i][2] = elem_data.eval_map[i][2] ;
276  m_elem_node_local[i][3] = 0 ;
277  }
278  }
279 
280  const size_t nwork =
281  std::max( m_recv_node.extent(0) ,
282  std::max( m_send_node.extent(0) ,
283  std::max( m_send_node_id.extent(0) ,
284  std::max( m_node_grid.extent(0) ,
285  m_elem_node.extent(0) * m_elem_node.extent(1) ))));
286 
287  Kokkos::parallel_for( nwork , *this );
288  }
289 
290 
291  // Initialization:
292 
294  void operator()( size_t i ) const
295  {
296  if ( i < m_elem_node.extent(0) * m_elem_node.extent(1) ) {
297 
298  const size_t ielem = i / ElemNode ;
299  const size_t inode = i % ElemNode ;
300 
301  unsigned elem_grid[SpaceDim] ;
302  unsigned node_grid[SpaceDim] ;
303 
304  m_box_part.uses_elem_coord( ielem , elem_grid );
305 
306  enum { elem_node_scale = Order == BoxElemPart::ElemLinear ? 1 :
307  Order == BoxElemPart::ElemQuadratic ? 2 : 0 };
308 
309  node_grid[0] = elem_node_scale * elem_grid[0] + m_elem_node_local[inode][0] ;
310  node_grid[1] = elem_node_scale * elem_grid[1] + m_elem_node_local[inode][1] ;
311  node_grid[2] = elem_node_scale * elem_grid[2] + m_elem_node_local[inode][2] ;
312 
313  m_elem_node(ielem,inode) = m_box_part.local_node_id( node_grid );
314  }
315 
316  if ( i < m_node_grid.extent(0) ) {
317  unsigned node_grid[SpaceDim] ;
318  m_box_part.local_node_coord( i , node_grid );
319  m_node_grid(i,0) = node_grid[0] ;
320  m_node_grid(i,1) = node_grid[1] ;
321  m_node_grid(i,2) = node_grid[2] ;
322 
323  m_coord_map( node_grid[0] ,
324  node_grid[1] ,
325  node_grid[2] ,
326  m_node_coord(i,0) ,
327  m_node_coord(i,1) ,
328  m_node_coord(i,2) );
329  }
330 
331  if ( i < m_recv_node.extent(0) ) {
334  }
335 
336  if ( i < m_send_node.extent(0) ) {
339  }
340 
341  if ( i < m_send_node_id.extent(0) ) {
343  }
344  }
345 };
346 
347 } // namespace Example
348 } // namespace Kokkos
349 
350 //----------------------------------------------------------------------------
351 
352 #endif /* #ifndef KOKKOS_EXAMPLE_BOXELEMFIXTURE_HPP */
353 
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
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
#define KOKKOS_INLINE_FUNCTION
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
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.
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...