GEOS
KernelBase.hpp
Go to the documentation of this file.
1 /*
2  * ------------------------------------------------------------------------------------------------------------
3  * SPDX-License-Identifier: LGPL-2.1-only
4  *
5  * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC
6  * Copyright (c) 2018-2024 Total, S.A
7  * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University
8  * Copyright (c) 2023-2024 Chevron
9  * Copyright (c) 2019- GEOS/GEOSX Contributors
10  * All rights reserved
11  *
12  * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
13  * ------------------------------------------------------------------------------------------------------------
14  */
15 
16 
21 #ifndef GEOS_FINITEELEMENT_KERNELBASE_HPP_
22 #define GEOS_FINITEELEMENT_KERNELBASE_HPP_
23 
24 #include "common/DataTypes.hpp"
25 #include "common/TimingMacros.hpp"
26 #include "constitutive/ConstitutivePassThru.hpp"
27 #include "finiteElement/FiniteElementDispatch.hpp"
28 #include "mesh/MeshLevel.hpp"
29 #include "common/GEOS_RAJA_Interface.hpp"
30 
35 #ifndef SELECTED_FE_TYPES
36 #define SELECTED_FE_TYPES BASE_FE_TYPES
37 #endif
38 
39 namespace geos
40 {
41 
45 namespace finiteElement
46 {
47 
81 template< typename SUBREGION_TYPE,
82  typename CONSTITUTIVE_TYPE,
83  typename FE_TYPE,
84  int NUM_DOF_PER_TEST_SP,
85  int NUM_DOF_PER_TRIAL_SP >
87 {
88 public:
91  static constexpr int maxNumTestSupportPointsPerElem = FE_TYPE::maxSupportPoints;
92 
95  static constexpr int maxNumTrialSupportPointsPerElem = FE_TYPE::maxSupportPoints;
96 
99  static constexpr int numDofPerTestSupportPoint = NUM_DOF_PER_TEST_SP;
100 
103  static constexpr int numDofPerTrialSupportPoint = NUM_DOF_PER_TRIAL_SP;
104 
106  static constexpr int numQuadraturePointsPerElem = FE_TYPE::numQuadraturePoints;
107 
116  KernelBase( SUBREGION_TYPE const & elementSubRegion,
117  FE_TYPE const & finiteElementSpace,
118  CONSTITUTIVE_TYPE & inputConstitutiveType ):
119  m_elemsToNodes( elementSubRegion.nodeList().toViewConst() ),
120  m_elemGhostRank( elementSubRegion.ghostRank() ),
121  m_constitutiveUpdate( inputConstitutiveType.createKernelUpdates() ),
122  m_finiteElementSpace( finiteElementSpace )
123  {}
124 
137  {};
138 
153  inline
154  void setup( localIndex const k,
155  StackVariables & stack ) const
156  {
157  GEOS_UNUSED_VAR( k );
158  GEOS_UNUSED_VAR( stack );
159  }
160 
180  localIndex const q,
181  StackVariables & stack ) const
182  {
183  GEOS_UNUSED_VAR( k );
184  GEOS_UNUSED_VAR( q );
185  GEOS_UNUSED_VAR( stack );
186  }
187 
203  inline
205  StackVariables & stack ) const
206  {
207  GEOS_UNUSED_VAR( k );
208  GEOS_UNUSED_VAR( stack );
209  return 0;
210  }
211 
212 
225  //START_kernelLauncher
226  template< typename POLICY,
227  typename KERNEL_TYPE >
228  static
229  real64
230  kernelLaunch( localIndex const numElems,
231  KERNEL_TYPE const & kernelComponent )
232  {
234 
235  // Define a RAJA reduction variable to get the maximum residual contribution.
236  RAJA::ReduceMax< ReducePolicy< POLICY >, real64 > maxResidual( 0 );
237 
238  forAll< POLICY >( numElems,
239  [=] GEOS_HOST_DEVICE ( localIndex const k )
240  {
241  typename KERNEL_TYPE::StackVariables stack;
242 
243  kernelComponent.setup( k, stack );
244  // #pragma unroll
245  for( integer q=0; q<numQuadraturePointsPerElem; ++q )
246  {
247  kernelComponent.quadraturePointKernel( k, q, stack );
248  }
249  maxResidual.max( kernelComponent.complete( k, stack ) );
250  } );
251  return maxResidual.get();
252  }
253  //END_kernelLauncher
254 
255 protected:
257  traits::ViewTypeConst< typename SUBREGION_TYPE::NodeMapType::base_type > const m_elemsToNodes;
258 
261 
264  typename CONSTITUTIVE_TYPE::KernelWrapper const m_constitutiveUpdate;
265 
268  FE_TYPE const m_finiteElementSpace;
269 };
270 
277 template< template< typename SUBREGION_TYPE,
278  typename CONSTITUTIVE_TYPE,
279  typename FE_TYPE > class KERNEL_TYPE,
280  typename ... ARGS >
282 {
283 public:
284 
289  KernelFactory( ARGS ... args ):
290  m_args( args ... )
291  {}
292 
307  template< typename SUBREGION_TYPE, typename CONSTITUTIVE_TYPE, typename FE_TYPE >
308  KERNEL_TYPE< SUBREGION_TYPE, CONSTITUTIVE_TYPE, FE_TYPE > createKernel(
309  NodeManager & nodeManager,
310  EdgeManager const & edgeManager,
311  FaceManager const & faceManager,
312  localIndex const targetRegionIndex,
313  SUBREGION_TYPE const & elementSubRegion,
314  FE_TYPE const & finiteElementSpace,
315  CONSTITUTIVE_TYPE & inputConstitutiveType )
316  {
317  camp::tuple< NodeManager &,
318  EdgeManager const &,
319  FaceManager const &,
320  localIndex const,
321  SUBREGION_TYPE const &,
322  FE_TYPE const &,
323  CONSTITUTIVE_TYPE & > standardArgs { nodeManager,
324  edgeManager,
325  faceManager,
326  targetRegionIndex,
327  elementSubRegion,
328  finiteElementSpace,
329  inputConstitutiveType };
330 
331  auto allArgs = camp::tuple_cat_pair( standardArgs, m_args );
332  return camp::make_from_tuple< KERNEL_TYPE< SUBREGION_TYPE, CONSTITUTIVE_TYPE, FE_TYPE > >( allArgs );
333  }
334 
335 private:
337  camp::tuple< ARGS ... > m_args;
338 };
339 
340 
341 //*****************************************************************************
342 //*****************************************************************************
343 //*****************************************************************************
344 
345 //START_regionBasedKernelApplication
367 template< typename POLICY,
368  typename CONSTITUTIVE_BASE,
369  typename SUBREGION_TYPE,
370  typename KERNEL_FACTORY >
371 static
373  arrayView1d< string const > const & targetRegions,
374  string const & finiteElementName,
375  string const & constitutiveStringName,
376  KERNEL_FACTORY & kernelFactory )
377 {
379  // save the maximum residual contribution for scaling residuals for convergence criteria.
380  real64 maxResidualContribution = 0;
381 
382  NodeManager & nodeManager = mesh.getNodeManager();
383  EdgeManager & edgeManager = mesh.getEdgeManager();
384  FaceManager & faceManager = mesh.getFaceManager();
385  ElementRegionManager & elementRegionManager = mesh.getElemManager();
386 
387  // Loop over all sub-regions in regions of type SUBREGION_TYPE, that are listed in the targetRegions array.
388  elementRegionManager.forElementSubRegions< SUBREGION_TYPE >( targetRegions,
389  [&constitutiveStringName,
390  &maxResidualContribution,
391  &nodeManager,
392  &edgeManager,
393  &faceManager,
394  &kernelFactory,
395  &finiteElementName]
396  ( localIndex const targetRegionIndex, auto & elementSubRegion )
397  {
398  localIndex const numElems = elementSubRegion.size();
399 
400  // Get the constitutive model...and allocate a null constitutive model if required.
401 
402  constitutive::ConstitutiveBase * constitutiveRelation = nullptr;
403  constitutive::NullModel * nullConstitutiveModel = nullptr;
404  if( elementSubRegion.template hasWrapper< string >( constitutiveStringName ) )
405  {
406  string const & constitutiveName = elementSubRegion.template getReference< string >( constitutiveStringName );
407  constitutiveRelation = &elementSubRegion.template getConstitutiveModel( constitutiveName );
408  }
409  else
410  {
411  nullConstitutiveModel = &elementSubRegion.template registerGroup< constitutive::NullModel >( "nullModelGroup" );
412  constitutiveRelation = nullConstitutiveModel;
413  }
414 
415  // Call the constitutive dispatch which converts the type of constitutive model into a compile time constant.
416  constitutive::ConstitutivePassThru< CONSTITUTIVE_BASE >::execute( *constitutiveRelation,
417  [&maxResidualContribution,
418  &nodeManager,
419  &edgeManager,
420  &faceManager,
421  targetRegionIndex,
422  &kernelFactory,
423  &elementSubRegion,
424  &finiteElementName,
425  numElems]
426  ( auto & castedConstitutiveRelation )
427  {
429  subRegionFE = elementSubRegion.template getReference< FiniteElementBase >( finiteElementName );
430 
431  finiteElement::FiniteElementDispatchHandler< SELECTED_FE_TYPES >::dispatch3D( subRegionFE,
432  [&maxResidualContribution,
433  &nodeManager,
434  &edgeManager,
435  &faceManager,
436  targetRegionIndex,
437  &kernelFactory,
438  &elementSubRegion,
439  numElems,
440  &castedConstitutiveRelation] ( auto const finiteElement )
441  {
442  auto kernel = kernelFactory.createKernel( nodeManager,
443  edgeManager,
444  faceManager,
445  targetRegionIndex,
446  elementSubRegion,
448  castedConstitutiveRelation );
449 
450  using KERNEL_TYPE = decltype( kernel );
451 
452  // Call the kernelLaunch function, and store the maximum contribution to the residual.
453  maxResidualContribution =
454  std::max( maxResidualContribution,
455  KERNEL_TYPE::template kernelLaunch< POLICY, KERNEL_TYPE >( numElems, kernel ) );
456  } );
457  } );
458 
459  // Remove the null constitutive model (not required, but cleaner)
460  if( nullConstitutiveModel )
461  {
462  elementSubRegion.deregisterGroup( "nullModelGroup" );
463  }
464 
465  } );
466 
467  return maxResidualContribution;
468 }
469 //END_regionBasedKernelApplication
470 
471 } // namespace finiteElement
472 } // namespace geos
473 
474 
475 
476 #endif /* GEOS_FINITEELEMENT_KERNELBASE_HPP_ */
#define GEOS_HOST_DEVICE
Marks a host-device function.
Definition: GeosxMacros.hpp:49
#define GEOS_UNUSED_VAR(...)
Mark an unused variable and silence compiler warnings.
Definition: GeosxMacros.hpp:84
#define GEOS_FORCE_INLINE
Marks a function or lambda for inlining.
Definition: GeosxMacros.hpp:51
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:372
#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:43
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:44
Class facilitating the representation of a multi-level discretization of a MeshBody.
Definition: MeshLevel.hpp:42
NodeManager const & getNodeManager() const
Get the node manager.
Definition: MeshLevel.hpp:155
FaceManager const & getFaceManager() const
Get the face manager.
Definition: MeshLevel.hpp:194
ElementRegionManager const & getElemManager() const
Get the element region manager.
Definition: MeshLevel.hpp:207
EdgeManager const & getEdgeManager() const
Get the edge manager.
Definition: MeshLevel.hpp:181
The NodeManager class provides an interface to ObjectManagerBase in order to manage node data.
Definition: NodeManager.hpp:46
Base class for FEM element implementations.
Define the base interface for finite element kernels.
Definition: KernelBase.hpp:87
traits::ViewTypeConst< typename SUBREGION_TYPE::NodeMapType::base_type > const m_elemsToNodes
The element to nodes map.
Definition: KernelBase.hpp:257
GEOS_HOST_DEVICE void setup(localIndex const k, StackVariables &stack) const
Performs the setup phase for the kernel.
Definition: KernelBase.hpp:154
static constexpr int numQuadraturePointsPerElem
Compile time value for the number of quadrature points per element.
Definition: KernelBase.hpp:106
static constexpr int numDofPerTestSupportPoint
Definition: KernelBase.hpp:99
static constexpr int numDofPerTrialSupportPoint
Definition: KernelBase.hpp:103
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:179
static real64 kernelLaunch(localIndex const numElems, KERNEL_TYPE const &kernelComponent)
Kernel Launcher.
Definition: KernelBase.hpp:230
GEOS_HOST_DEVICE real64 complete(localIndex const k, StackVariables &stack) const
Performs the complete phase for the kernel.
Definition: KernelBase.hpp:204
static constexpr int maxNumTrialSupportPointsPerElem
Definition: KernelBase.hpp:95
arrayView1d< integer const > const m_elemGhostRank
The element ghost rank array.
Definition: KernelBase.hpp:260
CONSTITUTIVE_TYPE::KernelWrapper const m_constitutiveUpdate
Definition: KernelBase.hpp:264
KernelBase(SUBREGION_TYPE const &elementSubRegion, FE_TYPE const &finiteElementSpace, CONSTITUTIVE_TYPE &inputConstitutiveType)
Constructor.
Definition: KernelBase.hpp:116
static constexpr int maxNumTestSupportPointsPerElem
Definition: KernelBase.hpp:91
Used to forward arguments to a class that implements the KernelBase interface.
Definition: KernelBase.hpp:282
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:308
KernelFactory(ARGS ... args)
Initialize the factory.
Definition: KernelBase.hpp:289
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Definition: DataTypes.hpp:180
double real64
64-bit floating point type.
Definition: DataTypes.hpp:99
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:85
std::int32_t integer
Signed integer type.
Definition: DataTypes.hpp:82
Kernel variables allocated on the stack.
Definition: KernelBase.hpp:137