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 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_SOLIDMECHANICS_KERNELS_FIXEDSTRESSTHERMOPOROMECHANICS_IMPL_HPP_
21 #define GEOS_PHYSICSSOLVERS_SOLIDMECHANICS_KERNELS_FIXEDSTRESSTHERMOPOROMECHANICS_IMPL_HPP_
22 
24 #include "finiteElement/elementFormulations/FiniteElementOperators.hpp"
28 
29 namespace geos
30 {
31 
32 namespace solidMechanicsLagrangianFEMKernels
33 {
34 
35 template< typename SUBREGION_TYPE,
36  typename CONSTITUTIVE_TYPE,
37  typename FE_TYPE >
38 
40 FixedStressThermoPoromechanics( NodeManager const & nodeManager,
41  EdgeManager const & edgeManager,
42  FaceManager const & faceManager,
43  localIndex const targetRegionIndex,
44  SUBREGION_TYPE const & elementSubRegion,
45  FE_TYPE const & finiteElementSpace,
46  CONSTITUTIVE_TYPE & inputConstitutiveType,
47  arrayView1d< globalIndex const > const inputDofNumber,
48  globalIndex const rankOffset,
50  arrayView1d< real64 > const inputRhs,
51  real64 const inputDt,
52  real64 const (&inputGravityVector)[3] ):
53  Base( nodeManager,
54  edgeManager,
55  faceManager,
56  targetRegionIndex,
57  elementSubRegion,
58  finiteElementSpace,
59  inputConstitutiveType,
60  inputDofNumber,
61  rankOffset,
62  inputMatrix,
63  inputRhs,
64  inputDt ),
65  m_X( nodeManager.referencePosition()),
66  m_disp( nodeManager.getField< fields::solidMechanics::totalDisplacement >() ),
67  m_uhat( nodeManager.getField< fields::solidMechanics::incrementalDisplacement >() ),
68  m_gravityVector{ inputGravityVector[0], inputGravityVector[1], inputGravityVector[2] },
69  m_bulkDensity( elementSubRegion.template getField< fields::poromechanics::bulkDensity >() ),
70  m_pressure( elementSubRegion.template getField< fields::flow::pressure >() ),
71  m_pressure_n( elementSubRegion.template getField< fields::flow::pressure_n >() ),
72  m_initialTemperature( elementSubRegion.template getField< fields::flow::initialTemperature >() ),
73  m_temperature( elementSubRegion.template getField< fields::flow::temperature >() ),
74  m_temperature_n( elementSubRegion.template getField< fields::flow::temperature_n >() )
75 {}
76 
77 template< typename SUBREGION_TYPE,
78  typename CONSTITUTIVE_TYPE,
79  typename FE_TYPE >
83 setup( localIndex const k,
84  StackVariables & stack ) const
85 {
86  m_finiteElementSpace.template setup< FE_TYPE >( k, m_meshData, stack.feStack );
87  localIndex const numSupportPoints =
88  m_finiteElementSpace.getNumSupportPoints( stack.feStack );
89  stack.numRows = 3 * numSupportPoints;
90  stack.numCols = stack.numRows;
91 
92  for( localIndex a = 0; a < numSupportPoints; ++a )
93  {
94  localIndex const localNodeIndex = m_elemsToNodes( k, a );
95 
96  for( int i = 0; i < 3; ++i )
97  {
98  stack.xLocal[ a ][ i ] = m_X[ localNodeIndex ][ i ];
99  stack.u_local[ a ][i] = m_disp[ localNodeIndex ][i];
100  stack.uhat_local[ a ][i] = m_uhat[ localNodeIndex ][i];
101  stack.localRowDofIndex[a*3+i] = m_dofNumber[localNodeIndex]+i;
102  stack.localColDofIndex[a*3+i] = m_dofNumber[localNodeIndex]+i;
103  }
104  }
105 
106  // Add stabilization to block diagonal parts of the local jacobian
107  // (this is a no-operation with FEM classes)
108  real64 const stabilizationScaling = computeStabilizationScaling( k );
109  m_finiteElementSpace.template addGradGradStabilizationMatrix
110  < FE_TYPE, numDofPerTrialSupportPoint, true >( stack.feStack,
111  stack.localJacobian,
112  -stabilizationScaling );
113 }
114 
115 template< typename SUBREGION_TYPE,
116  typename CONSTITUTIVE_TYPE,
117  typename FE_TYPE >
122  localIndex const q,
123  StackVariables & stack ) const
124 {
125  real64 dNdX[ numNodesPerElem ][ 3 ];
126  real64 const detJxW = FE_TYPE::calcGradN( q, stack.xLocal,
127  stack.feStack, dNdX );
128 
129  real64 strainInc[6] = {0};
130  real64 totalStress[6] = {0};
131 
132  typename CONSTITUTIVE_TYPE::KernelWrapper::DiscretizationOps stiffness;
133 
134  finiteElement::feOps::symmetricGradient( dNdX, stack.uhat_local, strainInc );
135 
136  // Evaluate total stress and its derivatives
137  // TODO: allow for a customization of the kernel to pass the average pressure to the small strain update (to account for cap pressure
138  // later)
139  m_constitutiveUpdate.smallStrainUpdatePoromechanicsFixedStress( k, q,
140  m_dt,
141  m_pressure[k],
142  m_pressure_n[k],
143  m_temperature[k],
144  m_temperature_n[k],
145  m_initialTemperature[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  finiteElement::feOps::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.getNumSupportPoints( 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:179
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
LvArray::CRSMatrixView< T, COL_INDEX, INDEX_TYPE const, LvArray::ChaiBuffer > CRSMatrixView
Alias for CRS Matrix View.
Definition: DataTypes.hpp:309
real64 xLocal[numNodesPerElem][3]
C-array stack storage for element local the nodal positions.
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.