GEOSX
ExplicitMPM.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 
15 
20 #ifndef GEOSX_PHYSICSSOLVERS_CONTACT_EXPLICITMPM_HPP_
21 #define GEOSX_PHYSICSSOLVERS_CONTACT_EXPLICITMPM_HPP_
22 
23 #include "constitutive/solid/SolidUtilities.hpp"
25 #include "physicsSolvers/solidMechanics/MPMSolverFields.hpp"
26 
27 namespace geos
28 {
29 
30 namespace solidMechanicsMPMKernels
31 {
32 
33 // A helper function to calculate polar decomposition. TODO: Previously this was an LvArray method, hopefully it will be again someday.
35 void polarDecomposition( real64 (& R)[3][3],
36  real64 const (&matrix)[3][3] )
37 {
38  // Initialize
39  LvArray::tensorOps::copy< 3, 3 >( R, matrix );
40  real64 RInverse[3][3] = { {0} },
41  RInverseTranspose[3][3] = { {0} },
42  RRTMinusI[3][3] = { {0} };
43 
44  // Higham Algorithm
45  real64 errorSquared = 1.0;
46  real64 tolerance = 10 * LvArray::NumericLimits< real64 >::epsilon;
47  int iter = 0;
48  while( errorSquared > tolerance * tolerance && iter < 100 )
49  {
50  iter++;
51  errorSquared = 0.0;
52 
53  // Average the current R with its inverse tranpose
54  LvArray::tensorOps::internal::SquareMatrixOps< 3 >::invert( RInverse, R );
55  LvArray::tensorOps::transpose< 3, 3 >( RInverseTranspose, RInverse );
56  LvArray::tensorOps::add< 3, 3 >( R, RInverseTranspose );
57  LvArray::tensorOps::scale< 3, 3 >( R, 0.5 );
58 
59  // Determine how close R is to being orthogonal using L2Norm(R.R^T-I)
60  real64 copyR[3][3];
61  LvArray::tensorOps::copy< 3, 3 >( copyR, R );
62  LvArray::tensorOps::Rij_eq_AikBjk< 3, 3, 3 >( RRTMinusI, R, copyR );
63  LvArray::tensorOps::addIdentity< 3 >( RRTMinusI, -1.0 );
64  for( std::ptrdiff_t i = 0; i < 3; i++ )
65  {
66  for( std::ptrdiff_t j = 0; j < 3; j++ )
67  {
68  errorSquared += RRTMinusI[i][j] * RRTMinusI[i][j];
69  }
70  }
71  }
72  if( iter == 100 )
73  {
74  GEOS_LOG_RANK( "Polar decomposition did not converge in 100 iterations!" );
75  }
76 }
77 
78 
83 {
94  template< typename POLICY, typename CONSTITUTIVE_WRAPPER >
95  static void launch( SortedArrayView< localIndex const > const indices,
96  CONSTITUTIVE_WRAPPER const & constitutiveWrapper,
97  real64 dt,
98  arrayView3d< real64 const > const deformationGradient,
99  arrayView3d< real64 const > const fDot,
100  arrayView3d< real64 const > const velocityGradient,
101  arrayView2d< real64 > const particleStress )
102  {
103  arrayView3d< real64, solid::STRESS_USD > const oldStress = constitutiveWrapper.m_oldStress;
104  // arrayView3d< real64, solid::STRESS_USD > const newStress = constitutiveWrapper.m_newStress;
105 
106  // Perform constitutive call
107  forAll< POLICY >( indices.size(), [=] GEOS_HOST_DEVICE ( localIndex const k )
108  {
109  // Particle index
110  localIndex const p = indices[k];
111 
112  // Copy the beginning-of-step particle stress into the constitutive model's m_oldStress - this fixes the MPI sync issue on Lassen for
113  // some reason
114  #if defined(GEOSX_USE_CUDA)
115  LvArray::tensorOps::copy< 6 >( oldStress[p][0], particleStress[p] );
116  #endif
117 
118  // Determine the strain increment in Voigt notation
119  real64 strainIncrement[6];
120  strainIncrement[0] = velocityGradient[p][0][0] * dt;
121  strainIncrement[1] = velocityGradient[p][1][1] * dt;
122  strainIncrement[2] = velocityGradient[p][2][2] * dt;
123  strainIncrement[3] = (velocityGradient[p][1][2] + velocityGradient[p][2][1]) * dt;
124  strainIncrement[4] = (velocityGradient[p][0][2] + velocityGradient[p][2][0]) * dt;
125  strainIncrement[5] = (velocityGradient[p][0][1] + velocityGradient[p][1][0]) * dt;
126 
127  // Get old F by incrementing backwards
128  real64 fOld[3][3] = { {0} };
129  real64 fNew[3][3] = { {0} };
130  LvArray::tensorOps::copy< 3, 3 >( fNew, deformationGradient[p] );
131  LvArray::tensorOps::copy< 3, 3 >( fOld, deformationGradient[p] );
132  LvArray::tensorOps::scaledAdd< 3, 3 >( fOld, fDot[p], -dt );
133 
134  // Polar decompositions
135  real64 rotBeginning[3][3] = { {0} };
136  real64 rotEnd[3][3] = { {0} };
137  polarDecomposition( rotBeginning, fOld );
138  polarDecomposition( rotEnd, fNew );
139 
140  // Call stress update
141  real64 stress[6] = { 0 };
142  constitutive::SolidUtilities::hypoUpdate2_StressOnly( constitutiveWrapper, // the constitutive model
143  p, // particle local index
144  0, // particles have 1 quadrature point
145  dt, // time step size
146  strainIncrement, // particle strain increment
147  rotBeginning, // beginning-of-step rotation matrix
148  rotEnd, // end-of-step rotation matrix
149  stress ); // final updated stress
150 
151  // Copy the updated stress into particleStress
152  LvArray::tensorOps::copy< 6 >( particleStress[p], stress );
153 
154  // Copy m_newStress into m_oldStress
155  constitutiveWrapper.saveConvergedState( p, 0 );
156  } );
157  }
158 };
159 
160 } // namespace solidMechanicsMPMKernels
161 
162 } // namespace geos
163 
164 
165 #endif /* GEOSX_PHYSICSSOLVERS_CONTACT_EXPLICITMPM_HPP_ */
#define GEOS_HOST_DEVICE
Marks a host-device function.
Definition: GeosxMacros.hpp:48
#define GEOS_LOG_RANK(msg)
Log a message to the rank output stream.
Definition: Logger.hpp:91
double real64
64-bit floating point type.
Definition: DataTypes.hpp:139
LvArray::SortedArrayView< T, localIndex, LvArray::ChaiBuffer > SortedArrayView
A sorted array view of local indices.
Definition: DataTypes.hpp:311
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.
Definition: DataTypes.hpp:236
GEOSX_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:125
ArrayView< T, 3, USD > arrayView3d
Alias for 3D array view.
Definition: DataTypes.hpp:252
A struct to update particle stresses.
Definition: ExplicitMPM.hpp:83
static void launch(SortedArrayView< localIndex const > const indices, CONSTITUTIVE_WRAPPER const &constitutiveWrapper, real64 dt, arrayView3d< real64 const > const deformationGradient, arrayView3d< real64 const > const fDot, arrayView3d< real64 const > const velocityGradient, arrayView2d< real64 > const particleStress)
Launch the kernel function doing constitutive updates.
Definition: ExplicitMPM.hpp:95