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