GEOSX
KernelBase.hpp
Go to the documentation of this file.
1 /*
2  * ------------------------------------------------------------------------------------------------------------
3  * SPDX-License-Identifier: LGPL-2.1-only
4  *
5  * Copyright (c) 2018-2020 Lawrence Livermore National Security LLC
6  * Copyright (c) 2018-2020 The Board of Trustees of the Leland Stanford Junior University
7  * Copyright (c) 2018-2020 Total, S.A
8  * Copyright (c) 2019- GEOSX Contributors
9  * All rights reserved
10  *
11  * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
12  * ------------------------------------------------------------------------------------------------------------
13  */
14 
15 
20 #ifndef GEOSX_FINITEELEMENT_KERNELBASE_HPP_
21 #define GEOSX_FINITEELEMENT_KERNELBASE_HPP_
22 
23 #include "common/DataTypes.hpp"
24 #include "common/TimingMacros.hpp"
25 #include "constitutive/ConstitutivePassThru.hpp"
26 #include "finiteElement/FiniteElementDispatch.hpp"
28 #include "rajaInterface/GEOS_RAJA_Interface.hpp"
29 
30 
31 
32 #if defined(__APPLE__)
33 #define CONSTRUCTOR_PARAM_OPTION 2
35 #else
36 #define CONSTRUCTOR_PARAM_OPTION 1
38 #endif
39 
40 #if CONSTRUCTOR_PARAM_OPTION==1
41 namespace std
42 {
43 namespace detail
44 {
57 template< class T, class Tuple, std::size_t... I >
58 constexpr T make_from_tuple_impl( Tuple && t, std::index_sequence< I... > )
59 {
60  return T( std::get< I >( std::forward< Tuple >( t ))... );
61 }
62 } // namespace detail
63 
73 template< class T, class Tuple >
74 constexpr T make_from_tuple( Tuple && t )
75 {
76  return detail::make_from_tuple_impl< T >( std::forward< Tuple >( t ),
77  std::make_index_sequence< std::tuple_size< std::remove_reference_t< Tuple > >::value >{} );
78 }
79 
80 }
81 #elif CONSTRUCTOR_PARAM_OPTION==2
82  #include "camp/camp.hpp"
83 #endif
84 
85 namespace geosx
86 {
87 
91 namespace finiteElement
92 {
93 
127 template< typename SUBREGION_TYPE,
128  typename CONSTITUTIVE_TYPE,
129  typename FE_TYPE,
130  int NUM_DOF_PER_TEST_SP,
131  int NUM_DOF_PER_TRIAL_SP >
133 {
134 public:
137  static constexpr int numTestSupportPointsPerElem = FE_TYPE::numNodes;
138 
141  static constexpr int numTrialSupportPointsPerElem = FE_TYPE::numNodes;
142 
145  static constexpr int numDofPerTestSupportPoint = NUM_DOF_PER_TEST_SP;
146 
149  static constexpr int numDofPerTrialSupportPoint = NUM_DOF_PER_TRIAL_SP;
150 
152  static constexpr int numQuadraturePointsPerElem = FE_TYPE::numQuadraturePoints;
153 
162  KernelBase( SUBREGION_TYPE const & elementSubRegion,
163  FE_TYPE const & finiteElementSpace,
164  CONSTITUTIVE_TYPE * const inputConstitutiveType ):
165  m_elemsToNodes( elementSubRegion.nodeList().toViewConst() ),
166  m_elemGhostRank( elementSubRegion.ghostRank() ),
167  m_constitutiveUpdate( inputConstitutiveType->createKernelUpdates() ),
168  m_finiteElementSpace( finiteElementSpace )
169  {}
170 
183  {};
184 
200  void setup( localIndex const k,
201  StackVariables & stack ) const
202  {
203  GEOSX_UNUSED_VAR( k );
204  GEOSX_UNUSED_VAR( stack );
205  }
206 
226  localIndex const q,
227  StackVariables & stack ) const
228  {
229  GEOSX_UNUSED_VAR( k );
230  GEOSX_UNUSED_VAR( q );
231  GEOSX_UNUSED_VAR( stack );
232  }
233 
251  StackVariables & stack ) const
252  {
253  GEOSX_UNUSED_VAR( k );
254  GEOSX_UNUSED_VAR( stack );
255  return 0;
256  }
257 
258 
271  //START_kernelLauncher
272  template< typename POLICY,
273  typename KERNEL_TYPE >
274  static
275  real64
276  kernelLaunch( localIndex const numElems,
277  KERNEL_TYPE const & kernelComponent )
278  {
279  GEOSX_MARK_FUNCTION;
280 
281  // Define a RAJA reduction variable to get the maximum residual contribution.
282  RAJA::ReduceMax< ReducePolicy< POLICY >, real64 > maxResidual( 0 );
283 
284  forAll< POLICY >( numElems,
285  [=] GEOSX_HOST_DEVICE ( localIndex const k )
286  {
287  typename KERNEL_TYPE::StackVariables stack;
288 
289  kernelComponent.setup( k, stack );
290  for( integer q=0; q<numQuadraturePointsPerElem; ++q )
291  {
292  kernelComponent.quadraturePointKernel( k, q, stack );
293  }
294  maxResidual.max( kernelComponent.complete( k, stack ) );
295  } );
296  return maxResidual.get();
297  }
298  //END_kernelLauncher
299 
300 protected:
302  traits::ViewTypeConst< typename SUBREGION_TYPE::NodeMapType::base_type > const m_elemsToNodes;
303 
306 
309  typename CONSTITUTIVE_TYPE::KernelWrapper const m_constitutiveUpdate;
310 
313  FE_TYPE const & m_finiteElementSpace;
314 };
315 
316 
317 //*****************************************************************************
318 //*****************************************************************************
319 //*****************************************************************************
320 
321 //START_regionBasedKernelApplication
360 template< typename POLICY,
361  typename CONSTITUTIVE_BASE,
362  typename REGION_TYPE,
363  template< typename SUBREGION_TYPE,
364  typename CONSTITUTIVE_TYPE,
365  typename FE_TYPE > class KERNEL_TEMPLATE,
366  typename ... KERNEL_CONSTRUCTOR_PARAMS >
367 static
369  arrayView1d< string const > const & targetRegions,
370  string const & finiteElementName,
371  arrayView1d< string const > const & constitutiveNames,
372  KERNEL_CONSTRUCTOR_PARAMS && ... kernelConstructorParams )
373 {
374  GEOSX_MARK_FUNCTION;
375  // save the maximum residual contribution for scaling residuals for convergence criteria.
376  real64 maxResidualContribution = 0;
377 
378  NodeManager & nodeManager = *(mesh.getNodeManager());
379  EdgeManager & edgeManager = *(mesh.getEdgeManager());
380  FaceManager & faceManager = *(mesh.getFaceManager());
381  ElementRegionManager & elementRegionManager = *(mesh.getElemManager());
382 
383 
384  // Create a tuple that contains the kernelConstructorParams, as the lambda does not properly catch the parameter pack
385  // until c++20
386 #if CONSTRUCTOR_PARAM_OPTION==1
387  std::tuple< KERNEL_CONSTRUCTOR_PARAMS &... > kernelConstructorParamsTuple = std::forward_as_tuple( kernelConstructorParams ... );
388 #elif CONSTRUCTOR_PARAM_OPTION==2
389  camp::tuple< KERNEL_CONSTRUCTOR_PARAMS &... > kernelConstructorParamsTuple = camp::forward_as_tuple( kernelConstructorParams ... );
390 #endif
391 
392 
393  // Loop over all sub-regions in regiongs of type REGION_TYPE, that are listed in the targetRegions array.
394  elementRegionManager.forElementSubRegions< REGION_TYPE >( targetRegions,
395  [&constitutiveNames,
396  &maxResidualContribution,
397  &nodeManager,
398  &edgeManager,
399  &faceManager,
400  &kernelConstructorParamsTuple,
401  &finiteElementName]
402  ( localIndex const targetRegionIndex, auto & elementSubRegion )
403  {
404  localIndex const numElems = elementSubRegion.size();
405 
406  // Create an alias for the type of subregion we are in, which is now known at compile time.
407  typedef TYPEOFREF( elementSubRegion ) SUBREGIONTYPE;
408 
409  // Get the constitutive model...and allocate a null constitutive model if required.
410  constitutive::ConstitutiveBase * constitutiveRelation = nullptr;
411  constitutive::NullModel * nullConstitutiveModel = nullptr;
412  if( targetRegionIndex <= constitutiveNames.size()-1 )
413  {
414  constitutiveRelation = elementSubRegion.template getConstitutiveModel( constitutiveNames[targetRegionIndex] );
415  }
416  else
417  {
418  nullConstitutiveModel = elementSubRegion.template RegisterGroup< constitutive::NullModel >( "nullModelGroup" );
419  constitutiveRelation = nullConstitutiveModel;
420  }
421 
422  // Call the constitutive dispatch which converts the type of constitutive model into a compile time constant.
423  constitutive::ConstitutivePassThru< CONSTITUTIVE_BASE >::Execute( constitutiveRelation,
424  [&maxResidualContribution,
425  &nodeManager,
426  &edgeManager,
427  &faceManager,
428  &kernelConstructorParamsTuple,
429  &elementSubRegion,
430  &finiteElementName,
431  numElems]
432  ( auto * const castedConstitutiveRelation )
433  {
434  // Create an alias for the type of constitutive model.
435  using CONSTITUTIVE_TYPE = TYPEOFPTR( castedConstitutiveRelation );
436 
437 
438  string const elementTypeString = elementSubRegion.GetElementTypeString();
439 
440  FiniteElementBase &
441  subRegionFE = elementSubRegion.template getReference< FiniteElementBase >( finiteElementName );
442 
443  finiteElement::dispatch3D( subRegionFE,
444  [&maxResidualContribution,
445  &nodeManager,
446  &edgeManager,
447  &faceManager,
448  &kernelConstructorParamsTuple,
449  &elementSubRegion,
450  &numElems,
451  &castedConstitutiveRelation] ( auto const finiteElement )
452  {
453  using FE_TYPE = TYPEOFREF( finiteElement );
454 
455  // Define an alias for the kernel type for easy use.
456  using KERNEL_TYPE = KERNEL_TEMPLATE< SUBREGIONTYPE,
457  CONSTITUTIVE_TYPE,
458  FE_TYPE >;
459 
460  // 1) Combine the tuple containing the physics kernel specific constructor parameters with
461  // the parameters common to all phsyics kernels that use this interface,
462  // 2) Instantiate the kernel.
463  // note: have two options, using std::tuple and camp::tuple. Due to a bug in the OSX
464  // implementation of std::tuple_cat, we must use camp on OSX. In the future, we should
465  // only use one option...most likely camp since we can easily fix bugs.
466 #if CONSTRUCTOR_PARAM_OPTION==1
467  auto temp = std::forward_as_tuple( nodeManager,
468  edgeManager,
469  faceManager,
470  elementSubRegion,
472  castedConstitutiveRelation );
473 
474  auto fullKernelComponentConstructorArgs = std::tuple_cat( temp,
475  kernelConstructorParamsTuple );
476 
477  KERNEL_TYPE kernelComponent = std::make_from_tuple< KERNEL_TYPE >( fullKernelComponentConstructorArgs );
478 
479 #elif CONSTRUCTOR_PARAM_OPTION==2
480  auto temp = camp::forward_as_tuple( nodeManager,
481  edgeManager,
482  faceManager,
483  elementSubRegion,
485  castedConstitutiveRelation );
486  auto fullKernelComponentConstructorArgs = camp::tuple_cat_pair( temp,
487  kernelConstructorParamsTuple );
488  KERNEL_TYPE kernelComponent = camp::make_from_tuple< KERNEL_TYPE >( fullKernelComponentConstructorArgs );
489 
490 #endif
491 
492  // Call the kernelLaunch function, and store the maximum contribution to the residual.
493  maxResidualContribution =
494  std::max( maxResidualContribution,
495  KERNEL_TYPE::template kernelLaunch< POLICY,
496  KERNEL_TYPE >( numElems,
497  kernelComponent ) );
498  } );
499  } );
500 
501  // Remove the null constitutive model (not required, but cleaner)
502  if( nullConstitutiveModel )
503  {
504  elementSubRegion.deregisterGroup( "nullModelGroup" );
505  }
506 
507  } );
508 
509  return maxResidualContribution;
510 }
511 //END_regionBasedKernelApplication
512 
513 } // namespace finiteElement
514 } // namespace geosx
515 
516 
517 
518 #endif /* GEOSX_FINITEELEMENT_KERNELBASE_HPP_ */
#define GEOSX_HOST_DEVICE
Marks a host-device function.
Definition: GeosxMacros.hpp:48
CONSTITUTIVE_TYPE::KernelWrapper const m_constitutiveUpdate
Definition: KernelBase.hpp:309
Kernel variables allocated on the stack.
Definition: KernelBase.hpp:182
constexpr T make_from_tuple(Tuple &&t)
Implementation of std::make_from_tuple()
Definition: KernelBase.hpp:74
#define TYPEOFREF(X)
Given an expression X that evaluates to a reference, expands to the type referred to...
Definition: Macros.hpp:72
Class facilitating the representation of a multi-level discretization of a MeshBody.
Definition: MeshLevel.hpp:38
The NodeManager class provides an interface to ObjectManagerBase in order to manage node data...
Definition: NodeManager.hpp:47
arrayView1d< integer const > const m_elemGhostRank
The element ghost rank array.
Definition: KernelBase.hpp:305
GEOSX_HOST_DEVICE GEOSX_FORCE_INLINE void setup(localIndex const k, StackVariables &stack) const
Performs the setup phase for the kernel.
Definition: KernelBase.hpp:200
traits::ViewTypeConst< typename SUBREGION_TYPE::NodeMapType::base_type > const m_elemsToNodes
The element to nodes map.
Definition: KernelBase.hpp:302
This class serves to provide a "view" of a multidimensional array.
Definition: ArrayView.hpp:67
double real64
64-bit floating point type.
Definition: DataTypes.hpp:136
GEOSX_HOST_DEVICE GEOSX_FORCE_INLINE void quadraturePointKernel(localIndex const k, localIndex const q, StackVariables &stack) const
Performs a state update at a quadrature point.
Definition: KernelBase.hpp:225
Define the base interface for finite element kernels.
Definition: KernelBase.hpp:132
static real64 kernelLaunch(localIndex const numElems, KERNEL_TYPE const &kernelComponent)
Kernel Launcher.
Definition: KernelBase.hpp:276
FE_TYPE const & m_finiteElementSpace
Definition: KernelBase.hpp:313
std::int32_t integer
Signed integer type.
Definition: DataTypes.hpp:122
This class provides an interface to ObjectManagerBase in order to manage edge data.
Definition: EdgeManager.hpp:42
#define TYPEOFPTR(X)
Given an expression X that evaluates to a pointer, expands to the type pointed to.
Definition: Macros.hpp:66
#define GEOSX_FORCE_INLINE
Marks a function or lambda for inlining.
Definition: GeosxMacros.hpp:50
#define GEOSX_UNUSED_VAR(...)
Mark an unused variable and silence compiler warnings.
Definition: GeosxMacros.hpp:78
std::ptrdiff_t localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:125
The ElementRegionManager class provides an interface to ObjectManagerBase in order to manage ElementR...
The FaceManager class provides an interface to ObjectManagerBase in order to manage face data...
Definition: FaceManager.hpp:40
static real64 regionBasedKernelApplication(MeshLevel &mesh, arrayView1d< string const > const &targetRegions, string const &finiteElementName, arrayView1d< string const > const &constitutiveNames, KERNEL_CONSTRUCTOR_PARAMS &&... kernelConstructorParams)
Performs a loop over specific regions (by type and name) and calls a kernel launch on the subregions ...
Definition: KernelBase.hpp:368
KernelBase(SUBREGION_TYPE const &elementSubRegion, FE_TYPE const &finiteElementSpace, CONSTITUTIVE_TYPE *const inputConstitutiveType)
Constructor.
Definition: KernelBase.hpp:162
std::size_t size_t
Unsigned size type.
Definition: DataTypes.hpp:119
void forElementSubRegions(LAMBDA &&lambda)
This function is used to launch kernel function over the element subregions of all the subregion type...
constexpr std::enable_if_t< std::is_arithmetic< T >::value, T > max(T const a, T const b)
Definition: math.hpp:46
GEOSX_HOST_DEVICE GEOSX_FORCE_INLINE real64 complete(localIndex const k, StackVariables &stack) const
Performs the complete phase for the kernel.
Definition: KernelBase.hpp:250