Sacado Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
view/fenl_functors.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_FENLFUNCTORS_HPP
18 #define KOKKOS_EXAMPLE_FENLFUNCTORS_HPP
19 
20 #include <stdio.h>
21 
22 #include <iostream>
23 #include <fstream>
24 #include <iomanip>
25 #include <cstdlib>
26 #include <cmath>
27 #include <limits>
28 
29 #include <Kokkos_Core.hpp>
30 #include <Kokkos_Pair.hpp>
31 #include <Kokkos_UnorderedMap.hpp>
32 #include <Kokkos_StaticCrsGraph.hpp>
33 
34 #include <Kokkos_Timer.hpp>
35 
36 #include <BoxElemFixture.hpp>
37 #include <HexElement.hpp>
38 
39 #include "Sacado.hpp"
40 
41 //----------------------------------------------------------------------------
42 //----------------------------------------------------------------------------
43 
44 namespace Kokkos {
45 namespace Example {
46 namespace FENL {
47 
48 template< typename ValueType , class Space >
49 struct CrsMatrix {
50 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE // Don't remove this until Kokkos has removed the deprecated code path probably around September 2018
51  typedef Kokkos::StaticCrsGraph< unsigned , Space , void , unsigned > StaticCrsGraphType ;
52 #else
53  typedef Kokkos::StaticCrsGraph< unsigned , Space , void , void , unsigned > StaticCrsGraphType ;
54 #endif
55  typedef View< ValueType * , Space > coeff_type ;
56 
59 
60  CrsMatrix() : graph(), coeff() {}
61 
62  CrsMatrix( const StaticCrsGraphType & arg_graph )
63  : graph( arg_graph )
64  , coeff( "crs_matrix_coeff" , arg_graph.entries.extent(0) )
65  {}
66 };
67 
68 template< class ElemNodeIdView , class CrsGraphType , unsigned ElemNode >
69 class NodeNodeGraph {
70 public:
71 
72  typedef typename ElemNodeIdView::execution_space execution_space ;
73  typedef pair<unsigned,unsigned> key_type ;
74 
75  typedef Kokkos::UnorderedMap< key_type, void , execution_space > SetType ;
76  typedef typename CrsGraphType::row_map_type::non_const_type RowMapType ;
77  typedef Kokkos::View< unsigned , execution_space > UnsignedValue ;
78 
79  // Static dimensions of 0 generate compiler warnings or errors.
80  typedef Kokkos::View< unsigned*[ElemNode][ElemNode] , execution_space >
82 
83  struct TagFillNodeSet {};
84  struct TagScanNodeCount {};
85  struct TagFillGraphEntries {};
86  struct TagSortGraphEntries {};
87  struct TagFillElementGraph {};
88 
89 private:
90 
96 
97  const unsigned node_count ;
98  const ElemNodeIdView elem_node_id ;
103  PhaseType phase ;
104 
105 public:
106 
107  CrsGraphType graph ;
109 
110  struct Times
111  {
112  double ratio;
113  double fill_node_set;
114  double scan_node_count;
115  double fill_graph_entries;
116  double sort_graph_entries;
117  double fill_element_graph;
118  };
119 
120  NodeNodeGraph( const ElemNodeIdView & arg_elem_node_id ,
121  const unsigned arg_node_count,
122  Times & results
123  )
124  : node_count(arg_node_count)
125  , elem_node_id( arg_elem_node_id )
126  , row_total( "row_total" )
127  , row_count(Kokkos::ViewAllocateWithoutInitializing("row_count") , node_count ) // will deep_copy to 0 inside loop
128  , row_map( "graph_row_map" , node_count + 1 )
129  , node_node_set()
130  , phase( FILL_NODE_SET )
131  , graph()
132  , elem_graph()
133  {
134  //--------------------------------
135  // Guess at capacity required for the map:
136 
137  Kokkos::Timer wall_clock ;
138 
139  wall_clock.reset();
140  phase = FILL_NODE_SET ;
141 
142  // upper bound on the capacity
143  size_t set_capacity = (28ull * node_count) / 2;
144  unsigned failed_insert_count = 0 ;
145 
146  do {
147  // Zero the row count to restart the fill
148  Kokkos::deep_copy( row_count , 0u );
149 
150  node_node_set = SetType( ( set_capacity += failed_insert_count ) );
151 
152  // May be larger that requested:
153  set_capacity = node_node_set.capacity();
154 
155  Kokkos::parallel_reduce( Kokkos::RangePolicy<execution_space,TagFillNodeSet>(0,elem_node_id.extent(0))
156  , *this
157  , failed_insert_count );
158 
159  } while ( failed_insert_count );
160 
161  execution_space().fence();
162  results.ratio = (double)node_node_set.size() / (double)node_node_set.capacity();
163  results.fill_node_set = wall_clock.seconds();
164  //--------------------------------
165 
166  wall_clock.reset();
168 
169  // Exclusive scan of row_count into row_map
170  // including the final total in the 'node_count + 1' position.
171  // Zero the 'row_count' values.
172  Kokkos::parallel_scan( node_count , *this );
173 
174  // Zero the row count for the fill:
175  Kokkos::deep_copy( row_count , 0u );
176 
177  unsigned graph_entry_count = 0 ;
178 
179  Kokkos::deep_copy( graph_entry_count , row_total );
180 
181  // Assign graph's row_map and allocate graph's entries
182  graph.row_map = row_map ;
183  graph.entries = typename CrsGraphType::entries_type( "graph_entries" , graph_entry_count );
184 
185  //--------------------------------
186  // Fill graph's entries from the (node,node) set.
187 
188  execution_space().fence();
189  results.scan_node_count = wall_clock.seconds();
190 
191  wall_clock.reset();
193  Kokkos::parallel_for( node_node_set.capacity() , *this );
194 
195  execution_space().fence();
196  results.fill_graph_entries = wall_clock.seconds();
197 
198  //--------------------------------
199  // Done with the temporary sets and arrays
200  wall_clock.reset();
202 
204  row_count = RowMapType();
205  row_map = RowMapType();
206  node_node_set.clear();
207 
208  //--------------------------------
209 
210  Kokkos::parallel_for( node_count , *this );
211 
212  execution_space().fence();
213  results.sort_graph_entries = wall_clock.seconds();
214 
215  //--------------------------------
216  // Element-to-graph mapping:
217  wall_clock.reset();
219  elem_graph = ElemGraphType("elem_graph", elem_node_id.extent(0) );
220  Kokkos::parallel_for( elem_node_id.extent(0) , *this );
221 
222  execution_space().fence();
223  results.fill_element_graph = wall_clock.seconds();
224  }
225 
226  //------------------------------------
227  // parallel_for: create map and count row length
228 
229  KOKKOS_INLINE_FUNCTION
230  void operator()( const TagFillNodeSet & , unsigned ielem , unsigned & count ) const
231  {
232  // Loop over element's (row_local_node,col_local_node) pairs:
233  for ( unsigned row_local_node = 0 ; row_local_node < elem_node_id.extent(1) ; ++row_local_node ) {
234 
235  const unsigned row_node = elem_node_id( ielem , row_local_node );
236 
237  for ( unsigned col_local_node = row_local_node ; col_local_node < elem_node_id.extent(1) ; ++col_local_node ) {
238 
239  const unsigned col_node = elem_node_id( ielem , col_local_node );
240 
241  // If either node is locally owned then insert the pair into the unordered map:
242 
243  if ( row_node < row_count.extent(0) || col_node < row_count.extent(0) ) {
244 
245  const key_type key = (row_node < col_node) ? make_pair( row_node, col_node ) : make_pair( col_node, row_node ) ;
246 
247  const typename SetType::insert_result result = node_node_set.insert( key );
248 
249  // A successfull insert: the first time this pair was added
250  if ( result.success() ) {
251 
252  // If row node is owned then increment count
253  if ( row_node < row_count.extent(0) ) { atomic_inc( & row_count( row_node ) ); }
254 
255  // If column node is owned and not equal to row node then increment count
256  if ( col_node < row_count.extent(0) && col_node != row_node ) { atomic_inc( & row_count( col_node ) ); }
257  }
258  else if ( result.failed() ) {
259  ++count ;
260  }
261  }
262  }
263  }
264  }
265 
266  KOKKOS_INLINE_FUNCTION
267  void fill_graph_entries( const unsigned iset ) const
268  {
269  typedef typename std::remove_reference< decltype( row_count(0) ) >::type atomic_incr_type;
270 
271  if ( node_node_set.valid_at(iset) ) {
272  // Add each entry to the graph entries.
273 
274  const key_type key = node_node_set.key_at(iset) ;
275  const unsigned row_node = key.first ;
276  const unsigned col_node = key.second ;
277 
278  if ( row_node < row_count.extent(0) ) {
279  const unsigned offset = graph.row_map( row_node ) + atomic_fetch_add( & row_count( row_node ) , atomic_incr_type(1) );
280  graph.entries( offset ) = col_node ;
281  }
282 
283  if ( col_node < row_count.extent(0) && col_node != row_node ) {
284  const unsigned offset = graph.row_map( col_node ) + atomic_fetch_add( & row_count( col_node ) , atomic_incr_type(1) );
285  graph.entries( offset ) = row_node ;
286  }
287  }
288  }
289 
290  KOKKOS_INLINE_FUNCTION
291  void sort_graph_entries( const unsigned irow ) const
292  {
293  const unsigned row_beg = graph.row_map( irow );
294  const unsigned row_end = graph.row_map( irow + 1 );
295  for ( unsigned i = row_beg + 1 ; i < row_end ; ++i ) {
296  const unsigned col = graph.entries(i);
297  unsigned j = i ;
298  for ( ; row_beg < j && col < graph.entries(j-1) ; --j ) {
299  graph.entries(j) = graph.entries(j-1);
300  }
301  graph.entries(j) = col ;
302  }
303  }
304 
305  KOKKOS_INLINE_FUNCTION
306  void fill_elem_graph_map( const unsigned ielem ) const
307  {
308  for ( unsigned row_local_node = 0 ; row_local_node < elem_node_id.extent(1) ; ++row_local_node ) {
309 
310  const unsigned row_node = elem_node_id( ielem , row_local_node );
311 
312  for ( unsigned col_local_node = 0 ; col_local_node < elem_node_id.extent(1) ; ++col_local_node ) {
313 
314  const unsigned col_node = elem_node_id( ielem , col_local_node );
315 
316  unsigned entry = ~0u ;
317 
318  if ( row_node + 1 < graph.row_map.extent(0) ) {
319 
320  const unsigned entry_end = graph.row_map( row_node + 1 );
321 
322  entry = graph.row_map( row_node );
323 
324  for ( ; entry < entry_end && graph.entries(entry) != col_node ; ++entry );
325 
326  if ( entry == entry_end ) entry = ~0u ;
327  }
328 
329  elem_graph( ielem , row_local_node , col_local_node ) = entry ;
330  }
331  }
332  }
333 
334  KOKKOS_INLINE_FUNCTION
335  void operator()( const unsigned iwork ) const
336  {
337 /*
338  if ( phase == FILL_NODE_SET ) {
339  operator()( TagFillNodeSet() , iwork );
340  }
341  else */
342  if ( phase == FILL_GRAPH_ENTRIES ) {
343  fill_graph_entries( iwork );
344  }
345  else if ( phase == SORT_GRAPH_ENTRIES ) {
346  sort_graph_entries( iwork );
347  }
348  else if ( phase == FILL_ELEMENT_GRAPH ) {
349  fill_elem_graph_map( iwork );
350  }
351  }
352 
353  //------------------------------------
354  // parallel_scan: row offsets
355 
356  typedef unsigned value_type ;
357 
358  KOKKOS_INLINE_FUNCTION
359  void operator()( const unsigned irow , unsigned & update , const bool final ) const
360  {
361  // exclusive scan
362  if ( final ) { row_map( irow ) = update ; }
363 
364  update += row_count( irow );
365 
366  if ( final ) {
367  if ( irow + 1 == row_count.extent(0) ) {
368  row_map( irow + 1 ) = update ;
369  row_total() = update ;
370  }
371  }
372  }
373 
374  // For the reduce phase:
375  KOKKOS_INLINE_FUNCTION
376  void init( const TagFillNodeSet & , unsigned & update ) const { update = 0 ; }
377 
378  KOKKOS_INLINE_FUNCTION
379  void join( const TagFillNodeSet &
380  , unsigned & update
381  , const unsigned & input ) const { update += input ; }
382 
383  // For the scan phase::
384  KOKKOS_INLINE_FUNCTION
385  void init( unsigned & update ) const { update = 0 ; }
386 
387  KOKKOS_INLINE_FUNCTION
388  void join( unsigned & update
389  , const unsigned & input ) const { update += input ; }
390 
391  //------------------------------------
392 };
393 
394 } /* namespace FENL */
395 } /* namespace Example */
396 } /* namespace Kokkos */
397 
398 //----------------------------------------------------------------------------
399 //----------------------------------------------------------------------------
400 
401 namespace Kokkos {
402 namespace Example {
403 namespace FENL {
404 
405 template< class ExecutionSpace , BoxElemPart::ElemOrder Order ,
406  class CoordinateMap , typename ScalarType >
407 class ElementComputationBase
408 {
409 public:
410 
413 
414  //------------------------------------
415 
416  typedef ExecutionSpace execution_space ;
417  typedef ScalarType scalar_type ;
418 
421  typedef Kokkos::View< scalar_type* , Kokkos::LayoutLeft, execution_space > vector_type ;
422 
423  //------------------------------------
424 
425  static const unsigned SpatialDim = element_data_type::spatial_dimension ;
426  static const unsigned TensorDim = SpatialDim * SpatialDim ;
427  static const unsigned ElemNodeCount = element_data_type::element_node_count ;
428  static const unsigned FunctionCount = element_data_type::function_count ;
430 
431  //------------------------------------
432 
435  typedef Kokkos::View< scalar_type*[FunctionCount][FunctionCount] , execution_space > elem_matrices_type ;
436  typedef Kokkos::View< scalar_type*[FunctionCount] , execution_space > elem_vectors_type ;
437 
439 
440  //------------------------------------
441 
442 
443  //------------------------------------
444  // Computational data:
445 
452  const vector_type solution ;
453  const vector_type residual ;
455 
457  : elem_data()
459  , node_coords( rhs.node_coords )
460  , elem_graph( rhs.elem_graph )
463  , solution( rhs.solution )
464  , residual( rhs.residual )
465  , jacobian( rhs.jacobian )
466  {}
467 
468  ElementComputationBase( const mesh_type & arg_mesh ,
469  const vector_type & arg_solution ,
470  const elem_graph_type & arg_elem_graph ,
471  const sparse_matrix_type & arg_jacobian ,
472  const vector_type & arg_residual )
473  : elem_data()
474  , elem_node_ids( arg_mesh.elem_node() )
475  , node_coords( arg_mesh.node_coord() )
476  , elem_graph( arg_elem_graph )
477  , elem_jacobians()
478  , elem_residuals()
479  , solution( arg_solution )
480  , residual( arg_residual )
481  , jacobian( arg_jacobian )
482  {}
483 
484  //------------------------------------
485 
486  KOKKOS_INLINE_FUNCTION
488  const double grad[][ FunctionCount ] , // Gradient of bases master element
489  const double x[] ,
490  const double y[] ,
491  const double z[] ,
492  double dpsidx[] ,
493  double dpsidy[] ,
494  double dpsidz[] ) const
495  {
496  enum { j11 = 0 , j12 = 1 , j13 = 2 ,
497  j21 = 3 , j22 = 4 , j23 = 5 ,
498  j31 = 6 , j32 = 7 , j33 = 8 };
499 
500  // Jacobian accumulation:
501 
502  double J[ TensorDim ] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
503 
504  for( unsigned i = 0; i < FunctionCount ; ++i ) {
505  const double x1 = x[i] ;
506  const double x2 = y[i] ;
507  const double x3 = z[i] ;
508 
509  const double g1 = grad[0][i] ;
510  const double g2 = grad[1][i] ;
511  const double g3 = grad[2][i] ;
512 
513  J[j11] += g1 * x1 ;
514  J[j12] += g1 * x2 ;
515  J[j13] += g1 * x3 ;
516 
517  J[j21] += g2 * x1 ;
518  J[j22] += g2 * x2 ;
519  J[j23] += g2 * x3 ;
520 
521  J[j31] += g3 * x1 ;
522  J[j32] += g3 * x2 ;
523  J[j33] += g3 * x3 ;
524  }
525 
526  // Inverse jacobian:
527 
528  double invJ[ TensorDim ] = {
529  static_cast<double>( J[j22] * J[j33] - J[j23] * J[j32] ) ,
530  static_cast<double>( J[j13] * J[j32] - J[j12] * J[j33] ) ,
531  static_cast<double>( J[j12] * J[j23] - J[j13] * J[j22] ) ,
532 
533  static_cast<double>( J[j23] * J[j31] - J[j21] * J[j33] ) ,
534  static_cast<double>( J[j11] * J[j33] - J[j13] * J[j31] ) ,
535  static_cast<double>( J[j13] * J[j21] - J[j11] * J[j23] ) ,
536 
537  static_cast<double>( J[j21] * J[j32] - J[j22] * J[j31] ) ,
538  static_cast<double>( J[j12] * J[j31] - J[j11] * J[j32] ) ,
539  static_cast<double>( J[j11] * J[j22] - J[j12] * J[j21] ) };
540 
541  const double detJ = J[j11] * invJ[j11] +
542  J[j21] * invJ[j12] +
543  J[j31] * invJ[j13] ;
544 
545  const double detJinv = 1.0 / detJ ;
546 
547  for ( unsigned i = 0 ; i < TensorDim ; ++i ) { invJ[i] *= detJinv ; }
548 
549  // Transform gradients:
550 
551  for( unsigned i = 0; i < FunctionCount ; ++i ) {
552  const double g0 = grad[0][i];
553  const double g1 = grad[1][i];
554  const double g2 = grad[2][i];
555 
556  dpsidx[i] = g0 * invJ[j11] + g1 * invJ[j12] + g2 * invJ[j13];
557  dpsidy[i] = g0 * invJ[j21] + g1 * invJ[j22] + g2 * invJ[j23];
558  dpsidz[i] = g0 * invJ[j31] + g1 * invJ[j32] + g2 * invJ[j33];
559  }
560 
561  return detJ ;
562  }
563 
564 };
565 
567  Analytic,
568  FadElement,
571 };
572 
573 template< class FiniteElementMeshType ,
574  class SparseMatrixType ,
576  >
577 class ElementComputation ;
578 
579 template< class ExecutionSpace , BoxElemPart::ElemOrder Order ,
580  class CoordinateMap , typename ScalarType >
581 class ElementComputation
582  < Kokkos::Example::BoxElemFixture< ExecutionSpace , Order , CoordinateMap > ,
583  CrsMatrix< ScalarType , ExecutionSpace > ,
584  Analytic > :
585  public ElementComputationBase<ExecutionSpace, Order, CoordinateMap,
586  ScalarType> {
587 public:
588 
589  typedef ElementComputationBase<ExecutionSpace, Order, CoordinateMap,
590  ScalarType> base_type;
591 
594 
595  static const unsigned FunctionCount = base_type::FunctionCount;
596  static const unsigned IntegrationCount = base_type::IntegrationCount;
597  static const unsigned ElemNodeCount = base_type::ElemNodeCount;
598 
599  typedef Kokkos::View<scalar_type[FunctionCount],Kokkos::LayoutRight,execution_space,Kokkos::MemoryUnmanaged> elem_vec_type;
600  typedef Kokkos::View<scalar_type[FunctionCount][FunctionCount],Kokkos::LayoutRight,execution_space,Kokkos::MemoryUnmanaged> elem_mat_type;
601 
603 
605  const typename base_type::mesh_type & arg_mesh ,
606  const typename base_type::vector_type & arg_solution ,
607  const typename base_type::elem_graph_type & arg_elem_graph ,
608  const typename base_type::sparse_matrix_type & arg_jacobian ,
609  const typename base_type::vector_type & arg_residual ) :
610  base_type(arg_mesh, arg_solution, arg_elem_graph,
611  arg_jacobian, arg_residual) {}
612 
613  //------------------------------------
614 
615  void apply() const
616  {
617  const size_t nelem = this->elem_node_ids.extent(0);
618  parallel_for( nelem , *this );
619  }
620 
621  KOKKOS_INLINE_FUNCTION
622  void gatherSolution(const unsigned ielem,
623  const elem_vec_type& val,
624  unsigned node_index[],
625  double x[], double y[], double z[],
626  const elem_vec_type& res,
627  const elem_mat_type& mat) const
628  {
629  for ( unsigned i = 0 ; i < ElemNodeCount ; ++i ) {
630  const unsigned ni = this->elem_node_ids( ielem , i );
631 
632  node_index[i] = ni ;
633 
634  x[i] = this->node_coords( ni , 0 );
635  y[i] = this->node_coords( ni , 1 );
636  z[i] = this->node_coords( ni , 2 );
637 
638  val(i) = this->solution( ni ) ;
639  res(i) = 0 ;
640 
641  for( unsigned j = 0; j < FunctionCount ; j++){
642  mat(i,j) = 0 ;
643  }
644  }
645  }
646 
647  KOKKOS_INLINE_FUNCTION
648  void scatterResidual(const unsigned ielem,
649  const unsigned node_index[],
650  const elem_vec_type& res,
651  const elem_mat_type& mat) const
652  {
653  for( unsigned i = 0 ; i < FunctionCount ; i++ ) {
654  const unsigned row = node_index[i] ;
655  if ( row < this->residual.extent(0) ) {
656  atomic_add( & this->residual( row ) , res(i) );
657 
658  for( unsigned j = 0 ; j < FunctionCount ; j++ ) {
659  const unsigned entry = this->elem_graph( ielem , i , j );
660  if ( entry != ~0u ) {
661  atomic_add( & this->jacobian.coeff( entry ) , mat(i,j) );
662  }
663  }
664  }
665  }
666  }
667 
668  KOKKOS_INLINE_FUNCTION
670  const elem_vec_type& dof_values ,
671  const double x[],
672  const double y[],
673  const double z[],
674  const elem_vec_type& elem_res ,
675  const elem_mat_type& elem_mat ) const
676  {
677  double coeff_k = 3.456;
678  double coeff_src = 1.234;
679  double advection[] = { 1.1, 1.2, 1.3 };
680  double dpsidx[ FunctionCount ] ;
681  double dpsidy[ FunctionCount ] ;
682  double dpsidz[ FunctionCount ] ;
683  for ( unsigned i = 0 ; i < IntegrationCount ; ++i ) {
684 
685  const double integ_weight = this->elem_data.weights[i];
686  const double* bases_vals = this->elem_data.values[i];
687  const double detJ =
688  this->transform_gradients( this->elem_data.gradients[i] ,
689  x , y , z ,
690  dpsidx , dpsidy , dpsidz );
691  const double detJ_weight = detJ * integ_weight;
692  const double detJ_weight_coeff_k = detJ_weight * coeff_k;
693 
694  scalar_type value_at_pt = 0 ;
695  scalar_type gradx_at_pt = 0 ;
696  scalar_type grady_at_pt = 0 ;
697  scalar_type gradz_at_pt = 0 ;
698  for ( unsigned m = 0 ; m < FunctionCount ; m++ ) {
699  value_at_pt += dof_values(m) * bases_vals[m] ;
700  gradx_at_pt += dof_values(m) * dpsidx[m] ;
701  grady_at_pt += dof_values(m) * dpsidy[m] ;
702  gradz_at_pt += dof_values(m) * dpsidz[m] ;
703  }
704 
705  const scalar_type source_term =
706  coeff_src * value_at_pt * value_at_pt ;
707  const scalar_type source_deriv =
708  2.0 * coeff_src * value_at_pt ;
709 
710  const scalar_type advection_x = advection[0];
711  const scalar_type advection_y = advection[1];
712  const scalar_type advection_z = advection[2];
713 
714  const scalar_type advection_term =
715  advection_x*gradx_at_pt +
716  advection_y*grady_at_pt +
717  advection_z*gradz_at_pt ;
718 
719  for ( unsigned m = 0; m < FunctionCount; ++m) {
720  const double bases_val_m = bases_vals[m] * detJ_weight ;
721  const double dpsidx_m = dpsidx[m] ;
722  const double dpsidy_m = dpsidy[m] ;
723  const double dpsidz_m = dpsidz[m] ;
724 
725  elem_res(m) +=
726  detJ_weight_coeff_k * ( dpsidx_m * gradx_at_pt +
727  dpsidy_m * grady_at_pt +
728  dpsidz_m * gradz_at_pt ) +
729  bases_val_m * ( advection_term + source_term ) ;
730 
731  for( unsigned n = 0; n < FunctionCount; n++) {
732  const double dpsidx_n = dpsidx[n] ;
733  const double dpsidy_n = dpsidy[n] ;
734  const double dpsidz_n = dpsidz[n] ;
735  elem_mat(m,n) +=
736  detJ_weight_coeff_k * ( dpsidx_m * dpsidx_n +
737  dpsidy_m * dpsidy_n +
738  dpsidz_m * dpsidz_n ) +
739  bases_val_m * ( advection_x * dpsidx_n +
740  advection_y * dpsidy_n +
741  advection_z * dpsidz_n +
742  source_deriv * bases_vals[n] ) ;
743  }
744  }
745  }
746  }
747 
748  KOKKOS_INLINE_FUNCTION
749  void operator()( const unsigned ielem ) const
750  {
751  double x[ FunctionCount ] ;
752  double y[ FunctionCount ] ;
753  double z[ FunctionCount ] ;
754  unsigned node_index[ ElemNodeCount ];
755 
756  scalar_type local_val[FunctionCount], local_res[FunctionCount], local_mat[FunctionCount*FunctionCount];
757  elem_vec_type val(local_val, FunctionCount) ;
758  elem_vec_type elem_res(local_res, FunctionCount ) ;
759  elem_mat_type elem_mat(local_mat, FunctionCount, FunctionCount ) ;
760 
761  // Gather nodal coordinates and solution vector:
762  gatherSolution(ielem, val, node_index, x, y, z, elem_res, elem_mat);
763 
764  // Compute nodal element residual vector and Jacobian matrix
765  computeElementResidualJacobian( val, x, y, z, elem_res , elem_mat );
766 
767  // Scatter nodal element residual and Jacobian in global vector and matrix:
768  scatterResidual( ielem, node_index, elem_res, elem_mat );
769  }
770 }; /* ElementComputation */
771 
772 template< class ExecutionSpace , BoxElemPart::ElemOrder Order ,
773  class CoordinateMap , typename ScalarType >
774 class ElementComputation
775  < Kokkos::Example::BoxElemFixture< ExecutionSpace , Order , CoordinateMap > ,
776  CrsMatrix< ScalarType , ExecutionSpace > ,
777  FadElement > : public ElementComputationBase<ExecutionSpace, Order, CoordinateMap,
778  ScalarType> {
779 public:
780 
781  typedef ElementComputationBase<ExecutionSpace, Order, CoordinateMap,
782  ScalarType> base_type;
783 
786 
787  static const unsigned FunctionCount = base_type::FunctionCount;
788  static const unsigned IntegrationCount = base_type::IntegrationCount;
789  static const unsigned ElemNodeCount = base_type::ElemNodeCount;
790 
792 
793  //typedef Kokkos::View<fad_scalar_type[FunctionCount],Kokkos::LayoutRight,execution_space,Kokkos::MemoryUnmanaged> elem_vec_type;
794  typedef Kokkos::View<fad_scalar_type*,Kokkos::LayoutRight,execution_space,Kokkos::MemoryUnmanaged> elem_vec_type; // possibly fix warning and internal compiler error with gcc 4.7.2????
795 
797 
799  const typename base_type::mesh_type & arg_mesh ,
800  const typename base_type::vector_type & arg_solution ,
801  const typename base_type::elem_graph_type & arg_elem_graph ,
802  const typename base_type::sparse_matrix_type & arg_jacobian ,
803  const typename base_type::vector_type & arg_residual ) :
804  base_type(arg_mesh, arg_solution, arg_elem_graph,
805  arg_jacobian, arg_residual) {}
806 
807  //------------------------------------
808 
809  void apply() const
810  {
811  const size_t nelem = this->elem_node_ids.extent(0);
812  parallel_for( nelem , *this );
813  }
814 
815  KOKKOS_INLINE_FUNCTION
816  void gatherSolution(const unsigned ielem,
817  const elem_vec_type& val,
818  unsigned node_index[],
819  double x[], double y[], double z[],
820  const elem_vec_type& res) const
821  {
822  for ( unsigned i = 0 ; i < ElemNodeCount ; ++i ) {
823  const unsigned ni = this->elem_node_ids( ielem , i );
824 
825  node_index[i] = ni ;
826 
827  x[i] = this->node_coords( ni , 0 );
828  y[i] = this->node_coords( ni , 1 );
829  z[i] = this->node_coords( ni , 2 );
830 
831  val(i).val() = this->solution( ni );
832  val(i).diff( i, FunctionCount );
833  res(i) = 0.0;
834  }
835  }
836 
837  KOKKOS_INLINE_FUNCTION
838  void scatterResidual(const unsigned ielem,
839  const unsigned node_index[],
840  const elem_vec_type& res) const
841  {
842  for( unsigned i = 0 ; i < FunctionCount ; i++ ) {
843  const unsigned row = node_index[i] ;
844  if ( row < this->residual.extent(0) ) {
845  atomic_add( & this->residual( row ) , res(i).val() );
846 
847  for( unsigned j = 0 ; j < FunctionCount ; j++ ) {
848  const unsigned entry = this->elem_graph( ielem , i , j );
849  if ( entry != ~0u ) {
850  atomic_add( & this->jacobian.coeff( entry ) ,
851  res(i).fastAccessDx(j) );
852  }
853  }
854  }
855  }
856  }
857 
858  KOKKOS_INLINE_FUNCTION
859  void computeElementResidual(const elem_vec_type& dof_values ,
860  const double x[],
861  const double y[],
862  const double z[],
863  const elem_vec_type& elem_res ) const
864  {
865  double coeff_k = 3.456;
866  double coeff_src = 1.234;
867  double advection[] = { 1.1, 1.2, 1.3 };
868  double dpsidx[ FunctionCount ] ;
869  double dpsidy[ FunctionCount ] ;
870  double dpsidz[ FunctionCount ] ;
871  for ( unsigned i = 0 ; i < IntegrationCount ; ++i ) {
872 
873  const double integ_weight = this->elem_data.weights[i];
874  const double* bases_vals = this->elem_data.values[i];
875  const double detJ =
876  this->transform_gradients( this->elem_data.gradients[i] ,
877  x , y , z ,
878  dpsidx , dpsidy , dpsidz );
879  const double detJ_weight = detJ * integ_weight;
880  const double detJ_weight_coeff_k = detJ_weight * coeff_k;
881 
882  fad_scalar_type value_at_pt = 0 ;
883  fad_scalar_type gradx_at_pt = 0 ;
884  fad_scalar_type grady_at_pt = 0 ;
885  fad_scalar_type gradz_at_pt = 0 ;
886  for ( unsigned m = 0 ; m < FunctionCount ; m++ ) {
887  value_at_pt += dof_values(m) * bases_vals[m] ;
888  gradx_at_pt += dof_values(m) * dpsidx[m] ;
889  grady_at_pt += dof_values(m) * dpsidy[m] ;
890  gradz_at_pt += dof_values(m) * dpsidz[m] ;
891  }
892 
893  const fad_scalar_type source_term =
894  coeff_src * value_at_pt * value_at_pt ;
895 
896  const fad_scalar_type advection_term =
897  advection[0]*gradx_at_pt +
898  advection[1]*grady_at_pt +
899  advection[2]*gradz_at_pt;
900 
901  for ( unsigned m = 0; m < FunctionCount; ++m) {
902  const double bases_val_m = bases_vals[m] * detJ_weight ;
903  const double dpsidx_m = dpsidx[m] ;
904  const double dpsidy_m = dpsidy[m] ;
905  const double dpsidz_m = dpsidz[m] ;
906 
907  elem_res(m) +=
908  detJ_weight_coeff_k * ( dpsidx_m * gradx_at_pt +
909  dpsidy_m * grady_at_pt +
910  dpsidz_m * gradz_at_pt ) +
911  bases_val_m * ( advection_term + source_term ) ;
912  }
913  }
914  }
915 
916  KOKKOS_INLINE_FUNCTION
917  void operator()( const unsigned ielem ) const
918  {
919  double x[ FunctionCount ] ;
920  double y[ FunctionCount ] ;
921  double z[ FunctionCount ] ;
922  unsigned node_index[ ElemNodeCount ];
923 
924  scalar_type local_val[FunctionCount*(FunctionCount+1)], local_res[FunctionCount*(FunctionCount+1)];
926  elem_vec_type elem_res(local_res, FunctionCount, FunctionCount+1) ;
927 
928  // Gather nodal coordinates and solution vector:
929  gatherSolution( ielem, val, node_index, x, y, z, elem_res );
930 
931  // Compute nodal element residual vector:
932  computeElementResidual( val, x, y, z, elem_res );
933 
934  // Scatter nodal element residual in global vector:
935  scatterResidual( ielem, node_index, elem_res );
936  }
937 }; /* ElementComputation */
938 
939 template< class ExecutionSpace , BoxElemPart::ElemOrder Order ,
940  class CoordinateMap , typename ScalarType >
941 class ElementComputation
942  < Kokkos::Example::BoxElemFixture< ExecutionSpace , Order , CoordinateMap > ,
943  CrsMatrix< ScalarType , ExecutionSpace > ,
945  public ElementComputation< Kokkos::Example::BoxElemFixture< ExecutionSpace , Order , CoordinateMap > ,
946  CrsMatrix< ScalarType , ExecutionSpace > ,
947  FadElement > {
948 public:
949 
950  typedef ElementComputation< Kokkos::Example::BoxElemFixture< ExecutionSpace , Order , CoordinateMap > ,
951  CrsMatrix< ScalarType , ExecutionSpace > ,
953 
956 
957  static const unsigned FunctionCount = base_type::FunctionCount;
958  static const unsigned IntegrationCount = base_type::IntegrationCount;
959  static const unsigned ElemNodeCount = base_type::ElemNodeCount;
960 
961  typedef typename base_type::fad_scalar_type fad_scalar_type;
962 
963  typedef Kokkos::View<scalar_type[FunctionCount],Kokkos::LayoutRight,execution_space,Kokkos::MemoryUnmanaged> scalar_elem_vec_type;
964  typedef typename base_type::elem_vec_type fad_elem_vec_type;
965 
967 
969  const typename base_type::mesh_type & arg_mesh ,
970  const typename base_type::vector_type & arg_solution ,
971  const typename base_type::elem_graph_type & arg_elem_graph ,
972  const typename base_type::sparse_matrix_type & arg_jacobian ,
973  const typename base_type::vector_type & arg_residual ) :
974  base_type(arg_mesh, arg_solution, arg_elem_graph,
975  arg_jacobian, arg_residual) {}
976 
977  //------------------------------------
978 
979  void apply() const
980  {
981  const size_t nelem = this->elem_node_ids.extent(0);
982  parallel_for( nelem , *this );
983  }
984 
985  KOKKOS_INLINE_FUNCTION
986  void gatherSolution(const unsigned ielem,
987  const scalar_elem_vec_type& val,
988  unsigned node_index[],
989  double x[], double y[], double z[],
990  const fad_elem_vec_type& res) const
991  {
992  for ( unsigned i = 0 ; i < ElemNodeCount ; ++i ) {
993  const unsigned ni = this->elem_node_ids( ielem , i );
994 
995  node_index[i] = ni ;
996 
997  x[i] = this->node_coords( ni , 0 );
998  y[i] = this->node_coords( ni , 1 );
999  z[i] = this->node_coords( ni , 2 );
1000 
1001  val(i) = this->solution( ni );
1002  res(i) = 0.0;
1003  }
1004  }
1005 
1006  KOKKOS_INLINE_FUNCTION
1008  const double x[],
1009  const double y[],
1010  const double z[],
1011  const fad_elem_vec_type& elem_res ) const
1012  {
1013  double coeff_k = 3.456;
1014  double coeff_src = 1.234;
1015  double advection[] = { 1.1, 1.2, 1.3 };
1016  double dpsidx[ FunctionCount ] ;
1017  double dpsidy[ FunctionCount ] ;
1018  double dpsidz[ FunctionCount ] ;
1019  for ( unsigned i = 0 ; i < IntegrationCount ; ++i ) {
1020 
1021  const double integ_weight = this->elem_data.weights[i];
1022  const double* bases_vals = this->elem_data.values[i];
1023  const double detJ =
1024  this->transform_gradients( this->elem_data.gradients[i] ,
1025  x , y , z ,
1026  dpsidx , dpsidy , dpsidz );
1027  const double detJ_weight = detJ * integ_weight;
1028  const double detJ_weight_coeff_k = detJ_weight * coeff_k;
1029 
1034  for ( unsigned m = 0 ; m < FunctionCount ; m++ ) {
1035  value_at_pt.val() += dof_values(m) * bases_vals[m] ;
1036  value_at_pt.fastAccessDx(m) = bases_vals[m] ;
1037 
1038  gradx_at_pt.val() += dof_values(m) * dpsidx[m] ;
1039  gradx_at_pt.fastAccessDx(m) = dpsidx[m] ;
1040 
1041  grady_at_pt.val() += dof_values(m) * dpsidy[m] ;
1042  grady_at_pt.fastAccessDx(m) = dpsidy[m] ;
1043 
1044  gradz_at_pt.val() += dof_values(m) * dpsidz[m] ;
1045  gradz_at_pt.fastAccessDx(m) = dpsidz[m] ;
1046  }
1047 
1048  const fad_scalar_type source_term =
1049  coeff_src * value_at_pt * value_at_pt ;
1050 
1051  const fad_scalar_type advection_term =
1052  advection[0]*gradx_at_pt +
1053  advection[1]*grady_at_pt +
1054  advection[2]*gradz_at_pt;
1055 
1056  for ( unsigned m = 0; m < FunctionCount; ++m) {
1057  const double bases_val_m = bases_vals[m] * detJ_weight ;
1058  const double dpsidx_m = dpsidx[m] ;
1059  const double dpsidy_m = dpsidy[m] ;
1060  const double dpsidz_m = dpsidz[m] ;
1061 
1062  elem_res(m) +=
1063  detJ_weight_coeff_k * ( dpsidx_m * gradx_at_pt +
1064  dpsidy_m * grady_at_pt +
1065  dpsidz_m * gradz_at_pt ) +
1066  bases_val_m * ( advection_term + source_term ) ;
1067  }
1068  }
1069  }
1070 
1071  KOKKOS_INLINE_FUNCTION
1072  void operator()( const unsigned ielem ) const
1073  {
1074  double x[ FunctionCount ] ;
1075  double y[ FunctionCount ] ;
1076  double z[ FunctionCount ] ;
1077  unsigned node_index[ ElemNodeCount ];
1078 
1079  scalar_type local_val[FunctionCount], local_res[FunctionCount*(FunctionCount+1)];
1080  scalar_elem_vec_type val(local_val, FunctionCount) ;
1081  fad_elem_vec_type elem_res(local_res, FunctionCount, FunctionCount+1) ;
1082 
1083  // Gather nodal coordinates and solution vector:
1084  gatherSolution( ielem, val, node_index, x, y, z, elem_res );
1085 
1086  // Compute nodal element residual vector:
1087  computeElementResidual( val, x, y, z, elem_res );
1088 
1089  // Scatter nodal element residual in global vector:
1090  this->scatterResidual( ielem, node_index, elem_res );
1091  }
1092 }; /* ElementComputation */
1093 
1094 template< class ExecutionSpace , BoxElemPart::ElemOrder Order ,
1095  class CoordinateMap , typename ScalarType >
1096 class ElementComputation
1097  < Kokkos::Example::BoxElemFixture< ExecutionSpace , Order , CoordinateMap > ,
1098  CrsMatrix< ScalarType , ExecutionSpace > ,
1099  FadQuadPoint > :
1100  public ElementComputation< Kokkos::Example::BoxElemFixture< ExecutionSpace , Order , CoordinateMap > ,
1101  CrsMatrix< ScalarType , ExecutionSpace > ,
1102  Analytic > {
1103 public:
1104 
1105  typedef ElementComputation< Kokkos::Example::BoxElemFixture< ExecutionSpace , Order , CoordinateMap > ,
1106  CrsMatrix< ScalarType , ExecutionSpace > ,
1108 
1111 
1112  static const unsigned FunctionCount = base_type::FunctionCount;
1113  static const unsigned IntegrationCount = base_type::IntegrationCount;
1114  static const unsigned ElemNodeCount = base_type::ElemNodeCount;
1115 
1116  typedef typename base_type::elem_vec_type elem_vec_type;
1117  typedef typename base_type::elem_mat_type elem_mat_type;
1118 
1120 
1122 
1124  const typename base_type::mesh_type & arg_mesh ,
1125  const typename base_type::vector_type & arg_solution ,
1126  const typename base_type::elem_graph_type & arg_elem_graph ,
1127  const typename base_type::sparse_matrix_type & arg_jacobian ,
1128  const typename base_type::vector_type & arg_residual ) :
1129  base_type(arg_mesh, arg_solution, arg_elem_graph,
1130  arg_jacobian, arg_residual) {}
1131 
1132  //------------------------------------
1133 
1134  void apply() const
1135  {
1136  const size_t nelem = this->elem_node_ids.extent(0);
1137  parallel_for( nelem , *this );
1138  }
1139 
1140  KOKKOS_INLINE_FUNCTION
1142  const elem_vec_type& dof_values ,
1143  const double x[],
1144  const double y[],
1145  const double z[],
1146  const elem_vec_type& elem_res ,
1147  const elem_mat_type& elem_mat ) const
1148  {
1149  double coeff_k = 3.456;
1150  double coeff_src = 1.234;
1151  double advection[] = { 1.1, 1.2, 1.3 };
1152  double dpsidx[ FunctionCount ] ;
1153  double dpsidy[ FunctionCount ] ;
1154  double dpsidz[ FunctionCount ] ;
1155 
1156  fad_scalar_type value_at_pt(4, 0, 0.0) ;
1157  fad_scalar_type gradx_at_pt(4, 1, 0.0) ;
1158  fad_scalar_type grady_at_pt(4, 2, 0.0) ;
1159  fad_scalar_type gradz_at_pt(4, 3, 0.0) ;
1160  for ( unsigned i = 0 ; i < IntegrationCount ; ++i ) {
1161 
1162  const double integ_weight = this->elem_data.weights[i];
1163  const double* bases_vals = this->elem_data.values[i];
1164  const double detJ =
1165  this->transform_gradients( this->elem_data.gradients[i] ,
1166  x , y , z ,
1167  dpsidx , dpsidy , dpsidz );
1168  const double detJ_weight = detJ * integ_weight;
1169  const double detJ_weight_coeff_k = detJ_weight * coeff_k;
1170 
1171  value_at_pt.val() = 0.0 ;
1172  gradx_at_pt.val() = 0.0 ;
1173  grady_at_pt.val() = 0.0 ;
1174  gradz_at_pt.val() = 0.0 ;
1175  for ( unsigned m = 0 ; m < FunctionCount ; m++ ) {
1176  value_at_pt.val() += dof_values(m) * bases_vals[m] ;
1177  gradx_at_pt.val() += dof_values(m) * dpsidx[m] ;
1178  grady_at_pt.val() += dof_values(m) * dpsidy[m] ;
1179  gradz_at_pt.val() += dof_values(m) * dpsidz[m] ;
1180  }
1181 
1182  const fad_scalar_type source_term =
1183  coeff_src * value_at_pt * value_at_pt ;
1184 
1185  const fad_scalar_type advection_term =
1186  advection[0]*gradx_at_pt +
1187  advection[1]*grady_at_pt +
1188  advection[2]*gradz_at_pt;
1189 
1190  for ( unsigned m = 0; m < FunctionCount; ++m) {
1191  const double bases_val_m = bases_vals[m] * detJ_weight ;
1192  fad_scalar_type res =
1193  detJ_weight_coeff_k * ( dpsidx[m] * gradx_at_pt +
1194  dpsidy[m] * grady_at_pt +
1195  dpsidz[m] * gradz_at_pt ) +
1196  bases_val_m * ( advection_term + source_term ) ;
1197 
1198  elem_res(m) += res.val();
1199 
1200  for( unsigned n = 0; n < FunctionCount; n++) {
1201  elem_mat(m,n) += res.fastAccessDx(0) * bases_vals[n] +
1202  res.fastAccessDx(1) * dpsidx[n] +
1203  res.fastAccessDx(2) * dpsidy[n] +
1204  res.fastAccessDx(3) * dpsidz[n];
1205  }
1206  }
1207  }
1208  }
1209 
1210  KOKKOS_INLINE_FUNCTION
1211  void operator()( const unsigned ielem ) const
1212  {
1213  double x[ FunctionCount ] ;
1214  double y[ FunctionCount ] ;
1215  double z[ FunctionCount ] ;
1216  unsigned node_index[ ElemNodeCount ];
1217 
1218  scalar_type local_val[FunctionCount], local_res[FunctionCount], local_mat[FunctionCount*FunctionCount];
1219  elem_vec_type val(local_val, FunctionCount) ;
1220  elem_vec_type elem_res(local_res, FunctionCount) ;
1221  elem_mat_type elem_mat(local_mat, FunctionCount, FunctionCount) ;
1222 
1223  // Gather nodal coordinates and solution vector:
1224  this->gatherSolution( ielem, val, node_index, x, y, z, elem_res, elem_mat );
1225 
1226  // Compute nodal element residual vector and Jacobian matrix:
1227  computeElementResidualJacobian( val, x, y, z, elem_res, elem_mat );
1228 
1229  // Scatter nodal element residual and Jacobian in global vector and matrix:
1230  this->scatterResidual( ielem, node_index, elem_res, elem_mat );
1231  }
1232 }; /* ElementComputation */
1233 
1234 } /* namespace FENL */
1235 } /* namespace Example */
1236 } /* namespace Kokkos */
1237 
1238 //----------------------------------------------------------------------------
1239 
1240 #endif /* #ifndef KOKKOS_EXAMPLE_FENLFUNCTORS_HPP */
double weights[integration_count]
Definition: HexElement.hpp:192
ElementComputation(const typename base_type::mesh_type &arg_mesh, const typename base_type::vector_type &arg_solution, const typename base_type::elem_graph_type &arg_elem_graph, const typename base_type::sparse_matrix_type &arg_jacobian, const typename base_type::vector_type &arg_residual)
int * count
KOKKOS_INLINE_FUNCTION void computeElementResidualJacobian(const elem_vec_type &dof_values, const double x[], const double y[], const double z[], const elem_vec_type &elem_res, const elem_mat_type &elem_mat) const
KOKKOS_INLINE_FUNCTION void fill_graph_entries(const unsigned iset) const
Kokkos::View< scalar_type *[FunctionCount], execution_space > elem_vectors_type
static const unsigned element_node_count
Definition: HexElement.hpp:188
CrsMatrix< ScalarType, ExecutionSpace > sparse_matrix_type
KOKKOS_INLINE_FUNCTION void computeElementResidualJacobian(const elem_vec_type &dof_values, const double x[], const double y[], const double z[], const elem_vec_type &elem_res, const elem_mat_type &elem_mat) const
static const unsigned function_count
Definition: HexElement.hpp:190
KOKKOS_INLINE_FUNCTION void join(unsigned &update, const unsigned &input) const
ElementComputation< Kokkos::Example::BoxElemFixture< ExecutionSpace, Order, CoordinateMap >, CrsMatrix< ScalarType, ExecutionSpace >, Analytic > base_type
Kokkos::View< const double *[SpaceDim], Device > node_coord_type
double gradients[integration_count][spatial_dimension][function_count]
Definition: HexElement.hpp:194
Kokkos::View< const unsigned *[ElemNode], Device > elem_node_type
Kokkos::View< scalar_type *, Kokkos::LayoutLeft, execution_space > vector_type
KOKKOS_INLINE_FUNCTION void computeElementResidual(const scalar_elem_vec_type dof_values, const double x[], const double y[], const double z[], const fad_elem_vec_type &elem_res) const
NodeNodeGraph< elem_node_type, sparse_graph_type, ElemNodeCount >::ElemGraphType elem_graph_type
expr val()
ElemNodeIdView::execution_space execution_space
KOKKOS_INLINE_FUNCTION void operator()(const unsigned irow, unsigned &update, const bool final) const
KOKKOS_INLINE_FUNCTION void init(unsigned &update) const
ElementComputationBase(const ElementComputationBase &rhs)
KOKKOS_INLINE_FUNCTION void fill_elem_graph_map(const unsigned ielem) const
Kokkos::Example::HexElement_Data< mesh_type::ElemNode > element_data_type
CrsGraphType::row_map_type::non_const_type RowMapType
ElementComputationBase(const mesh_type &arg_mesh, const vector_type &arg_solution, const elem_graph_type &arg_elem_graph, const sparse_matrix_type &arg_jacobian, const vector_type &arg_residual)
KOKKOS_INLINE_FUNCTION void operator()(const TagFillNodeSet &, unsigned ielem, unsigned &count) const
CrsMatrix(const StaticCrsGraphType &arg_graph)
Kokkos::StaticCrsGraph< unsigned, Space, void, void, unsigned > StaticCrsGraphType
KOKKOS_INLINE_FUNCTION double transform_gradients(const double grad[][FunctionCount], const double x[], const double y[], const double z[], double dpsidx[], double dpsidy[], double dpsidz[]) const
double values[integration_count][function_count]
Definition: HexElement.hpp:193
Do not initialize the derivative array.
KOKKOS_INLINE_FUNCTION void operator()(const unsigned iwork) const
static const unsigned integration_count
Definition: HexElement.hpp:189
Kokkos::Example::BoxElemFixture< ExecutionSpace, Order, CoordinateMap > mesh_type
Kokkos::View< scalar_type[FunctionCount][FunctionCount], Kokkos::LayoutRight, execution_space, Kokkos::MemoryUnmanaged > elem_mat_type
NodeNodeGraph(const ElemNodeIdView &arg_elem_node_id, const unsigned arg_node_count, Times &results)
Uncopyable z
KOKKOS_INLINE_FUNCTION void init(const TagFillNodeSet &, unsigned &update) const
#define Method
KOKKOS_INLINE_FUNCTION void gatherSolution(const unsigned ielem, const scalar_elem_vec_type &val, unsigned node_index[], double x[], double y[], double z[], const fad_elem_vec_type &res) const
View< ValueType *, Space > coeff_type
sparse_matrix_type::StaticCrsGraphType sparse_graph_type
Kokkos::View< unsigned, execution_space > UnsignedValue
ElementComputation(const typename base_type::mesh_type &arg_mesh, const typename base_type::vector_type &arg_solution, const typename base_type::elem_graph_type &arg_elem_graph, const typename base_type::sparse_matrix_type &arg_jacobian, const typename base_type::vector_type &arg_residual)
ElementComputation< Kokkos::Example::BoxElemFixture< ExecutionSpace, Order, CoordinateMap >, CrsMatrix< ScalarType, ExecutionSpace >, FadElement > base_type
ElementComputation(const typename base_type::mesh_type &arg_mesh, const typename base_type::vector_type &arg_solution, const typename base_type::elem_graph_type &arg_elem_graph, const typename base_type::sparse_matrix_type &arg_jacobian, const typename base_type::vector_type &arg_residual)
ElementComputation(const typename base_type::mesh_type &arg_mesh, const typename base_type::vector_type &arg_solution, const typename base_type::elem_graph_type &arg_elem_graph, const typename base_type::sparse_matrix_type &arg_jacobian, const typename base_type::vector_type &arg_residual)
KOKKOS_INLINE_FUNCTION void scatterResidual(const unsigned ielem, const unsigned node_index[], const elem_vec_type &res, const elem_mat_type &mat) const
KOKKOS_INLINE_FUNCTION void join(const TagFillNodeSet &, unsigned &update, const unsigned &input) const
KOKKOS_INLINE_FUNCTION void sort_graph_entries(const unsigned irow) const
Kokkos::View< scalar_type *[FunctionCount][FunctionCount], execution_space > elem_matrices_type
KOKKOS_INLINE_FUNCTION void gatherSolution(const unsigned ielem, const elem_vec_type &val, unsigned node_index[], double x[], double y[], double z[], const elem_vec_type &res) const
Kokkos::View< unsigned *[ElemNode][ElemNode], execution_space > ElemGraphType
int n
Generate a distributed unstructured finite element mesh from a partitioned NX*NY*NZ box of elements...
KOKKOS_INLINE_FUNCTION void computeElementResidual(const elem_vec_type &dof_values, const double x[], const double y[], const double z[], const elem_vec_type &elem_res) const
Kokkos::UnorderedMap< key_type, void, execution_space > SetType
KOKKOS_INLINE_FUNCTION void gatherSolution(const unsigned ielem, const elem_vec_type &val, unsigned node_index[], double x[], double y[], double z[], const elem_vec_type &res, const elem_mat_type &mat) const
const double y
static const unsigned spatial_dimension
Definition: HexElement.hpp:187