GEOS
surfaceGenerationKernels.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 #include "common/DataTypes.hpp"
21 #include "common/TimingMacros.hpp"
22 #include "constitutive/solid/CoupledSolidBase.hpp"
23 #include "constitutive/solid/SolidBase.hpp"
24 #include "constitutive/solid/SolidFields.hpp"
25 
26 #include "constitutive/ConstitutiveManager.hpp"
29 
30 namespace geos
31 {
32 
33 namespace surfaceGenerationKernels
34 {
35 
37 {
38 
39 public:
40 
41  NodalForceKernel( ElementRegionManager const & elemManager,
42  constitutive::ConstitutiveManager const & constitutiveManager,
43  string const solidMaterialKey ):
44  m_elementRegionManager( elemManager ),
45  m_bulkModulus( elemManager.constructFullMaterialViewAccessor< array1d< real64 >, arrayView1d< real64 const > >( "bulkModulus", constitutiveManager ) ),
46  m_shearModulus( elemManager.constructFullMaterialViewAccessor< array1d< real64 >, arrayView1d< real64 const > >( "shearModulus", constitutiveManager ) ),
48  arrayView3d< real64 const, geos::solid::STRESS_USD > >( fields::solid::stress::key(),
49  constitutiveManager ) )
50  {
51  m_solidMaterialFullIndex.resize( elemManager.numRegions() );
52  elemManager.forElementRegionsComplete< CellElementRegion >( [&]( localIndex regionIndex,
53  CellElementRegion const & region )
54  {
55  string const & solidMaterialName = region.getSubRegion( 0 ).getReference< string >( solidMaterialKey );
56  constitutive::ConstitutiveBase const & solid = constitutiveManager.getConstitutiveRelation< constitutive::ConstitutiveBase >( solidMaterialName );
57  m_solidMaterialFullIndex[regionIndex] = solid.getIndexInParent();
58  } );
59  }
60 
61  virtual void
62  calculateSingleNodalForce( localIndex const er,
63  localIndex const esr,
64  localIndex const ei,
65  localIndex const targetNode,
66  real64 ( & force )[ 3 ] ) const
67  {
69 
70  NodeManager const & nodeManager = m_elementRegionManager.getParent().template getGroup< NodeManager >( MeshLevel::groupStructKeys::nodeManagerString() );
72 
73  CellElementRegion const & region = m_elementRegionManager.getRegion< CellElementRegion >( er );
74  CellElementSubRegion const & subRegion = region.getSubRegion< CellElementSubRegion >( esr );
75  CellElementSubRegion::NodeMapType const & toNodesRelation = subRegion.nodeList();
76 
77  // ASSUMPTION(?): subregions only have one registered element type
79  subRegion.forWrappers< finiteElement::FiniteElementBase >( [&]( auto const & fe )
80  {
81  finiteElement = &fe.reference();
82  } );
83 
84  finiteElement::FiniteElementDispatchHandler< ALL_FE_TYPES >::dispatch3D( *finiteElement, [ & ]( auto const & fe )
85  {
86  using FE_TYPE = TYPEOFREF( fe );
87  typename FE_TYPE::StackVariables feStack;
88  constexpr localIndex numQuadraturePoints = FE_TYPE::numQuadraturePoints;
89  constexpr localIndex numNodesPerElement = FE_TYPE::numNodes;
90  real64 xLocal[numNodesPerElement][3] = { { 0 } };
91 
92  localIndex const numSupportPoints = finiteElement->getNumSupportPoints( );
93  for( localIndex a = 0; a < numSupportPoints; ++a )
94  {
95  LvArray::tensorOps::copy< 3 >( xLocal[a], X[toNodesRelation( ei, a )] );
96  }
97 
98  for( localIndex q = 0; q < numQuadraturePoints; ++q )
99  {
100  real64 const quadratureStress[6] = LVARRAY_TENSOROPS_INIT_LOCAL_6 ( m_stress[er][esr][m_solidMaterialFullIndex[er]][ei][q] );
101  real64 dNdX[numNodesPerElement][3] = {{0}};
102  real64 J[3][3] = {{0}};
103  real64 const detJxW = FE_TYPE::calcJacobian( q, xLocal, feStack, J );
104  FE_TYPE::calcGradN( q, xLocal, feStack, dNdX );
105  surfaceGenerationKernelsHelpers::computeNodalForce( quadratureStress, dNdX[targetNode], detJxW, force );
106  }
107  } );
108 
109  //wu40: the nodal force need to be weighted by Young's modulus and possion's ratio.
110  surfaceGenerationKernelsHelpers::scaleNodalForce( m_bulkModulus[er][esr][m_solidMaterialFullIndex[er]][ei], m_shearModulus[er][esr][m_solidMaterialFullIndex[er]][ei], force );
111  }
112 
113 protected:
114 
115  ElementRegionManager const & m_elementRegionManager;
116 
118 
120 
122 
123  array1d< integer > m_solidMaterialFullIndex;
124 };
125 
126 
128 {
129 
130 public:
132  constitutive::ConstitutiveManager const & constitutiveManager,
133  string const solidMaterialKey,
134  string const porosityModelKey ):
135  NodalForceKernel( elemManager, constitutiveManager, solidMaterialKey ),
136  m_pressure( elemManager.constructArrayViewAccessor< real64, 1 >( fields::flow::pressure::key() ) ),
137  m_biotCoefficient( elemManager.constructFullMaterialViewAccessor< array1d< real64 >, arrayView1d< real64 const > >( "biotCoefficient", constitutiveManager ) )
138  {
139  m_porosityMaterialFullIndex.resize( elemManager.numRegions() );
140  elemManager.forElementRegionsComplete< CellElementRegion >( [&]( localIndex regionIndex,
141  CellElementRegion const & region )
142  {
143  string const & porosityModelName = region.getSubRegion( 0 ).getReference< string >( porosityModelKey );
144  constitutive::ConstitutiveBase const & porosityModel = constitutiveManager.getConstitutiveRelation< constitutive::ConstitutiveBase >( porosityModelName );
145  m_porosityMaterialFullIndex[regionIndex] = porosityModel.getIndexInParent();
146  } );
147 
148  }
149 
150  void
152  localIndex const esr,
153  localIndex const ei,
154  localIndex const targetNode,
155  real64 ( & force )[ 3 ] ) const override
156 
157  {
159 
160  NodeManager const & nodeManager = m_elementRegionManager.getParent().template getGroup< NodeManager >( MeshLevel::groupStructKeys::nodeManagerString() );
162 
163  CellElementRegion const & region = m_elementRegionManager.getRegion< CellElementRegion >( er );
164  CellElementSubRegion const & subRegion = region.getSubRegion< CellElementSubRegion >( esr );
165  CellElementSubRegion::NodeMapType const & toNodesRelation = subRegion.nodeList();
166 
167  // ASSUMPTION(?): subregions only have one registered element type
169  subRegion.forWrappers< finiteElement::FiniteElementBase >( [&]( auto const & fe )
170  {
171  finiteElement = &fe.reference();
172  } );
173 
174  finiteElement::FiniteElementDispatchHandler< ALL_FE_TYPES >::dispatch3D( *finiteElement, [ & ]( auto const & fe )
175  {
176  using FE_TYPE = TYPEOFREF( fe );
177  typename FE_TYPE::StackVariables feStack;
178  constexpr localIndex numQuadraturePoints = FE_TYPE::numQuadraturePoints;
179  constexpr localIndex numNodesPerElement = FE_TYPE::numNodes;
180  real64 xLocal[numNodesPerElement][3] = {{0}};
181 
182  localIndex const numSupportPoints = finiteElement->getNumSupportPoints( );
183  for( localIndex a = 0; a < numSupportPoints; ++a )
184  {
185  LvArray::tensorOps::copy< 3 >( xLocal[a], X[toNodesRelation( ei, a )] );
186  }
187 
188  for( localIndex q = 0; q < numQuadraturePoints; ++q )
189  {
190  real64 totalStress[6] = LVARRAY_TENSOROPS_INIT_LOCAL_6 ( m_stress[er][esr][m_solidMaterialFullIndex[er]][ei][q] );
192  LvArray::tensorOps::symAddIdentity< 3 >( totalStress, -m_biotCoefficient[er][esr][m_porosityMaterialFullIndex[er]][ei] * m_pressure[er][esr][ei] );
193 
194  real64 dNdX[numNodesPerElement][3] = {{0}};
195  real64 J[3][3] = {{0}};
196  real64 const detJxW = FE_TYPE::calcJacobian( q, xLocal, feStack, J );
197  FE_TYPE::calcGradN( q, xLocal, feStack, dNdX );
198  surfaceGenerationKernelsHelpers::computeNodalForce( totalStress, dNdX[targetNode], detJxW, force );
199  }
200  } );
201 
202  //wu40: the nodal force need to be weighted by Young's modulus and possion's ratio.
203  surfaceGenerationKernelsHelpers::scaleNodalForce( m_bulkModulus[er][esr][m_solidMaterialFullIndex[er]][ei], m_shearModulus[er][esr][m_solidMaterialFullIndex[er]][ei], force );
204  }
205 
206 private:
207 
209 
211 
212  array1d< integer > m_porosityMaterialFullIndex;
213 
214 };
215 
216 template< typename LAMBDA >
217 void kernelSelector( ElementRegionManager const & elemManager,
218  constitutive::ConstitutiveManager const & constitutiveManager,
219  string const solidMaterialKey,
220  integer const isPoroelastic,
221  LAMBDA && lambda )
222 {
223  if( isPoroelastic == 0 )
224  {
225  lambda( NodalForceKernel( elemManager, constitutiveManager, solidMaterialKey ) );
226  }
227  else
228  {
229  string const porosityModelKey = constitutive::CoupledSolidBase::viewKeyStruct::porosityModelNameString();
230  lambda( PoroElasticNodalForceKernel( elemManager, constitutiveManager, solidMaterialKey, porosityModelKey ) );
231  }
232 
233 }
234 
235 } // namespace solidMechanicsLagrangianFEMKernels
236 
237 } // namespace geos
#define GEOS_MARK_FUNCTION
Mark function with both Caliper and NVTX if enabled.
SUBREGIONTYPE const & getSubRegion(KEY_TYPE const &key) const
Get a reference to a subregion.
The ElementRegionManager class provides an interface to ObjectManagerBase in order to manage ElementR...
MaterialViewAccessor< LHS > constructFullMaterialViewAccessor(string const &viewName, constitutive::ConstitutiveManager const &cm) const
This is a const function to construct a MaterialViewAccessor to access the material data.
localIndex numRegions() const
Get number of the regions.
void forElementRegionsComplete(LAMBDA lambda) const
This const function is used to launch kernel function over all the types of element regions.
ElementViewAccessor< ArrayView< T const, NDIM, getUSD< PERM > > > constructArrayViewAccessor(string const &name, string const &neighborName=string()) const
This is a function to construct a ElementViewAccessor to access array data registered on the mesh.
array1d< array1d< array1d< VIEWTYPE > > > MaterialViewAccessor
The MaterialViewAccessor at the ElementRegionManager level is a 3D array of VIEWTYPE.
array1d< array1d< VIEWTYPE > > ElementViewAccessor
The ElementViewAccessor at the ElementRegionManager level is an array of array of VIEWTYPE.
T const & getRegion(KEY_TYPE const &key) const
Get a element region.
The NodeManager class provides an interface to ObjectManagerBase in order to manage node data.
Definition: NodeManager.hpp:46
Group & getParent()
Access the group's parent.
Definition: Group.hpp:1362
Base class for FEM element implementations.
void calculateSingleNodalForce(localIndex const er, localIndex const esr, localIndex const ei, localIndex const targetNode, real64(&force)[3]) const override
array2d< real64, nodes::REFERENCE_POSITION_PERM > & referencePosition()
Get the mutable reference position array. This table will contain all the node coordinates.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Definition: DataTypes.hpp:179
Array< T, 3, PERMUTATION > array3d
Alias for 3D array.
Definition: DataTypes.hpp:207
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
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.
Definition: DataTypes.hpp:195
int integer
Signed integer type.
Definition: DataTypes.hpp:81
Array< T, 1 > array1d
Alias for 1D array.
Definition: DataTypes.hpp:175
ArrayView< T, 3, USD > arrayView3d
Alias for 3D array view.
Definition: DataTypes.hpp:211