16 #ifndef GEOS_PHYSICSSOLVERS_INDUCEDSEISMICITY_KERNELS_IMPLICITRATEANDSTATEKERNELS_HPP_
17 #define GEOS_PHYSICSSOLVERS_INDUCEDSEISMICITY_KERNELS_IMPLICITRATEANDSTATEKERNELS_HPP_
19 #include "RateAndStateKernelsBase.hpp"
20 #include "denseLinearAlgebra/denseLASolvers.hpp"
25 namespace rateAndStateKernels
40 constitutive::RateAndStateFriction
const & frictionLaw,
41 real64 const shearImpedance ):
42 m_slipRate( subRegion.
getField< fields::rateAndState::slipRate >() ),
43 m_stateVariable( subRegion.
getField< fields::rateAndState::stateVariable >() ),
44 m_stateVariable_n( subRegion.
getField< fields::rateAndState::stateVariable_n >() ),
45 m_slipRate_n( subRegion.
getField< fields::rateAndState::slipRate_n >() ),
46 m_normalTraction( subRegion.
getField< fields::rateAndState::normalTraction >() ),
47 m_shearTraction( subRegion.
getField< fields::rateAndState::shearTraction >() ),
48 m_slipVelocity( subRegion.
getField< fields::rateAndState::slipVelocity >() ),
49 m_shearImpedance( shearImpedance ),
50 m_frictionLaw( frictionLaw.createKernelUpdates() )
74 real64 const normalTraction = m_normalTraction[k];
75 real64 const shearTractionMagnitude = LvArray::tensorOps::l2Norm< 2 >( m_shearTraction[k] );
78 stack.rhs[0] = shearTractionMagnitude - m_shearImpedance * m_slipRate[k]
79 - normalTraction * m_frictionLaw.frictionCoefficient( k, m_slipRate[k], m_stateVariable[k] );
80 real64 const dFriction[2] = { -normalTraction * m_frictionLaw.dFrictionCoefficient_dStateVariable( k, m_slipRate[k], m_stateVariable[k] ),
81 -m_shearImpedance - normalTraction * m_frictionLaw.dFrictionCoefficient_dSlipRate( k, m_slipRate[k], m_stateVariable[k] ) };
84 stack.rhs[1] = (m_stateVariable[k] - m_stateVariable_n[k]) / dt - m_frictionLaw.stateEvolution( k, m_slipRate[k], m_stateVariable[k] );
85 real64 const dStateEvolutionLaw[2] = { 1.0 / dt - m_frictionLaw.dStateEvolution_dStateVariable( k, m_slipRate[k], m_stateVariable[k] ),
86 -m_frictionLaw.dStateEvolution_dSlipRate( k, m_slipRate[k], m_stateVariable[k] ) };
89 stack.jacobian[0][0] = dFriction[0];
90 stack.jacobian[0][1] = dFriction[1];
91 stack.jacobian[1][0] = dStateEvolutionLaw[0];
92 stack.jacobian[1][1] = dStateEvolutionLaw[1];
100 real64 solution[2] = {0.0, 0.0};
101 LvArray::tensorOps::scale< 2 >( stack.rhs, -1.0 );
102 denseLinearAlgebra::solve< 2 >( stack.jacobian, stack.rhs, solution );
106 real64 const shearTractionMagnitude = LvArray::tensorOps::l2Norm< 2 >( m_shearTraction[k] );
107 real64 const upperBound = shearTractionMagnitude / m_shearImpedance - m_slipRate[k];
108 real64 const lowerBound = -m_slipRate[k];
110 real64 scalingFactor = 1.0;
111 if( solution[1] > upperBound )
113 scalingFactor = 0.5 * upperBound / solution[1];
115 else if( solution[1] < lowerBound )
117 scalingFactor = 0.5 * lowerBound / solution[1];
120 LvArray::tensorOps::scale< 2 >( solution, scalingFactor );
123 m_stateVariable[k] += solution[0];
124 m_slipRate[k] += solution[1];
128 void projectSlipRate(
localIndex const k )
const
130 real64 const frictionCoefficient = m_frictionLaw.frictionCoefficient( k, m_slipRate[k], m_stateVariable[k] );
131 projectSlipRateBase( k, frictionCoefficient, m_shearImpedance, m_normalTraction, m_shearTraction, m_slipRate, m_slipVelocity );
135 void udpateVariables(
localIndex const k )
const
137 projectSlipRate( k );
138 m_stateVariable_n[k] = m_stateVariable[k];
139 m_slipRate_n[k] = m_slipRate[k];
143 camp::tuple< int, real64 > checkConvergence( StackVariables
const & stack,
146 real64 const residualNorm = LvArray::tensorOps::l2Norm< 2 >( stack.rhs );
147 int const converged = residualNorm < tol ? 1 : 0;
148 camp::tuple< int, real64 > result { converged, residualNorm };
155 m_stateVariable[k] = m_stateVariable_n[k];
156 m_slipRate[k] = m_slipRate_n[k];
159 template<
typename POLICY >
160 static real64 solveRateAndStateEquation( SurfaceElementSubRegion & subRegion,
161 ImplicitFixedStressRateAndStateKernel & kernel,
166 bool converged =
false;
167 for(
integer attempt = 0; attempt < 5; attempt++ )
173 kernel.resetState( k );
177 converged = newtonSolve< POLICY >( subRegion, kernel, dt, maxNewtonIter, newtonTol );
182 kernel.udpateVariables( k );
188 GEOS_LOG_RANK_0( GEOS_FMT(
" Attempt {} failed. Halving dt and retrying.", attempt ) );
194 GEOS_ERROR(
"Maximum number of attempts reached without convergence." );
201 arrayView1d< real64 >
const m_slipRate;
203 arrayView1d< real64 >
const m_stateVariable;
205 arrayView1d< real64 >
const m_stateVariable_n;
207 arrayView1d< real64 >
const m_slipRate_n;
209 arrayView1d< real64 >
const m_normalTraction;
211 arrayView2d< real64 >
const m_shearTraction;
213 arrayView2d< real64 >
const m_slipVelocity;
215 real64 const m_shearImpedance;
217 constitutive::RateAndStateFriction::KernelWrapper m_frictionLaw;
#define GEOS_HOST_DEVICE
Marks a host-device function.
#define GEOS_ERROR(msg)
Raise a hard error and terminate the program.
#define GEOS_LOG_RANK_0(msg)
Log a message on screen on rank 0.
GEOS_DECLTYPE_AUTO_RETURN getField() const
Get a view to the field associated with a trait from this ObjectManagerBase.
GEOS_HOST_DEVICE void solve(localIndex const k, StackVariables &stack) const
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.
Kernel variables located on the stack.