GEOS
SinglePhasePoromechanicsDamage_impl.hpp
Go to the documentation of this file.
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) 2023-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 
20 #ifndef GEOS_PHYSICSSOLVERS_MULTIPHYSICS_SINGLEPHASEPOROMECHANICSDAMAGE_IMPL_HPP_
21 #define GEOS_PHYSICSSOLVERS_MULTIPHYSICS_SINGLEPHASEPOROMECHANICSDAMAGE_IMPL_HPP_
22 
23 #include "physicsSolvers/multiphysics/poromechanicsKernels/SinglePhasePoromechanicsDamage.hpp"
24 
25 namespace geos
26 {
27 
28 namespace poromechanicsDamageKernels
29 {
30 
31 template< typename SUBREGION_TYPE,
32  typename CONSTITUTIVE_TYPE,
33  typename FE_TYPE >
35 SinglePhasePoromechanicsDamage( NodeManager const & nodeManager,
36  EdgeManager const & edgeManager,
37  FaceManager const & faceManager,
38  localIndex const targetRegionIndex,
39  SUBREGION_TYPE const & elementSubRegion,
40  FE_TYPE const & finiteElementSpace,
41  CONSTITUTIVE_TYPE & inputConstitutiveType,
42  arrayView1d< globalIndex const > const inputDispDofNumber,
43  globalIndex const rankOffset,
45  arrayView1d< real64 > const inputRhs,
46  real64 const inputDt,
47  real64 const (&gravityVector)[3],
48  string const inputFlowDofKey,
49  integer const performStressInitialization,
50  string const fluidModelKey ):
51  Base( nodeManager,
52  edgeManager,
53  faceManager,
54  targetRegionIndex,
55  elementSubRegion,
56  finiteElementSpace,
57  inputConstitutiveType,
58  inputDispDofNumber,
59  rankOffset,
60  inputMatrix,
61  inputRhs,
62  inputDt,
63  gravityVector,
64  inputFlowDofKey,
65  performStressInitialization,
66  fluidModelKey ),
67  m_fluidPressureGradient( elementSubRegion.template getReference< array2d< real64 > >( "pressureGradient" ) )
68 {}
69 
70 template< typename SUBREGION_TYPE,
71  typename CONSTITUTIVE_TYPE,
72  typename FE_TYPE >
77  localIndex const q,
78  StackVariables & stack ) const
79 {
80  real64 porosity = 0.0;
81  real64 porosity_n = 0.0;
82  real64 dPorosity_dVolStrain = 0.0;
83  real64 dPorosity_dPressure = 0.0;
84  real64 dPorosity_dTemperature = 0.0;
85  real64 dSolidDensity_dPressure = 0.0;
86 
87  real64 fluidPressureGradient[3]{};
88 
89  for( integer i=0; i<3; ++i )
90  {
91  fluidPressureGradient[i] = m_fluidPressureGradient( k, i );
92  }
93 
94  // Step 1: call the constitutive model to evaluate the total stress and compute porosity
95  m_constitutiveUpdate.smallStrainUpdatePoromechanics( k, q,
96  m_dt,
97  m_pressure_n[k],
98  m_pressure[k],
99  stack.temperature,
101  stack.strainIncrement,
102  stack.totalStress,
105  stack.stiffness,
106  m_performStressInitialization,
107  porosity,
108  porosity_n,
109  dPorosity_dVolStrain,
110  dPorosity_dPressure,
111  dPorosity_dTemperature,
112  dSolidDensity_dPressure );
113 
114  // Step 2: compute fracture flow term and its derivative w.r.t pressure
115  m_constitutiveUpdate.computeFractureFlowTerm( k, q,
116  fluidPressureGradient,
117  stack.fractureFlowTerm,
119 
120  // Step 3: compute the body force
121  Base::computeBodyForce( k, q,
122  porosity,
123  dPorosity_dVolStrain,
124  dPorosity_dPressure,
125  dPorosity_dTemperature,
126  dSolidDensity_dPressure,
127  stack );
128 
129  // Step 3: compute fluid mass increment
130  Base::computeFluidIncrement( k, q,
131  porosity,
132  porosity_n,
133  dPorosity_dVolStrain,
134  dPorosity_dPressure,
135  dPorosity_dTemperature,
136  stack );
137 }
138 
139 template< typename SUBREGION_TYPE,
140  typename CONSTITUTIVE_TYPE,
141  typename FE_TYPE >
145 assembleMomentumBalanceTerms( real64 const ( &N )[numNodesPerElem],
146  real64 const ( &dNdX )[numNodesPerElem][3],
147  real64 const & detJxW,
148  StackVariables & stack ) const
149 {
150  using namespace PDEUtilities;
151 
152  constexpr FunctionSpace displacementTrialSpace = FE_TYPE::template getFunctionSpace< numDofPerTrialSupportPoint >();
153  constexpr FunctionSpace displacementTestSpace = displacementTrialSpace;
154  constexpr FunctionSpace pressureTrialSpace = FunctionSpace::P0;
155 
156  // Step 1: compute local linear momentum balance residual
157  LinearFormUtilities::compute< displacementTestSpace,
158  DifferentialOperator::SymmetricGradient >
159  (
160  stack.localResidualMomentum,
161  dNdX,
162  stack.totalStress,
163  -detJxW );
164 
165  if( m_gravityAcceleration > 0.0 )
166  {
167  LinearFormUtilities::compute< displacementTestSpace,
168  DifferentialOperator::Identity >
169  (
170  stack.localResidualMomentum,
171  N,
172  stack.bodyForce,
173  detJxW );
174  }
175 
176  LinearFormUtilities::compute< displacementTestSpace,
177  DifferentialOperator::Identity >
178  (
179  stack.localResidualMomentum,
180  N,
181  stack.fractureFlowTerm,
182  detJxW );
183 
184  // Step 2: compute local linear momentum balance residual derivatives with respect to displacement
185  BilinearFormUtilities::compute< displacementTestSpace,
186  displacementTrialSpace,
187  DifferentialOperator::SymmetricGradient,
188  DifferentialOperator::SymmetricGradient >
189  (
191  dNdX,
192  stack.stiffness, // fourth-order tensor handled via DiscretizationOps
193  dNdX,
194  -detJxW );
195 
196  if( m_gravityAcceleration > 0.0 )
197  {
198  BilinearFormUtilities::compute< displacementTestSpace,
199  displacementTrialSpace,
200  DifferentialOperator::Identity,
201  DifferentialOperator::Divergence >
202  (
204  N,
206  dNdX,
207  detJxW );
208  }
209 
210  // Step 3: compute local linear momentum balance residual derivatives with respect to pressure
211  BilinearFormUtilities::compute< displacementTestSpace,
212  pressureTrialSpace,
213  DifferentialOperator::SymmetricGradient,
214  DifferentialOperator::Identity >
215  (
217  dNdX,
219  1.0,
220  -detJxW );
221 
222  if( m_gravityAcceleration > 0.0 )
223  {
224  BilinearFormUtilities::compute< displacementTestSpace,
225  pressureTrialSpace,
226  DifferentialOperator::Identity,
227  DifferentialOperator::Identity >
228  (
230  N,
231  stack.dBodyForce_dPressure,
232  1.0,
233  detJxW );
234  }
235 
236  BilinearFormUtilities::compute< displacementTestSpace,
237  pressureTrialSpace,
238  DifferentialOperator::Identity,
239  DifferentialOperator::Identity >
240  (
242  N,
244  1.0,
245  detJxW );
246 }
247 
248 template< typename SUBREGION_TYPE,
249  typename CONSTITUTIVE_TYPE,
250  typename FE_TYPE >
255  localIndex const q,
256  StackVariables & stack ) const
257 {
258  // Step 1: compute displacement finite element basis functions (N), basis function derivatives (dNdX), and
259  // determinant of the Jacobian transformation matrix times the quadrature weight (detJxW)
260  real64 N[numNodesPerElem]{};
261  real64 dNdX[numNodesPerElem][3]{};
262  FE_TYPE::calcN( q, stack.feStack, N );
263  real64 const detJxW = m_finiteElementSpace.template getGradN< FE_TYPE >( k, q, stack.xLocal,
264  stack.feStack, dNdX );
265 
266  // Step 2: compute strain increment
267  LvArray::tensorOps::fill< 6 >( stack.strainIncrement, 0.0 );
268  FE_TYPE::symmetricGradient( dNdX, stack.uhat_local, stack.strainIncrement );
269 
270  // Step 3: compute 1) the total stress, 2) the body force terms, and 3) the fluidMassIncrement
271  // using quantities returned by the PorousSolid constitutive model.
272  // This function also computes the derivatives of these three quantities wrt primary variables
273  smallStrainUpdate( k, q, stack );
274 
275  // Step 4: use the total stress and the body force to increment the local momentum balance residual
276  // This function also fills the local Jacobian rows corresponding to the momentum balance.
277  assembleMomentumBalanceTerms( N, dNdX, detJxW, stack );
278 
279  // Step 5: use the fluid mass increment to increment the local mass balance residual
280  // This function also fills the local Jacobian rows corresponding to the mass balance.
281  Base::assembleElementBasedFlowTerms( dNdX, detJxW, stack );
282 }
283 
284 template< typename SUBREGION_TYPE,
285  typename CONSTITUTIVE_TYPE,
286  typename FE_TYPE >
290 complete( localIndex const k,
291  StackVariables & stack ) const
292 {
293  real64 const maxForce = Base::complete( k, stack );
294 
295  return maxForce;
296 }
297 
298 template< typename SUBREGION_TYPE,
299  typename CONSTITUTIVE_TYPE,
300  typename FE_TYPE >
301 template< typename POLICY,
302  typename KERNEL_TYPE >
304 kernelLaunch( localIndex const numElems,
305  KERNEL_TYPE const & kernelComponent )
306 {
308 
309  // Define a RAJA reduction variable to get the maximum residual contribution.
310  RAJA::ReduceMax< ReducePolicy< POLICY >, real64 > maxResidual( 0 );
311 
312  forAll< POLICY >( numElems,
313  [=] GEOS_HOST_DEVICE ( localIndex const k )
314  {
315  typename KERNEL_TYPE::StackVariables stack;
316 
317  kernelComponent.setup( k, stack );
318  for( integer q=0; q<KERNEL_TYPE::numQuadraturePointsPerElem; ++q )
319  {
320  kernelComponent.quadraturePointKernel( k, q, stack );
321  }
322  maxResidual.max( kernelComponent.complete( k, stack ) );
323  } );
324  return maxResidual.get();
325 }
326 
327 } // namespace poromechanicsDamageKernels
328 
329 } // namespace geos
330 
331 #endif // GEOS_PHYSICSSOLVERS_MULTIPHYSICS_SINGLEPHASEPOROMECHANICSDAMAGE_IMPL_HPP_
#define GEOS_HOST_DEVICE
Marks a host-device function.
Definition: GeosxMacros.hpp:49
#define GEOS_FORCE_INLINE
Marks a function or lambda for inlining.
Definition: GeosxMacros.hpp:51
#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.
Definition: EdgeManager.hpp:43
The FaceManager class provides an interface to ObjectManagerBase in order to manage face data.
Definition: FaceManager.hpp:44
The NodeManager class provides an interface to ObjectManagerBase in order to manage node data.
Definition: NodeManager.hpp:46
Implements kernels for solving quasi-static single-phase poromechanics with phase-field damage.
static real64 kernelLaunch(localIndex const numElems, KERNEL_TYPE const &kernelComponent)
GEOS_HOST_DEVICE void smallStrainUpdate(localIndex const k, localIndex const q, StackVariables &stack) const
Helper function to compute 1) the total stress, 2) the body force term, and 3) the fluidMassIncrement...
GEOS_HOST_DEVICE void assembleMomentumBalanceTerms(real64 const (&N)[numNodesPerElem], real64 const (&dNdX)[numNodesPerElem][3], real64 const &detJxW, StackVariables &stack) const
Assemble the local linear momentum balance residual and derivatives using total stress and body force...
GEOS_HOST_DEVICE real64 complete(localIndex const k, StackVariables &stack) const
SinglePhasePoromechanicsDamage(NodeManager const &nodeManager, EdgeManager const &edgeManager, FaceManager const &faceManager, localIndex const targetRegionIndex, SUBREGION_TYPE const &elementSubRegion, FE_TYPE const &finiteElementSpace, CONSTITUTIVE_TYPE &inputConstitutiveType, arrayView1d< globalIndex const > const inputDispDofNumber, globalIndex const rankOffset, CRSMatrixView< real64, globalIndex const > const inputMatrix, arrayView1d< real64 > const inputRhs, real64 const inputDt, real64 const (&gravityVector)[3], string const inputFlowDofKey, integer const performStressInitialization, string const fluidModelKey)
Constructor.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Definition: DataTypes.hpp:188
Array< T, 2, PERMUTATION > array2d
Alias for 2D array.
Definition: DataTypes.hpp:200
LvArray::CRSMatrixView< T, COL_INDEX, localIndex const, LvArray::ChaiBuffer > CRSMatrixView
Alias for CRS Matrix View.
Definition: DataTypes.hpp:318
GEOS_GLOBALINDEX_TYPE globalIndex
Global index type (for indexing objects across MPI partitions).
Definition: DataTypes.hpp:87
double real64
64-bit floating point type.
Definition: DataTypes.hpp:98
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:84
std::int32_t integer
Signed integer type.
Definition: DataTypes.hpp:81
real64 dFractureFlowTerm_dPressure[3]
Derivative of the fracture flow term wrt pressure.
real64(& dLocalResidualMomentum_dDisplacement)[numDispDofPerElem][numDispDofPerElem]
Derivative of linear momentum balance residual wrt displacement.
real64 dBodyForce_dPressure[3]
Derivative of body force wrt pressure.
real64 dTotalStress_dTemperature[6]
Derivative of total stress wrt temperature.
CONSTITUTIVE_TYPE::KernelWrapper::DiscretizationOps stiffness
Derivative of total stress wrt displacement.
real64 dLocalResidualMomentum_dPressure[numDispDofPerElem][1]
Derivative of linear momentum balance residual wrt pressure.
real64 dTotalStress_dPressure[6]
Derivative of total stress wrt pressure.
real64 dBodyForce_dVolStrainIncrement[3]
Derivative of body force wrt volumetric strain increment.
real64(& localResidualMomentum)[numDispDofPerElem]
Linear momentum balance residual.
real64 deltaTemperatureFromLastStep
Delta temperature since last time step.