GEOS
RateAndStateKernelsBase.hpp
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) 2018-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 
16 #ifndef GEOS_PHYSICSSOLVERS_INDUCEDSEISMICITY_KERNELS_RATEANDSTATEKERNELSBASE_HPP_
17 #define GEOS_PHYSICSSOLVERS_INDUCEDSEISMICITY_KERNELS_RATEANDSTATEKERNELSBASE_HPP_
18 
19 #include "common/DataTypes.hpp"
20 #include "common/GEOS_RAJA_Interface.hpp"
21 #include "constitutive/contact/RateAndStateFriction.hpp"
23 
24 namespace geos
25 {
26 
27 namespace rateAndStateKernels
28 {
29 
30 // TBD: Pass the kernel and add getters for relevant fields to make this function general purpose and avoid
31 // wrappers?
33 static void projectSlipRateBase( localIndex const k,
34  real64 const frictionCoefficient,
35  real64 const shearImpedance,
36  arrayView1d< real64 const > const normalTraction,
37  arrayView2d< real64 const > const shearTraction,
38  arrayView1d< real64 const > const slipRate,
39  arrayView2d< real64 > const slipVelocity )
40 {
41  // Project slip rate onto shear traction to get slip velocity components
42  real64 const frictionForce = normalTraction[k] * frictionCoefficient;
43  real64 const projectionScaling = 1.0 / ( shearImpedance + frictionForce / slipRate[k] );
44  slipVelocity[k][0] = projectionScaling * shearTraction[k][0];
45  slipVelocity[k][1] = projectionScaling * shearTraction[k][1];
46 }
47 
48 template< typename POLICY, typename KERNEL_TYPE >
49 static bool newtonSolve( SurfaceElementSubRegion & subRegion,
50  KERNEL_TYPE & kernel,
51  real64 const dt,
52  integer const maxNewtonIter,
53  real64 const newtonTol )
54 {
55  bool allConverged = false;
56  for( integer iter = 0; iter < maxNewtonIter; iter++ )
57  {
58  RAJA::ReduceMin< parallelDeviceReduce, int > converged( 1 );
59  RAJA::ReduceMax< parallelDeviceReduce, real64 > residualNorm( 0.0 );
60  forAll< POLICY >( subRegion.size(), [=] GEOS_HOST_DEVICE ( localIndex const k )
61  {
62  typename KERNEL_TYPE::StackVariables stack;
63  kernel.setup( k, dt, stack );
64  kernel.solve( k, stack );
65  auto const [elementConverged, elementResidualNorm] = kernel.checkConvergence( stack, newtonTol );
66  converged.min( elementConverged );
67  residualNorm.max( elementResidualNorm );
68  } );
69 
70  real64 const maxResidualNorm = MpiWrapper::max( residualNorm.get() );
71  GEOS_LOG_RANK_0( GEOS_FMT( " Newton iter {} : residual = {:.10e} ", iter, maxResidualNorm ) );
72 
73  if( converged.get() )
74  {
75  allConverged = true;
76  break;
77  }
78  }
79  return allConverged;
80 }
81 
86 template< typename KERNEL_TYPE, typename POLICY >
87 static void
88 createAndLaunch( SurfaceElementSubRegion & subRegion,
89  string const & frictionLawNameKey,
90  real64 const shearImpedance,
91  integer const maxNewtonIter,
92  real64 const newtonTol,
93  real64 const time_n,
94  real64 const totalDt )
95 {
97 
98  GEOS_UNUSED_VAR( time_n );
99 
100  string const & frictionaLawName = subRegion.getReference< string >( frictionLawNameKey );
101  constitutive::RateAndStateFriction const & frictionLaw = subRegion.getConstitutiveModel< constitutive::RateAndStateFriction >( frictionaLawName );
102  KERNEL_TYPE kernel( subRegion, frictionLaw, shearImpedance );
103 
104  real64 dtRemaining = totalDt;
105  real64 dt = totalDt;
106  for( integer subStep = 0; subStep < 5 && dtRemaining > 0.0; ++subStep )
107  {
108  real64 dtAccepted = KERNEL_TYPE::template solveRateAndStateEquation< POLICY >( subRegion, kernel, dt, maxNewtonIter, newtonTol );
109  dtRemaining -= dtAccepted;
110 
111  if( dtRemaining > 0.0 )
112  {
113  dt = dtAccepted;
114  }
115  GEOS_LOG_RANK_0( GEOS_FMT( " sub-step = {} completed, dt = {}, remaining dt = {}", subStep, dt, dtRemaining ) );
116  }
117 }
118 
119 } /* namespace rateAndStateKernels */
120 
121 } /* namespace geos */
122 
123 #endif /* GEOS_PHYSICSSOLVERS_INDUCEDSEISMICITY_KERNELS_RATEANDSTATEKERNELSBASE_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_LOG_RANK_0(msg)
Log a message on screen on rank 0.
Definition: Logger.hpp:101
#define GEOS_MARK_FUNCTION
Mark function with both Caliper and NVTX if enabled.
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
std::int32_t integer
Signed integer type.
Definition: DataTypes.hpp:82
static T max(T const &value, MPI_Comm comm=MPI_COMM_GEOS)
Convenience function for a MPI_Allreduce using a MPI_MAX operation.