GEOSX
ImplicitSmallStrainQuasiStatic_impl.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 
19 #ifndef GEOS_PHYSICSSOLVERS_SOLIDMECHANICS_KERNELS_IMPLCITSMALLSTRAINQUASISTATIC_IMPL_HPP_
20 #define GEOS_PHYSICSSOLVERS_SOLIDMECHANICS_KERNELS_IMPLCITSMALLSTRAINQUASISTATIC_IMPL_HPP_
21 
23 
24 namespace geos
25 {
26 
27 namespace solidMechanicsLagrangianFEMKernels
28 {
29 
30 
31 template< typename SUBREGION_TYPE,
32  typename CONSTITUTIVE_TYPE,
33  typename FE_TYPE >
35 ImplicitSmallStrainQuasiStatic( NodeManager const & nodeManager,
36  EdgeManager const & edgeManager,
37  FaceManager const & faceManager,
38  localIndex const targetRegionIndex,
39  SUBREGION_TYPE const & elementSubRegion,
40  FE_TYPE const & finiteElementSpace,
41  CONSTITUTIVE_TYPE & inputConstitutiveType,
42  arrayView1d< globalIndex const > const inputDofNumber,
43  globalIndex const rankOffset,
45  arrayView1d< real64 > const inputRhs,
46  real64 const inputDt,
47  real64 const (&inputGravityVector)[3] ):
48  Base( nodeManager,
49  edgeManager,
50  faceManager,
51  targetRegionIndex,
52  elementSubRegion,
53  finiteElementSpace,
54  inputConstitutiveType,
55  inputDofNumber,
56  rankOffset,
57  inputMatrix,
58  inputRhs,
59  inputDt ),
60  m_X( nodeManager.referencePosition()),
61  m_disp( nodeManager.getField< fields::solidMechanics::totalDisplacement >() ),
62  m_uhat( nodeManager.getField< fields::solidMechanics::incrementalDisplacement >() ),
63  m_gravityVector{ inputGravityVector[0], inputGravityVector[1], inputGravityVector[2] },
64  m_density( inputConstitutiveType.getDensity() )
65 {}
66 
67 
68 template< typename SUBREGION_TYPE,
69  typename CONSTITUTIVE_TYPE,
70  typename FE_TYPE >
74 setup( localIndex const k,
75  StackVariables & stack ) const
76 {
77  m_finiteElementSpace.template setup< FE_TYPE >( k, m_meshData, stack.feStack );
78 
79  localIndex const numSupportPoints = m_finiteElementSpace.template numSupportPoints< FE_TYPE >( stack.feStack );
80 
81  stack.numRows = 3 * numSupportPoints;
82  stack.numCols = stack.numRows;
83 
84  // #pragma unroll
85  for( localIndex a = 0; a < numSupportPoints; ++a )
86  {
87  localIndex const localNodeIndex = m_elemsToNodes( k, a );
88 
89  // #pragma unroll
90  for( int i = 0; i < numDofPerTestSupportPoint; ++i )
91  {
92 #if defined(CALC_FEM_SHAPE_IN_KERNEL)
93  stack.xLocal[ a ][ i ] = m_X[ localNodeIndex ][ i ];
94 #endif
95  stack.u_local[ a ][i] = m_disp[ localNodeIndex ][i];
96  stack.uhat_local[ a ][i] = m_uhat[ localNodeIndex ][i];
97  stack.localRowDofIndex[a*3+i] = m_dofNumber[localNodeIndex]+i;
98  stack.localColDofIndex[a*3+i] = m_dofNumber[localNodeIndex]+i;
99  }
100  }
101  // Add stabilization to block diagonal parts of the local jacobian
102  // (this is a no-operation with FEM classes)
103  real64 const stabilizationScaling = computeStabilizationScaling( k );
104  m_finiteElementSpace.template addGradGradStabilizationMatrix
105  < FE_TYPE, numDofPerTrialSupportPoint, true >( stack.feStack,
106  stack.localJacobian,
107  -stabilizationScaling );
108 }
109 
110 template< typename SUBREGION_TYPE,
111  typename CONSTITUTIVE_TYPE,
112  typename FE_TYPE >
113 template< typename STRESS_MODIFIER >
117  localIndex const q,
118  StackVariables & stack,
119  STRESS_MODIFIER && stressModifier ) const
120 {
121  real64 dNdX[ numNodesPerElem ][ 3 ];
122  real64 const detJxW = m_finiteElementSpace.template getGradN< FE_TYPE >( k, q, stack.xLocal, stack.feStack, dNdX );
123 
124  real64 strainInc[6] = {0};
125  real64 stress[6] = {0};
126 
127  typename CONSTITUTIVE_TYPE::KernelWrapper::DiscretizationOps stiffness;
128 
129  FE_TYPE::symmetricGradient( dNdX, stack.uhat_local, strainInc );
130 
131  m_constitutiveUpdate.smallStrainUpdate( k, q, m_dt, strainInc, stress, stiffness );
132 
133  stressModifier( stress );
134  // #pragma unroll
135  for( localIndex i=0; i<6; ++i )
136  {
137  stress[i] *= -detJxW;
138  }
139 
140  real64 const gravityForce[3] = { m_gravityVector[0] * m_density( k, q )* detJxW,
141  m_gravityVector[1] * m_density( k, q )* detJxW,
142  m_gravityVector[2] * m_density( k, q )* detJxW };
143 
144  real64 N[numNodesPerElem];
145  FE_TYPE::calcN( q, stack.feStack, N );
146  FE_TYPE::plusGradNajAijPlusNaFi( dNdX,
147  stress,
148  N,
149  gravityForce,
150  reinterpret_cast< real64 (&)[numNodesPerElem][3] >(stack.localResidual) );
151  real64 const stabilizationScaling = computeStabilizationScaling( k );
152  m_finiteElementSpace.template addEvaluatedGradGradStabilizationVector< FE_TYPE, numDofPerTrialSupportPoint >( stack.feStack,
153  stack.uhat_local,
154  reinterpret_cast< real64 (&)[numNodesPerElem][3] >(stack.localResidual),
155  -stabilizationScaling );
156 #if !defined( GEOS_USE_HIP )
157  stiffness.template upperBTDB< numNodesPerElem >( dNdX, -detJxW, stack.localJacobian );
158 # else
159  stiffness.template BTDB< numNodesPerElem >( dNdX, -detJxW, stack.localJacobian ); // need to use full BTDB compute for hip
160 #endif
161 }
162 
163 
164 template< typename SUBREGION_TYPE,
165  typename CONSTITUTIVE_TYPE,
166  typename FE_TYPE >
170  StackVariables & stack ) const
171 {
172  GEOS_UNUSED_VAR( k );
173  real64 maxForce = 0;
174 
175 #if !defined( GEOS_USE_HIP )
176  // TODO: Does this work if BTDB is non-symmetric?
177  CONSTITUTIVE_TYPE::KernelWrapper::DiscretizationOps::template fillLowerBTDB< numNodesPerElem >( stack.localJacobian );
178 #endif
179  localIndex const numSupportPoints = m_finiteElementSpace.template numSupportPoints< FE_TYPE >( stack.feStack );
180 
181  // #pragma unroll
182  for( int localNode = 0; localNode < numSupportPoints; ++localNode )
183  {
184  // #pragma unroll
185  for( int dim = 0; dim < numDofPerTestSupportPoint; ++dim )
186  {
187  localIndex const dof = LvArray::integerConversion< localIndex >( stack.localRowDofIndex[ numDofPerTestSupportPoint * localNode + dim ] - m_dofRankOffset );
188  if( dof < 0 || dof >= m_matrix.numRows() )
189  continue;
190  m_matrix.template addToRowBinarySearchUnsorted< parallelDeviceAtomic >( dof,
191  stack.localRowDofIndex,
192  stack.localJacobian[ numDofPerTestSupportPoint * localNode + dim ],
193  stack.numRows );
194 
195  RAJA::atomicAdd< parallelDeviceAtomic >( &m_rhs[ dof ], stack.localResidual[ numDofPerTestSupportPoint * localNode + dim ] );
196  maxForce = fmax( maxForce, fabs( stack.localResidual[ numDofPerTestSupportPoint * localNode + dim ] ) );
197  }
198  }
199 
200 
201  return maxForce;
202 }
203 
204 template< typename SUBREGION_TYPE,
205  typename CONSTITUTIVE_TYPE,
206  typename FE_TYPE >
207 template< typename POLICY,
208  typename KERNEL_TYPE >
210 real64
212  KERNEL_TYPE const & kernelComponent )
213 {
214  return Base::template kernelLaunch< POLICY, KERNEL_TYPE >( numElems, kernelComponent );
215 }
216 
217 
218 } // namespace solidMechanicsLagrangianFEMKernels
219 
220 } // namespace geos
221 
222 #endif // GEOS_PHYSICSSOLVERS_SOLIDMECHANICS_KERNELS_IMPLCITSMALLSTRAINQUASISTATIC_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_FORCE_INLINE
Marks a function or lambda for inlining.
Definition: GeosxMacros.hpp:50
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 quadraturePointKernel(localIndex const k, localIndex const q, StackVariables &stack, STRESS_MODIFIER &&stressModifier=NoOpFunctors{}) const
Performs a state update at a quadrature point.
ImplicitSmallStrainQuasiStatic(NodeManager const &nodeManager, EdgeManager const &edgeManager, FaceManager const &faceManager, localIndex const targetRegionIndex, SUBREGION_TYPE const &elementSubRegion, FE_TYPE const &finiteElementSpace, CONSTITUTIVE_TYPE &inputConstitutiveType, arrayView1d< globalIndex const > const inputDofNumber, globalIndex const rankOffset, CRSMatrixView< real64, globalIndex const > const inputMatrix, arrayView1d< real64 > const inputRhs, real64 const inputDt, real64 const (&inputGravityVector)[3])
Constructor.
GEOS_HOST_DEVICE real64 complete(localIndex const k, StackVariables &stack) const
Performs the complete phase for the kernel.
GEOS_HOST_DEVICE void setup(localIndex const k, StackVariables &stack) const
Copy global values from primary field to a local stack array.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Definition: DataTypes.hpp:220
LvArray::CRSMatrixView< T, COL_INDEX, localIndex const, LvArray::ChaiBuffer > CRSMatrixView
Alias for CRS Matrix View.
Definition: DataTypes.hpp:350
double real64
64-bit floating point type.
Definition: DataTypes.hpp:139
GEOSX_GLOBALINDEX_TYPE globalIndex
Global index type (for indexing objects across MPI partitions).
Definition: DataTypes.hpp:128
GEOSX_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:125
real64 uhat_local[numNodesPerElem][numDofPerTrialSupportPoint]
Stack storage for the element local nodal incremental displacement.
real64 u_local[numNodesPerElem][numDofPerTrialSupportPoint]
Stack storage for the element local nodal displacement.