20 #ifndef GEOS_PHYSICSSOLVERS_CONTACT_KERNELS_SOLIDMECHANICSCONTACTFACEBUBBLEKERNELS_HPP_
21 #define GEOS_PHYSICSSOLVERS_CONTACT_KERNELS_SOLIDMECHANICSCONTACTFACEBUBBLEKERNELS_HPP_
32 namespace solidMechanicsConformingContactKernels
40 template<
typename SUBREGION_TYPE,
41 typename CONSTITUTIVE_TYPE,
82 SUBREGION_TYPE
const & elementSubRegion,
83 FE_TYPE
const & finiteElementSpace,
84 CONSTITUTIVE_TYPE & inputConstitutiveType,
91 real64 const (&inputGravityVector)[3] ):
98 inputConstitutiveType,
104 inputGravityVector ),
105 m_bubbleDisp( faceManager.getField< fields::solidMechanics::totalBubbleDisplacement >().toViewConst() ),
142 constitutiveStiffness{ {} }
164 real64 localAbb[numBubbleUdofs][numBubbleUdofs];
167 real64 localAbu[numBubbleUdofs][numUdofs];
170 real64 localAub[numUdofs][numBubbleUdofs];
196 template<
typename POLICY,
197 typename KERNEL_TYPE >
201 KERNEL_TYPE
const & kernelComponent )
208 RAJA::ReduceMax< ReducePolicy< POLICY >,
real64 > maxResidual( 0 );
210 forAll< POLICY >( kernelComponent.m_bubbleElems.size(),
213 typename KERNEL_TYPE::StackVariables stack;
215 kernelComponent.setup( i, stack );
216 for(
integer q=0; q<numQuadraturePointsPerElem; ++q )
218 kernelComponent.quadraturePointKernel( i, q, stack );
220 maxResidual.max( kernelComponent.complete( i, stack ) );
223 return maxResidual.get();
230 StackVariables & stack )
const
237 localIndex const localNodeIndex = m_elemsToNodes( k, a );
239 for(
int i=0; i<3; ++i )
241 stack.dispEqnRowIndices[a*3+i] = m_dofNumber[localNodeIndex]+i-m_dofRankOffset;
242 stack.dispColIndices[a*3+i] = m_dofNumber[localNodeIndex]+i;
243 stack.X[ a ][ i ] = m_X[ localNodeIndex ][ i ];
244 stack.uLocal[ a*3 + i ] = m_disp[localNodeIndex][i];
248 localIndex const localFaceIndex = m_elemsToFaces[kk][0];
250 for(
int i=0; i<3; ++i )
253 stack.bEqnRowIndices[i] = m_bDofNumber[localFaceIndex] + i - m_dofRankOffset;
254 stack.bColIndices[i] = m_bDofNumber[localFaceIndex] + i;
255 stack.bLocal[ i ] = m_bubbleDisp[ localFaceIndex ][i];
262 void quadraturePointKernel(
localIndex const kk,
264 StackVariables & stack )
const
268 constexpr
int nUdof = numNodesPerElem*3;
269 constexpr
int nBubbleUdof = numFacesPerElem*3;
271 real64 dBubbleNdX[ numFacesPerElem ][ 3 ];
273 LvArray::tensorOps::fill< numFacesPerElem, 3 >( dBubbleNdX, 0 );
275 real64 detJ = m_finiteElementSpace.calcGradFaceBubbleN( q, stack.X, dBubbleNdX );
277 real64 dNdX[ numNodesPerElem ][ 3 ];
278 detJ = m_finiteElementSpace.calcGradN( q, stack.X, dNdX );
280 m_constitutiveUpdate.getElasticStiffness( k, q, stack.constitutiveStiffness );
282 real64 strainMatrix[6][nUdof];
283 solidMechanicsConformingContactKernelsHelper::assembleStrainOperator< 6, nUdof, numNodesPerElem >( strainMatrix, dNdX );
285 real64 strainBubbleMatrix[6][nBubbleUdof];
286 solidMechanicsConformingContactKernelsHelper::assembleStrainOperator< 6, nBubbleUdof, numFacesPerElem >( strainBubbleMatrix, dBubbleNdX );
290 real64 matBD[nBubbleUdof][6];
291 real64 Abb_gauss[nBubbleUdof][nBubbleUdof], Abu_gauss[nBubbleUdof][nUdof], Aub_gauss[nUdof][nBubbleUdof];
294 LvArray::tensorOps::Rij_eq_AkiBkj< nBubbleUdof, 6, 6 >( matBD, strainBubbleMatrix, stack.constitutiveStiffness );
297 LvArray::tensorOps::Rij_eq_AikBkj< nBubbleUdof, nUdof, 6 >( Abu_gauss, matBD, strainMatrix );
300 LvArray::tensorOps::Rij_eq_AikBkj< nBubbleUdof, nBubbleUdof, 6 >( Abb_gauss, matBD, strainBubbleMatrix );
303 LvArray::tensorOps::transpose< nUdof, nBubbleUdof >( Aub_gauss, Abu_gauss );
306 LvArray::tensorOps::scaledAdd< nBubbleUdof, nBubbleUdof >( stack.localAbb, Abb_gauss, -detJ );
307 LvArray::tensorOps::scaledAdd< nBubbleUdof, nUdof >( stack.localAbu, Abu_gauss, -detJ );
308 LvArray::tensorOps::scaledAdd< nUdof, nBubbleUdof >( stack.localAub, Aub_gauss, -detJ );
312 real64 rb_gauss[nBubbleUdof]{};
314 LvArray::tensorOps::Ri_eq_AijBj< 6, nUdof >( strain, strainMatrix, stack.uLocal );
316 real64 initStressLocal[ 6 ] = {0};
317 LvArray::tensorOps::Ri_eq_AijBj< 6, 6 >( initStressLocal, stack.constitutiveStiffness, strain );
320 initStressLocal[ c ] -= m_constitutiveUpdate.m_newStress( k, q, c );
323 LvArray::tensorOps::Ri_eq_AjiBj< nBubbleUdof, 6 >( rb_gauss, strainBubbleMatrix, initStressLocal );
324 LvArray::tensorOps::scaledAdd< nBubbleUdof >( stack.localRb, rb_gauss, detJ );
331 StackVariables & stack )
const
335 constexpr
int nUdof = numNodesPerElem*3;
337 localIndex const parentFaceIndex = m_elemsToFaces[kk][1];
341 real64 localAub[nUdof][3];
342 real64 localAbu[3][nUdof];
349 localAub[j][i] = stack.localAub[j][parentFaceIndex*3+i];
353 localAbb[j][i] = stack.localAbb[parentFaceIndex*3+j][parentFaceIndex*3+i];
355 localRb[i] = stack.localRb[parentFaceIndex*3+i];
362 localAbu[i][j] = stack.localAbu[parentFaceIndex*3+i][j];
367 LvArray::tensorOps::Ri_add_AijBj< 3, 3 >( localRb, localAbb, stack.bLocal );
368 LvArray::tensorOps::Ri_add_AijBj< 3, nUdof >( localRb, localAbu, stack.uLocal );
369 LvArray::tensorOps::Ri_add_AijBj< nUdof, 3 >( stack.localRu, localAub, stack.bLocal );
373 localIndex const dof = LvArray::integerConversion< localIndex >( stack.dispEqnRowIndices[ i ] );
374 if( dof < 0 || dof >= m_matrix.numRows() )
continue;
376 RAJA::atomicAdd< parallelDeviceAtomic >( &m_rhs[dof], stack.localRu[i] );
379 m_matrix.template addToRowBinarySearchUnsorted< parallelDeviceAtomic >( dof,
388 localIndex const dof = LvArray::integerConversion< localIndex >( stack.bEqnRowIndices[ i ] );
390 if( dof < 0 || dof >= m_matrix.numRows() )
continue;
392 RAJA::atomicAdd< parallelDeviceAtomic >( &m_rhs[dof], localRb[i] );
395 m_matrix.template addToRowBinarySearchUnsorted< parallelDeviceAtomic >( dof,
400 m_matrix.template addToRowBinarySearchUnsorted< parallelDeviceAtomic >( dof,
401 stack.dispColIndices,
#define GEOS_HOST_DEVICE
Marks a host-device function.
#define GEOS_UNUSED_VAR(...)
Mark an unused variable and silence compiler warnings.
#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.
The FaceManager class provides an interface to ObjectManagerBase in order to manage face data.
The NodeManager class provides an interface to ObjectManagerBase in order to manage node data.
globalIndex const m_dofRankOffset
The global rank offset.
traits::ViewTypeConst< typename SUBREGION_TYPE::NodeMapType::base_type > const m_elemsToNodes
The element to nodes map.
FE_TYPE const m_finiteElementSpace
CRSMatrixView< real64, globalIndex const > const m_matrix
The global Jacobian matrix.
arrayView1d< globalIndex const > const m_dofNumber
The global degree of freedom number.
static constexpr int maxNumTestSupportPointsPerElem
arrayView1d< real64 > const m_rhs
The global residaul vector.
CONSTITUTIVE_TYPE::KernelWrapper const m_constitutiveUpdate
Used to forward arguments to a class that implements the KernelBase interface.
Implements kernels for solving quasi-static equilibrium.
arrayView2d< real64 const, nodes::TOTAL_DISPLACEMENT_USD > const m_disp
The rank-global displacement array.
arrayView2d< real64 const, nodes::REFERENCE_POSITION_USD > const m_X
The array containing the nodal position array.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
LvArray::CRSMatrixView< T, COL_INDEX, localIndex const, LvArray::ChaiBuffer > CRSMatrixView
Alias for CRS Matrix View.
GEOS_GLOBALINDEX_TYPE globalIndex
Global index type (for indexing objects across MPI partitions).
double real64
64-bit floating point type.
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
std::int32_t integer
Signed integer type.
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.