17 #ifndef GEOS_PHYSICSSOLVERS_INDUCEDSEISMICITY_KERNELS_EMBEDDEDRUNGEKUTTAKERNELS_HPP_
18 #define GEOS_PHYSICSSOLVERS_INDUCEDSEISMICITY_KERNELS_EMBEDDEDRUNGEKUTTAKERNELS_HPP_
22 #include "common/GEOS_RAJA_Interface.hpp"
23 #include "constitutive/contact/RateAndStateFriction.hpp"
25 #include "constitutive/ConstitutivePassThru.hpp"
36 namespace rateAndStateKernels
45 integer constexpr
static algHighOrder = 3;
46 integer constexpr
static algLowOrder = 2;
47 integer constexpr
static numStages = 3;
48 real64 const a[2][2] = { { 1.0/2.0, 0.0 },
50 real64 const c[3] = { 0.0, 1.0/2.0, 1.0 };
51 real64 const b[3] = { 1.0/6.0, 4.0/6.0, 1.0/6.0 };
52 real64 const bStar[3] = { 1.0/2.0, 0.0, 1.0/2.0 };
53 real64 constexpr
static FSAL =
false;
61 integer constexpr
static algHighOrder = 3;
62 integer constexpr
static algLowOrder = 2;
63 integer constexpr
static numStages = 4;
64 real64 const a[3][3] = { { 1.0/2.0, 0.0, 0.0 },
65 { 0.0, 3.0/4.0, 0.0 },
66 { 2.0/9.0, 1.0/3.0, 4.0/9.0 } };
67 real64 const c[4] = { 0.0, 1.0/2.0, 3.0/4.0, 1.0 };
68 real64 const b[4] = { 2.0/9.0, 1.0/3.0, 4.0/9.0, 0.0 };
69 real64 const bStar[4] = { 7.0/24.0, 1.0/4.0, 1.0/3.0, 1.0/8.0};
70 bool constexpr
static FSAL =
true;
81 template<
typename TABLE_TYPE,
typename FRICTION_LAW_TYPE >
87 FRICTION_LAW_TYPE
const & frictionLaw,
88 TABLE_TYPE butcherTable ):
89 m_stateVariable( subRegion.
getField< fields::rateAndState::stateVariable >() ),
90 m_stateVariable_n( subRegion.
getField< fields::rateAndState::stateVariable_n >() ),
91 m_slipRate( subRegion.
getField< fields::rateAndState::slipRate >() ),
92 m_slipVelocity( subRegion.
getField< fields::rateAndState::slipVelocity >() ),
93 m_slipVelocity_n( subRegion.
getField< fields::rateAndState::slipVelocity_n >() ),
94 m_deltaSlip( subRegion.
getField< fields::contact::deltaSlip >() ),
95 m_deltaSlip_n( subRegion.
getField< fields::contact::deltaSlip_n >() ),
96 m_dispJump( subRegion.
getField< fields::contact::dispJump >() ),
97 m_dispJump_n( subRegion.
getField< fields::contact::dispJump_n >() ),
98 m_error( subRegion.
getField< fields::rateAndState::error >() ),
99 m_stageRates( subRegion.
getField< fields::rateAndState::rungeKuttaStageRates >() ),
100 m_frictionLaw( frictionLaw.createKernelUpdates() ),
101 m_butcherTable( butcherTable )
110 LvArray::tensorOps::copy< 2 >( m_slipVelocity[k], m_slipVelocity_n[k] );
111 m_slipRate[k] = LvArray::tensorOps::l2Norm< 2 >( m_slipVelocity_n[k] );
112 m_stateVariable[k] = m_stateVariable_n[k];
122 LvArray::tensorOps::copy< 3 >( m_stageRates[k][0], m_stageRates[k][m_butcherTable.numStages-1] );
131 m_stageRates[k][stageIndex][0] = m_slipVelocity[k][0];
132 m_stageRates[k][stageIndex][1] = m_slipVelocity[k][1];
133 m_stageRates[k][stageIndex][2] = m_frictionLaw.stateEvolution( k, m_slipRate[k], m_stateVariable[k] );
143 real64 stateVariableIncrement = 0.0;
144 real64 deltaSlipIncrement[2] = {0.0, 0.0};
146 for(
integer i = 0; i < stageIndex; i++ )
148 deltaSlipIncrement[0] += m_butcherTable.a[stageIndex-1][i] * m_stageRates[k][i][0];
149 deltaSlipIncrement[1] += m_butcherTable.a[stageIndex-1][i] * m_stageRates[k][i][1];
150 stateVariableIncrement += m_butcherTable.a[stageIndex-1][i] * m_stageRates[k][i][2];
152 m_deltaSlip[k][0] = m_deltaSlip_n[k][0] + dt*deltaSlipIncrement[0];
153 m_deltaSlip[k][1] = m_deltaSlip_n[k][1] + dt*deltaSlipIncrement[1];
154 m_stateVariable[k] = m_stateVariable_n[k] + dt*stateVariableIncrement;
156 m_dispJump[k][1] = m_dispJump_n[k][1] + m_deltaSlip[k][0];
157 m_dispJump[k][2] = m_dispJump_n[k][2] + m_deltaSlip[k][1];
168 real64 deltaSlipIncrement[2] = {0.0, 0.0};
169 real64 deltaSlipIncrementLowOrder[2] = {0.0, 0.0};
171 real64 stateVariableIncrement = 0.0;
172 real64 stateVariableIncrementLowOrder = 0.0;
174 for(
localIndex i = 0; i < m_butcherTable.numStages; i++ )
178 deltaSlipIncrement[0] += m_butcherTable.b[i] * m_stageRates[k][i][0];
179 deltaSlipIncrement[1] += m_butcherTable.b[i] * m_stageRates[k][i][1];
180 stateVariableIncrement += m_butcherTable.b[i] * m_stageRates[k][i][2];
183 deltaSlipIncrementLowOrder[0] += m_butcherTable.bStar[i] * m_stageRates[k][i][0];
184 deltaSlipIncrementLowOrder[1] += m_butcherTable.bStar[i] * m_stageRates[k][i][1];
185 stateVariableIncrementLowOrder += m_butcherTable.bStar[i] * m_stageRates[k][i][2];
188 m_deltaSlip[k][0] = m_deltaSlip_n[k][0] + dt * deltaSlipIncrement[0];
189 m_deltaSlip[k][1] = m_deltaSlip_n[k][1] + dt * deltaSlipIncrement[1];
190 m_stateVariable[k] = m_stateVariable_n[k] + dt * stateVariableIncrement;
192 real64 const deltaSlipLowOrder[2] = {m_deltaSlip_n[k][0] + dt * deltaSlipIncrementLowOrder[0],
193 m_deltaSlip_n[k][1] + dt * deltaSlipIncrementLowOrder[1]};
194 real64 const stateVariableLowOrder = m_stateVariable_n[k] + dt * stateVariableIncrementLowOrder;
196 m_dispJump[k][1] = m_dispJump_n[k][1] + m_deltaSlip[k][0];
197 m_dispJump[k][2] = m_dispJump_n[k][2] + m_deltaSlip[k][1];
200 m_error[k][0] =
computeError( m_deltaSlip[k][0], deltaSlipLowOrder[0], absTol, relTol );
201 m_error[k][1] =
computeError( m_deltaSlip[k][1], deltaSlipLowOrder[1], absTol, relTol );
202 m_error[k][2] =
computeError( m_stateVariable[k], stateVariableLowOrder, absTol, relTol );
213 real64 deltaSlipIncrementLowOrder[2] = {0.0, 0.0};
214 real64 stateVariableIncrementLowOrder = 0.0;
216 for(
localIndex i = 0; i < m_butcherTable.numStages; i++ )
221 deltaSlipIncrementLowOrder[0] += m_butcherTable.bStar[i] * m_stageRates[k][i][0];
222 deltaSlipIncrementLowOrder[1] += m_butcherTable.bStar[i] * m_stageRates[k][i][1];
223 stateVariableIncrementLowOrder += m_butcherTable.bStar[i] * m_stageRates[k][i][2];
226 real64 const deltaSlipLowOrder[2] = {m_deltaSlip_n[k][0] + dt * deltaSlipIncrementLowOrder[0],
227 m_deltaSlip_n[k][1] + dt * deltaSlipIncrementLowOrder[1]};
228 real64 const stateVariableLowOrder = m_stateVariable_n[k] + dt * stateVariableIncrementLowOrder;
230 m_dispJump[k][1] = m_dispJump_n[k][1] + m_deltaSlip[k][0];
231 m_dispJump[k][2] = m_dispJump_n[k][2] + m_deltaSlip[k][1];
234 m_error[k][0] =
computeError( m_deltaSlip[k][0], deltaSlipLowOrder[0], absTol, relTol );
235 m_error[k][1] =
computeError( m_deltaSlip[k][1], deltaSlipLowOrder[1], absTol, relTol );
236 m_error[k][2] =
computeError( m_stateVariable[k], stateVariableLowOrder, absTol, relTol );
245 return (highOrderApprox - lowOrderApprox) /
246 ( absTol + relTol * LvArray::math::max( LvArray::math::abs( highOrderApprox ), LvArray::math::abs( lowOrderApprox ) ));
285 typename FRICTION_LAW_TYPE::KernelWrapper m_frictionLaw;
288 TABLE_TYPE m_butcherTable;
291 template<
typename FRICTION_TYPE,
typename BUTCHER_TABLE_TYPE >
293 FRICTION_TYPE & frictionLaw,
294 BUTCHER_TABLE_TYPE
const & butcherTable,
296 bool const successfulStep )
299 if( butcherTable.FSAL && successfulStep )
303 rkKernel.updateStageRatesFSAL( k );
304 rkKernel.updateStageValues( k, 1, dt );
311 rkKernel.initialize( k );
312 rkKernel.updateStageRates( k, 0 );
313 rkKernel.updateStageValues( k, 1, dt );
318 template<
typename BUTCHER_TABLE_TYPE,
typename FRICTION_TYPE >
319 void createAndlaunchStepRateStateODESubstage( SurfaceElementSubRegion & subRegion,
320 FRICTION_TYPE & frictionLaw,
321 BUTCHER_TABLE_TYPE
const & butcherTable,
326 rateAndStateKernels::EmbeddedRungeKuttaKernel< BUTCHER_TABLE_TYPE, FRICTION_TYPE > rkKernel( subRegion, frictionLaw, butcherTable );
329 rkKernel.updateStageRates( k, stageIndex );
330 rkKernel.updateStageValues( k, stageIndex+1, dt );
334 template<
typename BUTCHER_TABLE_TYPE,
typename FRICTION_TYPE >
335 void createAndlaunchStepRateStateODEAndComputeError( SurfaceElementSubRegion & subRegion,
336 FRICTION_TYPE & frictionLaw,
337 BUTCHER_TABLE_TYPE
const & butcherTable,
338 real64 const relTolerance,
339 real64 const absTolerance,
343 rateAndStateKernels::EmbeddedRungeKuttaKernel< BUTCHER_TABLE_TYPE, FRICTION_TYPE > rkKernel( subRegion, frictionLaw, butcherTable );
344 if( butcherTable.FSAL )
349 rkKernel.updateStageRates( k, butcherTable.numStages-1 );
351 rkKernel.updateSolutionAndLocalErrorFSAL( k, dt, absTolerance, relTolerance );
359 rkKernel.updateStageRates( k, butcherTable.numStages-1 );
361 rkKernel.updateSolutionAndLocalError( k, dt, absTolerance, relTolerance );
#define GEOS_HOST_DEVICE
Marks a host-device function.
GEOS_DECLTYPE_AUTO_RETURN getField() const
Get a view to the field associated with a trait from this ObjectManagerBase.
localIndex size() const
Get the "size" of the group, which determines the number of elements in resizable wrappers.
Runge-Kutta method used to time integrate slip and state. Uses of a high order update used to integra...
GEOS_HOST_DEVICE real64 computeError(real64 const highOrderApprox, real64 const lowOrderApprox, real64 const absTol, real64 const relTol) const
Computes the relative error scaled by error tolerances.
GEOS_HOST_DEVICE void updateSolutionAndLocalErrorFSAL(localIndex const k, real64 const dt, real64 const absTol, real64 const relTol) const
Updates slip, state and displacement jump to the next time computes error the local error in the time...
GEOS_HOST_DEVICE void updateStageRatesFSAL(localIndex const k) const
Re-uses the last stage rate from the previous time step as the first in the next update....
GEOS_HOST_DEVICE void updateStageRates(localIndex const k, integer const stageIndex) const
Updates the stage rates rates (the right-hand-side of the ODEs for slip and state)
GEOS_HOST_DEVICE void updateSolutionAndLocalError(localIndex const k, real64 const dt, real64 const absTol, real64 const relTol) const
Updates slip, state and displacement jump to the next time computes error the local error in the time...
GEOS_HOST_DEVICE void initialize(localIndex const k) const
Initialize slip and state buffers.
GEOS_HOST_DEVICE void updateStageValues(localIndex const k, integer const stageIndex, real64 const dt) const
Update stage values (slip, state and displacement jump) to a Runge-Kutta substage.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
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.
ArrayView< T, 3, USD > arrayView3d
Alias for 3D array view.
Butcher table for the BogackiShampine 3(2) method.
Butcher table for embedded RK3(2) method using Kuttas third order method for the high-order update,...