GEOS
FixedStressThermoPoromechanics_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 Total, S.A
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_SOLIDMECHANICS_KERNELS_FIXEDSTRESSTHERMOPOROMECHANICS_IMPL_HPP_
21 #define GEOS_PHYSICSSOLVERS_SOLIDMECHANICS_KERNELS_FIXEDSTRESSTHERMOPOROMECHANICS_IMPL_HPP_
22 
27 
28 namespace geos
29 {
30 
31 namespace solidMechanicsLagrangianFEMKernels
32 {
33 
34 template< typename SUBREGION_TYPE,
35  typename CONSTITUTIVE_TYPE,
36  typename FE_TYPE >
37 
39 FixedStressThermoPoromechanics( NodeManager const & nodeManager,
40  EdgeManager const & edgeManager,
41  FaceManager const & faceManager,
42  localIndex const targetRegionIndex,
43  SUBREGION_TYPE const & elementSubRegion,
44  FE_TYPE const & finiteElementSpace,
45  CONSTITUTIVE_TYPE & inputConstitutiveType,
46  arrayView1d< globalIndex const > const inputDofNumber,
47  globalIndex const rankOffset,
49  arrayView1d< real64 > const inputRhs,
50  real64 const inputDt,
51  real64 const (&inputGravityVector)[3] ):
52  Base( nodeManager,
53  edgeManager,
54  faceManager,
55  targetRegionIndex,
56  elementSubRegion,
57  finiteElementSpace,
58  inputConstitutiveType,
59  inputDofNumber,
60  rankOffset,
61  inputMatrix,
62  inputRhs,
63  inputDt ),
64  m_X( nodeManager.referencePosition()),
65  m_disp( nodeManager.getField< fields::solidMechanics::totalDisplacement >() ),
66  m_uhat( nodeManager.getField< fields::solidMechanics::incrementalDisplacement >() ),
67  m_gravityVector{ inputGravityVector[0], inputGravityVector[1], inputGravityVector[2] },
68  m_bulkDensity( elementSubRegion.template getField< fields::poromechanics::bulkDensity >() ),
69  m_pressure( elementSubRegion.template getField< fields::flow::pressure >() ),
70  m_pressure_n( elementSubRegion.template getField< fields::flow::pressure_n >() ),
71  m_initialTemperature( elementSubRegion.template getField< fields::flow::initialTemperature >() ),
72  m_temperature( elementSubRegion.template getField< fields::flow::temperature >() ),
73  m_temperature_n( elementSubRegion.template getField< fields::flow::temperature_n >() )
74 {}
75 
76 template< typename SUBREGION_TYPE,
77  typename CONSTITUTIVE_TYPE,
78  typename FE_TYPE >
82 setup( localIndex const k,
83  StackVariables & stack ) const
84 {
85  m_finiteElementSpace.template setup< FE_TYPE >( k, m_meshData, stack.feStack );
86  localIndex const numSupportPoints =
87  m_finiteElementSpace.template numSupportPoints< FE_TYPE >( stack.feStack );
88  stack.numRows = 3 * numSupportPoints;
89  stack.numCols = stack.numRows;
90 
91  for( localIndex a = 0; a < numSupportPoints; ++a )
92  {
93  localIndex const localNodeIndex = m_elemsToNodes( k, a );
94 
95  for( int i = 0; i < 3; ++i )
96  {
97 #if defined(CALC_FEM_SHAPE_IN_KERNEL)
98  stack.xLocal[ a ][ i ] = m_X[ localNodeIndex ][ i ];
99 #endif
100  stack.u_local[ a ][i] = m_disp[ localNodeIndex ][i];
101  stack.uhat_local[ a ][i] = m_uhat[ localNodeIndex ][i];
102  stack.localRowDofIndex[a*3+i] = m_dofNumber[localNodeIndex]+i;
103  stack.localColDofIndex[a*3+i] = m_dofNumber[localNodeIndex]+i;
104  }
105  }
106 
107  // Add stabilization to block diagonal parts of the local jacobian
108  // (this is a no-operation with FEM classes)
109  real64 const stabilizationScaling = computeStabilizationScaling( k );
110  m_finiteElementSpace.template addGradGradStabilizationMatrix
111  < FE_TYPE, numDofPerTrialSupportPoint, true >( stack.feStack,
112  stack.localJacobian,
113  -stabilizationScaling );
114 }
115 
116 template< typename SUBREGION_TYPE,
117  typename CONSTITUTIVE_TYPE,
118  typename FE_TYPE >
123  localIndex const q,
124  StackVariables & stack ) const
125 {
126  real64 dNdX[ numNodesPerElem ][ 3 ];
127  real64 const detJxW = m_finiteElementSpace.template getGradN< FE_TYPE >( k, q, stack.xLocal,
128  stack.feStack, dNdX );
129 
130  real64 strainInc[6] = {0};
131  real64 totalStress[6] = {0};
132 
133  typename CONSTITUTIVE_TYPE::KernelWrapper::DiscretizationOps stiffness;
134 
135  FE_TYPE::symmetricGradient( dNdX, stack.uhat_local, strainInc );
136 
137  // Evaluate total stress and its derivatives
138  // TODO: allow for a customization of the kernel to pass the average pressure to the small strain update (to account for cap pressure
139  // later)
140  m_constitutiveUpdate.smallStrainUpdatePoromechanicsFixedStress( k, q,
141  m_dt,
142  m_pressure[k],
143  m_pressure_n[k],
144  m_temperature[k],
145  m_temperature_n[k],
146  strainInc,
147  totalStress,
148  stiffness );
149 
150  for( localIndex i=0; i<6; ++i )
151  {
152  totalStress[i] *= -detJxW;
153  }
154 
155  // Here we consider the bodyForce is purely from the solid
156  // Warning: here, we lag (in iteration) the displacement dependence of bulkDensity
157  real64 const gravityForce[3] = { m_gravityVector[0] * m_bulkDensity( k, q )* detJxW,
158  m_gravityVector[1] * m_bulkDensity( k, q )* detJxW,
159  m_gravityVector[2] * m_bulkDensity( k, q )* detJxW };
160 
161  real64 N[numNodesPerElem];
162  FE_TYPE::calcN( q, stack.feStack, N );
163  FE_TYPE::plusGradNajAijPlusNaFi( dNdX,
164  totalStress,
165  N,
166  gravityForce,
167  reinterpret_cast< real64 (&)[numNodesPerElem][3] >(stack.localResidual) );
168  real64 const stabilizationScaling = computeStabilizationScaling( k );
169  m_finiteElementSpace.template
170  addEvaluatedGradGradStabilizationVector< FE_TYPE,
171  numDofPerTrialSupportPoint >( stack.feStack,
172  stack.uhat_local,
173  reinterpret_cast< real64 (&)[numNodesPerElem][3] >(stack.localResidual),
174  -stabilizationScaling );
175  stiffness.template upperBTDB< numNodesPerElem >( dNdX, -detJxW, stack.localJacobian );
176 }
177 
178 template< typename SUBREGION_TYPE,
179  typename CONSTITUTIVE_TYPE,
180  typename FE_TYPE >
184 complete( localIndex const k,
185  StackVariables & stack ) const
186 {
187  GEOS_UNUSED_VAR( k );
188  real64 maxForce = 0;
189 
190  // TODO: Does this work if BTDB is non-symmetric?
191  CONSTITUTIVE_TYPE::KernelWrapper::DiscretizationOps::template fillLowerBTDB< numNodesPerElem >( stack.localJacobian );
192  localIndex const numSupportPoints =
193  m_finiteElementSpace.template numSupportPoints< FE_TYPE >( stack.feStack );
194  for( int localNode = 0; localNode < numSupportPoints; ++localNode )
195  {
196  for( int dim = 0; dim < numDofPerTestSupportPoint; ++dim )
197  {
198  localIndex const dof =
199  LvArray::integerConversion< localIndex >( stack.localRowDofIndex[ numDofPerTestSupportPoint * localNode + dim ] - m_dofRankOffset );
200  if( dof < 0 || dof >= m_matrix.numRows() )
201  continue;
202  m_matrix.template addToRowBinarySearchUnsorted< parallelDeviceAtomic >( dof,
203  stack.localRowDofIndex,
204  stack.localJacobian[ numDofPerTestSupportPoint * localNode + dim ],
205  stack.numRows );
206 
207  RAJA::atomicAdd< parallelDeviceAtomic >( &m_rhs[ dof ], stack.localResidual[ numDofPerTestSupportPoint * localNode + dim ] );
208  maxForce = fmax( maxForce, fabs( stack.localResidual[ numDofPerTestSupportPoint * localNode + dim ] ) );
209  }
210  }
211  return maxForce;
212 }
213 
214 template< typename SUBREGION_TYPE,
215  typename CONSTITUTIVE_TYPE,
216  typename FE_TYPE >
217 template< typename POLICY,
218  typename KERNEL_TYPE >
219 real64
221  KERNEL_TYPE const & kernelComponent )
222 {
223  return Base::template kernelLaunch< POLICY, KERNEL_TYPE >( numElems, kernelComponent );
224 }
225 
226 } // namespace solidMechanicsLagrangianFEMKernels
227 
228 } // namespace geos
229 
230 #endif // GEOS_PHYSICSSOLVERS_SOLIDMECHANICS_KERNELS_FIXEDSTRESSTHERMOPOROMECHANICS_IMPL_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_FORCE_INLINE
Marks a function or lambda for inlining.
Definition: GeosxMacros.hpp:51
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
static real64 kernelLaunch(localIndex const numElems, KERNEL_TYPE const &kernelComponent)
Kernel Launcher.
GEOS_HOST_DEVICE void setup(localIndex const k, StackVariables &stack) const
Copy global values from primary field to a local stack array.
GEOS_HOST_DEVICE GEOS_FORCE_INLINE real64 complete(localIndex const k, StackVariables &stack) const
Performs the complete phase for the kernel.
FixedStressThermoPoromechanics(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 inputDofNumber, globalIndex const rankOffset, CRSMatrixView< real64, globalIndex const > const inputMatrix, arrayView1d< real64 > const inputRhs, real64 const inputDt, real64 const (&inputGravityVector)[3])
Constructor.
GEOS_HOST_DEVICE void quadraturePointKernel(localIndex const k, localIndex const q, StackVariables &stack) const
Performs a state update at a quadrature point.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Definition: DataTypes.hpp:180
LvArray::CRSMatrixView< T, COL_INDEX, localIndex const, LvArray::ChaiBuffer > CRSMatrixView
Alias for CRS Matrix View.
Definition: DataTypes.hpp:310
GEOS_GLOBALINDEX_TYPE globalIndex
Global index type (for indexing objects across MPI partitions).
Definition: DataTypes.hpp:88
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
real64 u_local[numNodesPerElem][numDofPerTrialSupportPoint]
Stack storage for the element local nodal displacement.
real64 uhat_local[numNodesPerElem][numDofPerTrialSupportPoint]
Stack storage for the element local nodal incremental displacement.