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 TotalEnergies
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 GEOS_FINITEELEMENT_KERNELBASE_HPP_
21 #define GEOS_FINITEELEMENT_KERNELBASE_HPP_
22 
23 #include "common/DataTypes.hpp"
24 #include "common/TimingMacros.hpp"
25 #include "constitutive/ConstitutivePassThru.hpp"
26 #include "finiteElement/FiniteElementDispatch.hpp"
27 #include "mesh/MeshLevel.hpp"
28 #include "common/GEOS_RAJA_Interface.hpp"
29 
34 #ifndef SELECTED_FE_TYPES
35 #define SELECTED_FE_TYPES BASE_FE_TYPES
36 #endif
37 
38 namespace geos
39 {
40 
44 namespace finiteElement
45 {
46 
80 template< typename SUBREGION_TYPE,
81  typename CONSTITUTIVE_TYPE,
82  typename FE_TYPE,
83  int NUM_DOF_PER_TEST_SP,
84  int NUM_DOF_PER_TRIAL_SP >
86 {
87 public:
90  static constexpr int maxNumTestSupportPointsPerElem = FE_TYPE::maxSupportPoints;
91 
94  static constexpr int maxNumTrialSupportPointsPerElem = FE_TYPE::maxSupportPoints;
95 
98  static constexpr int numDofPerTestSupportPoint = NUM_DOF_PER_TEST_SP;
99 
102  static constexpr int numDofPerTrialSupportPoint = NUM_DOF_PER_TRIAL_SP;
103 
105  static constexpr int numQuadraturePointsPerElem = FE_TYPE::numQuadraturePoints;
106 
115  KernelBase( SUBREGION_TYPE const & elementSubRegion,
116  FE_TYPE const & finiteElementSpace,
117  CONSTITUTIVE_TYPE & inputConstitutiveType ):
118  m_elemsToNodes( elementSubRegion.nodeList().toViewConst() ),
119  m_elemGhostRank( elementSubRegion.ghostRank() ),
120  m_constitutiveUpdate( inputConstitutiveType.createKernelUpdates() ),
121  m_finiteElementSpace( finiteElementSpace )
122  {}
123 
136  {};
137 
152  inline
153  void setup( localIndex const k,
154  StackVariables & stack ) const
155  {
156  GEOS_UNUSED_VAR( k );
157  GEOS_UNUSED_VAR( stack );
158  }
159 
179  localIndex const q,
180  StackVariables & stack ) const
181  {
182  GEOS_UNUSED_VAR( k );
183  GEOS_UNUSED_VAR( q );
184  GEOS_UNUSED_VAR( stack );
185  }
186 
202  inline
204  StackVariables & stack ) const
205  {
206  GEOS_UNUSED_VAR( k );
207  GEOS_UNUSED_VAR( stack );
208  return 0;
209  }
210 
211 
224  //START_kernelLauncher
225  template< typename POLICY,
226  typename KERNEL_TYPE >
227  static
228  real64
229  kernelLaunch( localIndex const numElems,
230  KERNEL_TYPE const & kernelComponent )
231  {
233 
234  // Define a RAJA reduction variable to get the maximum residual contribution.
235  RAJA::ReduceMax< ReducePolicy< POLICY >, real64 > maxResidual( 0 );
236 
237  forAll< POLICY >( numElems,
238  [=] GEOS_HOST_DEVICE ( localIndex const k )
239  {
240  typename KERNEL_TYPE::StackVariables stack;
241 
242  kernelComponent.setup( k, stack );
243  // #pragma unroll
244  for( integer q=0; q<numQuadraturePointsPerElem; ++q )
245  {
246  kernelComponent.quadraturePointKernel( k, q, stack );
247  }
248  maxResidual.max( kernelComponent.complete( k, stack ) );
249  } );
250  return maxResidual.get();
251  }
252  //END_kernelLauncher
253 
254 protected:
256  traits::ViewTypeConst< typename SUBREGION_TYPE::NodeMapType::base_type > const m_elemsToNodes;
257 
260 
263  typename CONSTITUTIVE_TYPE::KernelWrapper const m_constitutiveUpdate;
264 
267  FE_TYPE const & m_finiteElementSpace;
268 };
269 
276 template< template< typename SUBREGION_TYPE,
277  typename CONSTITUTIVE_TYPE,
278  typename FE_TYPE > class KERNEL_TYPE,
279  typename ... ARGS >
281 {
282 public:
283 
288  KernelFactory( ARGS ... args ):
289  m_args( args ... )
290  {}
291 
306  template< typename SUBREGION_TYPE, typename CONSTITUTIVE_TYPE, typename FE_TYPE >
307  KERNEL_TYPE< SUBREGION_TYPE, CONSTITUTIVE_TYPE, FE_TYPE > createKernel(
308  NodeManager & nodeManager,
309  EdgeManager const & edgeManager,
310  FaceManager const & faceManager,
311  localIndex const targetRegionIndex,
312  SUBREGION_TYPE const & elementSubRegion,
313  FE_TYPE const & finiteElementSpace,
314  CONSTITUTIVE_TYPE & inputConstitutiveType )
315  {
316  camp::tuple< NodeManager &,
317  EdgeManager const &,
318  FaceManager const &,
319  localIndex const,
320  SUBREGION_TYPE const &,
321  FE_TYPE const &,
322  CONSTITUTIVE_TYPE & > standardArgs { nodeManager,
323  edgeManager,
324  faceManager,
325  targetRegionIndex,
326  elementSubRegion,
327  finiteElementSpace,
328  inputConstitutiveType };
329 
330  auto allArgs = camp::tuple_cat_pair( standardArgs, m_args );
331  return camp::make_from_tuple< KERNEL_TYPE< SUBREGION_TYPE, CONSTITUTIVE_TYPE, FE_TYPE > >( allArgs );
332  }
333 
334 private:
336  camp::tuple< ARGS ... > m_args;
337 };
338 
339 
340 //*****************************************************************************
341 //*****************************************************************************
342 //*****************************************************************************
343 
344 //START_regionBasedKernelApplication
366 template< typename POLICY,
367  typename CONSTITUTIVE_BASE,
368  typename SUBREGION_TYPE,
369  typename KERNEL_FACTORY >
370 static
372  arrayView1d< string const > const & targetRegions,
373  string const & finiteElementName,
374  string const & constitutiveStringName,
375  KERNEL_FACTORY & kernelFactory )
376 {
378  // save the maximum residual contribution for scaling residuals for convergence criteria.
379  real64 maxResidualContribution = 0;
380 
381  NodeManager & nodeManager = mesh.getNodeManager();
382  EdgeManager & edgeManager = mesh.getEdgeManager();
383  FaceManager & faceManager = mesh.getFaceManager();
384  ElementRegionManager & elementRegionManager = mesh.getElemManager();
385 
386  // Loop over all sub-regions in regions of type SUBREGION_TYPE, that are listed in the targetRegions array.
387  elementRegionManager.forElementSubRegions< SUBREGION_TYPE >( targetRegions,
388  [&constitutiveStringName,
389  &maxResidualContribution,
390  &nodeManager,
391  &edgeManager,
392  &faceManager,
393  &kernelFactory,
394  &finiteElementName]
395  ( localIndex const targetRegionIndex, auto & elementSubRegion )
396  {
397  localIndex const numElems = elementSubRegion.size();
398 
399  // Get the constitutive model...and allocate a null constitutive model if required.
400 
401  constitutive::ConstitutiveBase * constitutiveRelation = nullptr;
402  constitutive::NullModel * nullConstitutiveModel = nullptr;
403  if( elementSubRegion.template hasWrapper< string >( constitutiveStringName ) )
404  {
405  string const & constitutiveName = elementSubRegion.template getReference< string >( constitutiveStringName );
406  constitutiveRelation = &elementSubRegion.template getConstitutiveModel( constitutiveName );
407  }
408  else
409  {
410  nullConstitutiveModel = &elementSubRegion.template registerGroup< constitutive::NullModel >( "nullModelGroup" );
411  constitutiveRelation = nullConstitutiveModel;
412  }
413 
414  // Call the constitutive dispatch which converts the type of constitutive model into a compile time constant.
415  constitutive::ConstitutivePassThru< CONSTITUTIVE_BASE >::execute( *constitutiveRelation,
416  [&maxResidualContribution,
417  &nodeManager,
418  &edgeManager,
419  &faceManager,
420  targetRegionIndex,
421  &kernelFactory,
422  &elementSubRegion,
423  &finiteElementName,
424  numElems]
425  ( auto & castedConstitutiveRelation )
426  {
427  FiniteElementBase &
428  subRegionFE = elementSubRegion.template getReference< FiniteElementBase >( finiteElementName );
429 
430  finiteElement::FiniteElementDispatchHandler< SELECTED_FE_TYPES >::dispatch3D( subRegionFE,
431  [&maxResidualContribution,
432  &nodeManager,
433  &edgeManager,
434  &faceManager,
435  targetRegionIndex,
436  &kernelFactory,
437  &elementSubRegion,
438  numElems,
439  &castedConstitutiveRelation] ( auto const finiteElement )
440  {
441  auto kernel = kernelFactory.createKernel( nodeManager,
442  edgeManager,
443  faceManager,
444  targetRegionIndex,
445  elementSubRegion,
447  castedConstitutiveRelation );
448 
449  using KERNEL_TYPE = decltype( kernel );
450 
451  // Call the kernelLaunch function, and store the maximum contribution to the residual.
452  maxResidualContribution =
453  std::max( maxResidualContribution,
454  KERNEL_TYPE::template kernelLaunch< POLICY, KERNEL_TYPE >( numElems, kernel ) );
455  } );
456  } );
457 
458  // Remove the null constitutive model (not required, but cleaner)
459  if( nullConstitutiveModel )
460  {
461  elementSubRegion.deregisterGroup( "nullModelGroup" );
462  }
463 
464  } );
465 
466  return maxResidualContribution;
467 }
468 //END_regionBasedKernelApplication
469 
470 } // namespace finiteElement
471 } // namespace geos
472 
473 
474 
475 #endif /* GEOS_FINITEELEMENT_KERNELBASE_HPP_ */
#define GEOS_HOST_DEVICE
Marks a host-device function.
Definition: GeosxMacros.hpp:48
#define GEOS_UNUSED_VAR(...)
Mark an unused variable and silence compiler warnings.
Definition: GeosxMacros.hpp:83
#define GEOS_FORCE_INLINE
Marks a function or lambda for inlining.
Definition: GeosxMacros.hpp:50
static real64 regionBasedKernelApplication(MeshLevel &mesh, arrayView1d< string const > const &targetRegions, string const &finiteElementName, string const &constitutiveStringName, KERNEL_FACTORY &kernelFactory)
Performs a loop over specific regions (by type and name) and calls a kernel launch on the subregions ...
Definition: KernelBase.hpp:371
#define GEOS_MARK_FUNCTION
Mark function with both Caliper and NVTX if enabled.
This class provides an interface to ObjectManagerBase in order to manage edge data.
Definition: EdgeManager.hpp:42
The ElementRegionManager class provides an interface to ObjectManagerBase in order to manage ElementR...
void forElementSubRegions(LAMBDA &&lambda)
This function is used to launch kernel function over the element subregions of all the subregion type...
The FaceManager class provides an interface to ObjectManagerBase in order to manage face data.
Definition: FaceManager.hpp:43
Class facilitating the representation of a multi-level discretization of a MeshBody.
Definition: MeshLevel.hpp:41
NodeManager const & getNodeManager() const
Get the node manager.
Definition: MeshLevel.hpp:154
FaceManager const & getFaceManager() const
Get the face manager.
Definition: MeshLevel.hpp:193
ElementRegionManager const & getElemManager() const
Get the element region manager.
Definition: MeshLevel.hpp:206
EdgeManager const & getEdgeManager() const
Get the edge manager.
Definition: MeshLevel.hpp:180
The NodeManager class provides an interface to ObjectManagerBase in order to manage node data.
Definition: NodeManager.hpp:45
Define the base interface for finite element kernels.
Definition: KernelBase.hpp:86
traits::ViewTypeConst< typename SUBREGION_TYPE::NodeMapType::base_type > const m_elemsToNodes
The element to nodes map.
Definition: KernelBase.hpp:256
GEOS_HOST_DEVICE void setup(localIndex const k, StackVariables &stack) const
Performs the setup phase for the kernel.
Definition: KernelBase.hpp:153
static constexpr int numQuadraturePointsPerElem
Compile time value for the number of quadrature points per element.
Definition: KernelBase.hpp:105
static constexpr int numDofPerTestSupportPoint
Definition: KernelBase.hpp:98
static constexpr int numDofPerTrialSupportPoint
Definition: KernelBase.hpp:102
GEOS_HOST_DEVICE GEOS_FORCE_INLINE void quadraturePointKernel(localIndex const k, localIndex const q, StackVariables &stack) const
Performs a state update at a quadrature point.
Definition: KernelBase.hpp:178
static real64 kernelLaunch(localIndex const numElems, KERNEL_TYPE const &kernelComponent)
Kernel Launcher.
Definition: KernelBase.hpp:229
GEOS_HOST_DEVICE real64 complete(localIndex const k, StackVariables &stack) const
Performs the complete phase for the kernel.
Definition: KernelBase.hpp:203
static constexpr int maxNumTrialSupportPointsPerElem
Definition: KernelBase.hpp:94
arrayView1d< integer const > const m_elemGhostRank
The element ghost rank array.
Definition: KernelBase.hpp:259
CONSTITUTIVE_TYPE::KernelWrapper const m_constitutiveUpdate
Definition: KernelBase.hpp:263
FE_TYPE const & m_finiteElementSpace
Definition: KernelBase.hpp:267
KernelBase(SUBREGION_TYPE const &elementSubRegion, FE_TYPE const &finiteElementSpace, CONSTITUTIVE_TYPE &inputConstitutiveType)
Constructor.
Definition: KernelBase.hpp:115
static constexpr int maxNumTestSupportPointsPerElem
Definition: KernelBase.hpp:90
Used to forward arguments to a class that implements the KernelBase interface.
Definition: KernelBase.hpp:281
KERNEL_TYPE< SUBREGION_TYPE, CONSTITUTIVE_TYPE, FE_TYPE > createKernel(NodeManager &nodeManager, EdgeManager const &edgeManager, FaceManager const &faceManager, localIndex const targetRegionIndex, SUBREGION_TYPE const &elementSubRegion, FE_TYPE const &finiteElementSpace, CONSTITUTIVE_TYPE &inputConstitutiveType)
Create a new kernel with the given standard arguments.
Definition: KernelBase.hpp:307
KernelFactory(ARGS ... args)
Initialize the factory.
Definition: KernelBase.hpp:288
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Definition: DataTypes.hpp:220
double real64
64-bit floating point type.
Definition: DataTypes.hpp:139
std::int32_t integer
Signed integer type.
Definition: DataTypes.hpp:122
GEOSX_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:125
Kernel variables allocated on the stack.
Definition: KernelBase.hpp:136