GEOSX
ExplicitSmallStrain_impl.hpp
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 
19 #ifndef GEOS_PHYSICSSOLVERS_SOLIDMECHANICS_KERNELS_EXPLICITSMALLTRAIN_IMPL_HPP_
20 #define GEOS_PHYSICSSOLVERS_SOLIDMECHANICS_KERNELS_EXPLICITSMALLTRAIN_IMPL_HPP_
21 
22 //#include "ExplicitFiniteStrain.hpp"
23 #include "ExplicitSmallStrain.hpp"
24 
25 
26 namespace geos
27 {
28 
30 namespace solidMechanicsLagrangianFEMKernels
31 {
32 
33 
34 template< typename SUBREGION_TYPE,
35  typename CONSTITUTIVE_TYPE,
36  typename FE_TYPE >
38  EdgeManager const & edgeManager,
39  FaceManager const & faceManager,
40  localIndex const targetRegionIndex,
41  SUBREGION_TYPE const & elementSubRegion,
42  FE_TYPE const & finiteElementSpace,
43  CONSTITUTIVE_TYPE & inputConstitutiveType,
44  real64 const dt,
45  string const elementListName ):
46  Base( elementSubRegion,
47  finiteElementSpace,
48  inputConstitutiveType ),
49  m_X( nodeManager.referencePosition()),
50  m_u( nodeManager.getField< fields::solidMechanics::totalDisplacement >() ),
51  m_vel( nodeManager.getField< fields::solidMechanics::velocity >() ),
52  m_acc( nodeManager.getField< fields::solidMechanics::acceleration >() ),
53  m_dt( dt ),
54  m_elementList( elementSubRegion.template getReference< SortedArray< localIndex > >( elementListName ).toViewConst() )
55 {
56  GEOS_UNUSED_VAR( edgeManager );
57  GEOS_UNUSED_VAR( faceManager );
58  GEOS_UNUSED_VAR( targetRegionIndex );
59 }
60 
61 
62 template< typename SUBREGION_TYPE,
63  typename CONSTITUTIVE_TYPE,
64  typename FE_TYPE >
66 inline
68  StackVariables & stack ) const
69 {
70  for( localIndex a=0; a< numNodesPerElem; ++a )
71  {
72  localIndex const nodeIndex = m_elemsToNodes( k, a );
73  for( int i=0; i<numDofPerTrialSupportPoint; ++i )
74  {
75 #if defined(CALC_FEM_SHAPE_IN_KERNEL)
76  stack.xLocal[ a ][ i ] = m_X[ nodeIndex ][ i ];
77 #endif
78 
79 #if UPDATE_STRESS==2
80  stack.varLocal[ a ][ i ] = m_vel[ nodeIndex ][ i ] * m_dt;
81 #else
82  stack.varLocal[ a ][ i ] = m_u[ nodeIndex ][ i ];
83 #endif
84  }
85  }
86 }
87 
88 template< typename SUBREGION_TYPE,
89  typename CONSTITUTIVE_TYPE,
90  typename FE_TYPE >
92 inline
94  localIndex const q,
95  StackVariables & stack ) const
96 {
97 //#define USE_JACOBIAN
98 #if !defined( USE_JACOBIAN )
99  real64 dNdX[ numNodesPerElem ][ 3 ];
100  real64 const detJ = m_finiteElementSpace.template getGradN< FE_TYPE >( k, q, stack.xLocal, dNdX );
102  real64 strain[6] = {0};
103  //real64 timeIncrement = 0.0;
104  FE_TYPE::symmetricGradient( dNdX, stack.varLocal, strain );
105 
106  real64 stressLocal[ 6 ] = {0};
107 #if UPDATE_STRESS == 2
108  m_constitutiveUpdate.smallStrainUpdate_StressOnly( k, q, m_dt, strain, stressLocal );
109 #else
110  m_constitutiveUpdate.smallStrainNoStateUpdate_StressOnly( k, q, strain, stressLocal );
111 #endif
112 
113  for( localIndex c = 0; c < 6; ++c )
114  {
115 #if UPDATE_STRESS == 2
116  stressLocal[ c ] *= -detJ;
117 #elif UPDATE_STRESS == 1
118  stressLocal[ c ] = -( stressLocal[ c ] + m_constitutiveUpdate.m_newStress( k, q, c ) ) * detJ; // TODO: decide on
119  // initial stress
120  // strategy
121 #else
122  stressLocal[ c ] *= -detJ;
123 #endif
124  }
125 
126  FE_TYPE::plusGradNajAij( dNdX, stressLocal, stack.fLocal );
127 
128 #else
129  real64 invJ[3][3];
130  real64 const detJ = FE_TYPE::inverseJacobianTransformation( q, stack.xLocal, invJ );
131 
132  real64 strain[6] = {0};
133  FE_TYPE::symmetricGradient( q, invJ, stack.varLocal, strain );
134 
135  real64 stressLocal[ 6 ] = {0};
136 #if UPDATE_STRESS == 2
137  m_constitutiveUpdate.smallStrainUpdate_StressOnly( k, q, m_dt, strain, stressLocal );
138 #else
139  m_constitutiveUpdate.smallStrainNoStateUpdate_StressOnly( k, q, strain, stressLocal );
140 #endif
141 
142  for( localIndex c = 0; c < 6; ++c )
143  {
144 #if UPDATE_STRESS == 2
145  stressLocal[ c ] *= detJ;
146 #elif UPDATE_STRESS == 1
147  stressLocal[ c ] = ( stressLocal[ c ] + m_constitutiveUpdate.m_newStress( k, q, c ) ) * DETJ; // TODO: decide on
148  // initial stress
149  // strategy
150 #else
151  stressLocal[ c ] *= DETJ;
152 #endif
153  }
154 
155  FE_TYPE::plusGradNajAij( q, invJ, stressLocal, stack.fLocal );
156 #endif
157 }
158 
159 template< typename SUBREGION_TYPE,
160  typename CONSTITUTIVE_TYPE,
161  typename FE_TYPE >
163 inline
165  StackVariables const & stack ) const
166 {
167  for( localIndex a = 0; a < numNodesPerElem; ++a )
168  {
169  localIndex const nodeIndex = m_elemsToNodes( k, a );
170  for( int b = 0; b < numDofPerTestSupportPoint; ++b )
171  {
172  RAJA::atomicAdd< parallelDeviceAtomic >( &m_acc( nodeIndex, b ), stack.fLocal[ a ][ b ] );
173  }
174  }
175  return 0;
176 }
177 
178 template< typename SUBREGION_TYPE,
179  typename CONSTITUTIVE_TYPE,
180  typename FE_TYPE >
181 template< typename POLICY,
182  typename KERNEL_TYPE >
183 real64
185  KERNEL_TYPE const & kernelComponent )
186 {
188 
189  GEOS_UNUSED_VAR( numElems );
190 
191  localIndex const numProcElems = kernelComponent.m_elementList.size();
192  forAll< POLICY >( numProcElems,
193  [=] GEOS_DEVICE ( localIndex const index )
194  {
195  localIndex const k = kernelComponent.m_elementList[ index ];
196 
197  typename KERNEL_TYPE::StackVariables stack;
198 
199  kernelComponent.setup( k, stack );
200  for( integer q=0; q<KERNEL_TYPE::numQuadraturePointsPerElem; ++q )
201  {
202  kernelComponent.quadraturePointKernel( k, q, stack );
203  }
204  kernelComponent.complete( k, stack );
205  } );
206  return 0;
207 }
208 
209 
210 #undef UPDATE_STRESS
211 
212 } // namespace solidMechanicsLagrangianFEMKernels
213 
214 } // namespace geos
215 
216 #endif //GEOS_PHYSICSSOLVERS_SOLIDMECHANICS_KERNELS_EXPLICITSMALLTRAIN_IMPL_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_DEVICE
Marks a device-only function.
Definition: GeosxMacros.hpp:46
#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 FaceManager class provides an interface to ObjectManagerBase in order to manage face data.
Definition: FaceManager.hpp:43
The NodeManager class provides an interface to ObjectManagerBase in order to manage node data.
Definition: NodeManager.hpp:45
static real64 kernelLaunch(localIndex const numElems, KERNEL_TYPE const &kernelComponent)
Kernel Launcher.
GEOS_HOST_DEVICE void setup(localIndex const k, StackVariables &stack) const
Performs the setup phase for the kernel.
ExplicitSmallStrain(NodeManager &nodeManager, EdgeManager const &edgeManager, FaceManager const &faceManager, localIndex const targetRegionIndex, SUBREGION_TYPE const &elementSubRegion, FE_TYPE const &finiteElementSpace, CONSTITUTIVE_TYPE &inputConstitutiveType, real64 const dt, string const elementListName)
Constructor.
GEOS_HOST_DEVICE void quadraturePointKernel(localIndex const k, localIndex const q, StackVariables &stack) const
Performs a state update at a quadrature point.
GEOS_HOST_DEVICE real64 complete(localIndex const k, StackVariables const &stack) const
Performs the complete phase for the kernel.
double real64
64-bit floating point type.
Definition: DataTypes.hpp:139
std::int32_t integer
Signed integer type.
Definition: DataTypes.hpp:122
LvArray::SortedArray< T, localIndex, LvArray::ChaiBuffer > SortedArray
A sorted array of local indices.
Definition: DataTypes.hpp:307
GEOSX_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:125
real64 varLocal[numNodesPerElem][numDofPerTestSupportPoint]
C-array stack storage for element local primary variable values.
real64 fLocal[numNodesPerElem][numDofPerTrialSupportPoint]
C-array stack storage for the element local force.