Stokhos Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
FadMPAssembly/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
57namespace Kokkos {
58namespace 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 >
87 KOKKOS_INLINE_FUNCTION
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
112namespace Kokkos {
113namespace Example {
114
121template< class Device ,
123 class CoordinateMap = MapGridUnitCube >
125public:
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
133private:
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
149public:
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
157 KOKKOS_INLINE_FUNCTION
158 unsigned node_count() const { return m_node_grid.extent(0); }
159
160 KOKKOS_INLINE_FUNCTION
161 unsigned node_count_owned() const { return m_box_part.owns_node_count(); }
162
163 KOKKOS_INLINE_FUNCTION
164 unsigned node_count_global() const { return m_box_part.global_node_count(); }
165
166 KOKKOS_INLINE_FUNCTION
167 unsigned elem_count() const { return m_elem_node.extent(0); }
168
169 KOKKOS_INLINE_FUNCTION
170 unsigned elem_count_global() const { return m_box_part.global_elem_count(); }
171
172 KOKKOS_INLINE_FUNCTION
173 unsigned elem_node_local( unsigned inode , unsigned k ) const
174 { return m_elem_node_local[inode][k] ; }
175
176 KOKKOS_INLINE_FUNCTION
177 unsigned node_grid( unsigned inode , unsigned iaxis ) const
178 { return m_node_grid(inode,iaxis); }
179
180 KOKKOS_INLINE_FUNCTION
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) };
186 }
187
188 KOKKOS_INLINE_FUNCTION
189 double node_coord( unsigned inode , unsigned iaxis ) const
190 { return m_node_coord(inode,iaxis); }
191
192 KOKKOS_INLINE_FUNCTION
193 unsigned node_grid_max( unsigned iaxis ) const
194 { return m_box_part.global_coord_max(iaxis); }
195
196 KOKKOS_INLINE_FUNCTION
197 unsigned elem_node( unsigned ielem , unsigned inode ) const
198 { return m_elem_node(ielem,inode); }
199
206
207 KOKKOS_INLINE_FUNCTION
209 : m_box_part( rhs.m_box_part )
210 , m_coord_map( rhs.m_coord_map )
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 ;
235 m_send_node_id = rhs.m_send_node_id ;
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
293 KOKKOS_INLINE_FUNCTION
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
314 }
315
316 if ( i < m_node_grid.extent(0) ) {
317 unsigned node_grid[SpaceDim] ;
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
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
Generate a distributed unstructured finite element mesh from a partitioned NX*NY*NZ box of elements.
Kokkos::View< const double *[SpaceDim], Device > node_coord_type
Kokkos::View< unsigned *[2], Device > m_send_node
Kokkos::View< unsigned *[SpaceDim], Device > m_node_grid
KOKKOS_INLINE_FUNCTION unsigned elem_count_global() const
Kokkos::View< const unsigned *[SpaceDim], Device > node_grid_type
Kokkos::View< const unsigned *, Device > send_nodeid_type
Kokkos::View< unsigned *[2], Device > m_recv_node
Kokkos::View< const unsigned *[ElemNode], Device > elem_node_type
BoxElemFixture & operator=(const BoxElemFixture &rhs)
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)
Kokkos::Example::HexElement_TensorData< ElemNode > hex_data
Kokkos::View< double *[SpaceDim], Device > m_node_coord
KOKKOS_INLINE_FUNCTION BoxElemFixture(const BoxElemFixture &rhs)
KOKKOS_INLINE_FUNCTION unsigned elem_node(unsigned ielem, unsigned inode) const
Kokkos::View< unsigned *, Device > m_send_node_id
KOKKOS_INLINE_FUNCTION unsigned node_count() const
KOKKOS_INLINE_FUNCTION unsigned node_grid(unsigned inode, unsigned iaxis) const
KOKKOS_INLINE_FUNCTION void operator()(size_t i) const
Kokkos::View< const unsigned *[2], Device > comm_list_type
KOKKOS_INLINE_FUNCTION size_t node_global_index(unsigned local) const
KOKKOS_INLINE_FUNCTION unsigned elem_node_local(unsigned inode, unsigned k) const
KOKKOS_INLINE_FUNCTION double node_coord(unsigned inode, unsigned iaxis) const
KOKKOS_INLINE_FUNCTION unsigned node_count_owned() const
KOKKOS_INLINE_FUNCTION unsigned elem_count() const
Kokkos::View< unsigned *[ElemNode], Device > m_elem_node
KOKKOS_INLINE_FUNCTION unsigned node_count_global() const
KOKKOS_INLINE_FUNCTION unsigned node_grid_max(unsigned iaxis) const
Partition a box of hexahedral elements among subdomains.
KOKKOS_INLINE_FUNCTION unsigned local_node_id(const unsigned c[]) const
KOKKOS_INLINE_FUNCTION unsigned send_node_id(unsigned item) const
KOKKOS_INLINE_FUNCTION void uses_elem_coord(size_t lid, unsigned c[]) const
KOKKOS_INLINE_FUNCTION size_t global_elem_count() const
KOKKOS_INLINE_FUNCTION void local_node_coord(size_t lid, unsigned coord[]) const
KOKKOS_INLINE_FUNCTION unsigned global_coord_max(unsigned axis) const
KOKKOS_INLINE_FUNCTION unsigned recv_node_rank(unsigned msg) const
KOKKOS_INLINE_FUNCTION size_t owns_node_count() const
KOKKOS_INLINE_FUNCTION unsigned send_node_rank(unsigned msg) const
KOKKOS_INLINE_FUNCTION unsigned send_node_count(unsigned msg) const
KOKKOS_INLINE_FUNCTION unsigned recv_node_count(unsigned msg) const
KOKKOS_INLINE_FUNCTION size_t global_node_count() const
KOKKOS_INLINE_FUNCTION size_t global_node_id(const unsigned c[]) const
Map a grid onto a unit cube with smooth nonlinear grading of the map.
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 void operator()(int grid_x, int grid_y, int grid_z, Scalar &coord_x, Scalar &coord_y, Scalar &coord_z) const