GEOS
ThermalAccumulationKernels.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_FLUIDFLOW_SINGLEPHASE_THERMALACCUMULATIONKERNELS_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_THERMALACCUMULATIONKERNELS_HPP
22 
24 
25 namespace geos
26 {
27 
28 namespace thermalSinglePhaseBaseKernels
29 {
30 
31 /******************************** AccumulationKernel ********************************/
32 
37 template< typename SUBREGION_TYPE, integer NUM_DOF >
38 class AccumulationKernel : public singlePhaseBaseKernels::AccumulationKernel< SUBREGION_TYPE, NUM_DOF >
39 {
40 
41 public:
42 
44  using Base::numDof;
45  using Base::numEqn;
46  using Base::m_rankOffset;
47  using Base::m_dofNumber;
49  using Base::m_volume;
50  using Base::m_deltaVolume;
51  using Base::m_porosity;
52  using Base::m_dPoro_dPres;
53  using Base::m_density;
54  using Base::m_dDensity_dPres;
55  using Base::m_localMatrix;
56  using Base::m_localRhs;
57 
68  AccumulationKernel( globalIndex const rankOffset,
69  string const dofKey,
70  SUBREGION_TYPE const & subRegion,
71  constitutive::SingleFluidBase const & fluid,
72  constitutive::CoupledSolidBase const & solid,
74  arrayView1d< real64 > const & localRhs )
75  : Base( rankOffset, dofKey, subRegion, fluid, solid, localMatrix, localRhs ),
76  m_dDensity_dTemp( fluid.dDensity_dTemperature() ),
77  m_dPoro_dTemp( solid.getDporosity_dTemperature() ),
78  m_internalEnergy( fluid.internalEnergy() ),
79  m_dInternalEnergy_dPres( fluid.dInternalEnergy_dPressure() ),
80  m_dInternalEnergy_dTemp( fluid.dInternalEnergy_dTemperature() ),
81  m_rockInternalEnergy( solid.getInternalEnergy() ),
82  m_dRockInternalEnergy_dTemp( solid.getDinternalEnergy_dTemperature() ),
83  m_energy_n( subRegion.template getField< fields::flow::energy_n >() )
84  {}
85 
91  {
92 public:
93 
97  {}
98 
105 
108 
109  // Solid energy
110 
113 
116 
119  };
120 
121 
128  void setup( localIndex const ei,
129  StackVariables & stack ) const
130  {
131  Base::setup( ei, stack );
132 
133  stack.dPoreVolume_dTemp = ( m_volume[ei] + m_deltaVolume[ei] ) * m_dPoro_dTemp[ei][0];
134 
135  // initialize the solid volume
136  real64 const solidVolume = ( m_volume[ei] + m_deltaVolume[ei] ) * ( 1.0 - m_porosity[ei][0] );
137  real64 const dSolidVolume_dPres = -( m_volume[ei] + m_deltaVolume[ei] ) * m_dPoro_dPres[ei][0];
138  real64 const dSolidVolume_dTemp = -( m_volume[ei] + m_deltaVolume[ei] ) * m_dPoro_dTemp[ei][0];
139 
140  // initialize the solid internal energy
141  stack.solidEnergy = solidVolume * m_rockInternalEnergy[ei][0];
142  stack.dSolidEnergy_dPres = dSolidVolume_dPres * m_rockInternalEnergy[ei][0];
143  stack.dSolidEnergy_dTemp = solidVolume * m_dRockInternalEnergy_dTemp[ei][0] + dSolidVolume_dTemp * m_rockInternalEnergy[ei][0];
144  }
145 
155  StackVariables & stack ) const
156  {
157  stack.localResidual[numEqn-1] = -m_energy_n[ei];
158 
159  Base::computeAccumulation( ei, stack, [&] ()
160  {
161  // Step 1: assemble the derivatives of the mass balance equation w.r.t temperature
162  stack.localJacobian[0][numDof-1] = stack.poreVolume * m_dDensity_dTemp[ei][0] + stack.dPoreVolume_dTemp * m_density[ei][0];
163 
164  // Step 2: assemble the fluid part of the accumulation term of the energy equation
165  real64 const fluidEnergy = stack.poreVolume * m_density[ei][0] * m_internalEnergy[ei][0];
166 
167  real64 const dFluidEnergy_dP = stack.dPoreVolume_dPres * m_density[ei][0] * m_internalEnergy[ei][0]
168  + stack.poreVolume * m_dDensity_dPres[ei][0] * m_internalEnergy[ei][0]
169  + stack.poreVolume * m_density[ei][0] * m_dInternalEnergy_dPres[ei][0];
170 
171  real64 const dFluidEnergy_dT = stack.poreVolume * m_dDensity_dTemp[ei][0] * m_internalEnergy[ei][0]
172  + stack.poreVolume * m_density[ei][0] * m_dInternalEnergy_dTemp[ei][0]
173  + stack.dPoreVolume_dTemp * m_density[ei][0] * m_internalEnergy[ei][0];
174 
175  // local accumulation
176  stack.localResidual[numEqn-1] += fluidEnergy;
177 
178  // derivatives w.r.t. pressure and temperature
179  stack.localJacobian[numEqn-1][0] = dFluidEnergy_dP;
180  stack.localJacobian[numEqn-1][numDof-1] = dFluidEnergy_dT;
181  } );
182 
183  // Step 3: assemble the solid part of the accumulation term of the energy equation
184  stack.localResidual[numEqn-1] += stack.solidEnergy;
185  stack.localJacobian[numEqn-1][0] += stack.dSolidEnergy_dPres;
186  stack.localJacobian[numEqn-1][numDof-1] += stack.dSolidEnergy_dTemp;
187  }
188 
195  void complete( localIndex const ei,
196  StackVariables & stack ) const
197  {
198  // Step 1: assemble the mass balance equation
199  Base::complete( ei, stack );
200 
201  // Step 2: assemble the energy equation
202  m_localRhs[stack.localRow + numEqn-1] += stack.localResidual[numEqn-1];
203  m_localMatrix.template addToRow< serialAtomic >( stack.localRow + numEqn-1,
204  stack.dofIndices,
205  stack.localJacobian[numEqn-1],
206  numDof );
207  }
208 
209 protected:
210 
213 
216 
219  arrayView2d< real64 const > const m_dInternalEnergy_dPres;
220  arrayView2d< real64 const > const m_dInternalEnergy_dTemp;
221 
224  arrayView2d< real64 const > const m_dRockInternalEnergy_dTemp;
225 
228 
229 };
230 
235 class SurfaceElementAccumulationKernel : public AccumulationKernel< SurfaceElementSubRegion, 2 >
236 {
237 
238 public:
239 
241 
253  string const dofKey,
254  SurfaceElementSubRegion const & subRegion,
255  constitutive::SingleFluidBase const & fluid,
256  constitutive::CoupledSolidBase const & solid,
257  CRSMatrixView< real64, globalIndex const > const & localMatrix,
258  arrayView1d< real64 > const & localRhs )
259  : Base( rankOffset, dofKey, subRegion, fluid, solid, localMatrix, localRhs ),
260  m_creationMass( subRegion.getField< fields::flow::massCreated >() )
261  {}
262 
271  Base::StackVariables & stack ) const
272  {
273  Base::computeAccumulation( ei, stack );
274  if( Base::m_mass_n[ei] > 1.1 * m_creationMass[ei] )
275  {
276  stack.localResidual[0] += m_creationMass[ei] * 0.25;
277  }
278  }
279 
280 protected:
281 
282  arrayView1d< real64 const > const m_creationMass;
283 
284 };
285 
290 {
291 public:
292 
304  template< typename POLICY, typename SUBREGION_TYPE >
305  static void
306  createAndLaunch( globalIndex const rankOffset,
307  string const dofKey,
308  SUBREGION_TYPE const & subRegion,
309  constitutive::SingleFluidBase const & fluid,
310  constitutive::CoupledSolidBase const & solid,
311  CRSMatrixView< real64, globalIndex const > const & localMatrix,
312  arrayView1d< real64 > const & localRhs )
313  {
314  if constexpr ( std::is_base_of_v< CellElementSubRegion, SUBREGION_TYPE > )
315  {
316  integer constexpr NUM_DOF = 2;
317  AccumulationKernel< CellElementSubRegion, NUM_DOF > kernel( rankOffset, dofKey, subRegion, fluid, solid, localMatrix, localRhs );
318  AccumulationKernel< CellElementSubRegion, NUM_DOF >::template launch< POLICY >( subRegion.size(), kernel );
319  }
320  else if constexpr ( std::is_base_of_v< SurfaceElementSubRegion, SUBREGION_TYPE > )
321  {
322  SurfaceElementAccumulationKernel kernel( rankOffset, dofKey, subRegion, fluid, solid, localMatrix, localRhs );
323  SurfaceElementAccumulationKernel::launch< POLICY >( subRegion.size(), kernel );
324  }
325  else
326  {
327  GEOS_UNUSED_VAR( rankOffset, dofKey, subRegion, fluid, solid, localMatrix, localRhs );
328  GEOS_ERROR( "Unsupported subregion type: " << typeid(SUBREGION_TYPE).name() );
329  }
330  }
331 
332 };
333 
334 } // namespace thermalSinglePhaseBaseKernels
335 
336 } // namespace geos
337 
338 #endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_THERMALACCUMULATIONKERNELS_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_ERROR(msg)
Raise a hard error and terminate the program.
Definition: Logger.hpp:157
Define the interface for the assembly kernel in charge of accumulation.
arrayView2d< real64 const > const m_density
Views on density.
arrayView2d< real64 const > const m_porosity
Views on the porosity.
GEOS_HOST_DEVICE void computeAccumulation(localIndex const ei, StackVariables &stack, FUNC &&kernelOp=NoOpFunc{}) const
Compute the local accumulation contributions to the residual and Jacobian.
arrayView1d< globalIndex const > const m_dofNumber
View on the dof numbers.
static constexpr integer numDof
Compute time value for the number of degrees of freedom.
GEOS_HOST_DEVICE void complete(localIndex const GEOS_UNUSED_PARAM(ei), StackVariables &stack) const
Performs the complete phase for the kernel.
arrayView1d< real64 > const m_localRhs
View on the local RHS.
arrayView1d< real64 const > const m_volume
View on the element volumes.
CRSMatrixView< real64, globalIndex const > const m_localMatrix
View on the local CRS matrix.
GEOS_HOST_DEVICE void setup(localIndex const ei, StackVariables &stack) const
Performs the setup phase for the kernel.
arrayView1d< integer const > const m_elemGhostRank
View on the ghost ranks.
static constexpr integer numEqn
Compute time value for the number of equations.
globalIndex const m_rankOffset
Offset for my MPI rank.
static void createAndLaunch(globalIndex const rankOffset, string const dofKey, SUBREGION_TYPE const &subRegion, constitutive::SingleFluidBase const &fluid, constitutive::CoupledSolidBase const &solid, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs)
Create a new kernel and launch.
Define the interface for the assembly kernel in charge of accumulation.
arrayView2d< real64 const > const m_internalEnergy
Views on fluid internal energy.
arrayView2d< real64 const > const m_density
Views on density.
arrayView2d< real64 const > const m_porosity
Views on the porosity.
arrayView2d< real64 const > const m_dDensity_dTemp
View on derivative of fluid density w.r.t temperature.
GEOS_HOST_DEVICE void complete(localIndex const ei, StackVariables &stack) const
Performs the complete phase for the kernel.
GEOS_HOST_DEVICE void computeAccumulation(localIndex const ei, StackVariables &stack) const
Compute the local accumulation contributions to the residual and Jacobian.
static constexpr integer numDof
Compute time value for the number of degrees of freedom.
AccumulationKernel(globalIndex const rankOffset, string const dofKey, SUBREGION_TYPE const &subRegion, constitutive::SingleFluidBase const &fluid, constitutive::CoupledSolidBase const &solid, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs)
Constructor.
arrayView1d< real64 > const m_localRhs
View on the local RHS.
arrayView1d< real64 const > const m_volume
View on the element volumes.
arrayView1d< real64 const > const m_energy_n
View on energy.
CRSMatrixView< real64, globalIndex const > const m_localMatrix
View on the local CRS matrix.
arrayView2d< real64 const > const m_dPoro_dTemp
View on derivative of porosity w.r.t temperature.
arrayView2d< real64 const > const m_rockInternalEnergy
Views on rock internal energy.
static constexpr integer numEqn
Compute time value for the number of equations.
GEOS_HOST_DEVICE void setup(localIndex const ei, StackVariables &stack) const
Performs the setup phase for the kernel.
Define the interface for the assembly kernel in charge of accumulation in SurfaceElementSubRegion.
SurfaceElementAccumulationKernel(globalIndex const rankOffset, string const dofKey, SurfaceElementSubRegion const &subRegion, constitutive::SingleFluidBase const &fluid, constitutive::CoupledSolidBase const &solid, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs)
Constructor.
GEOS_HOST_DEVICE void computeAccumulation(localIndex const ei, Base::StackVariables &stack) const
Compute the local accumulation contributions to the residual and Jacobian.
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
std::int32_t integer
Signed integer type.
Definition: DataTypes.hpp:82
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.
Definition: DataTypes.hpp:196
Kernel variables (dof numbers, jacobian and residual) located on the stack.
real64 localJacobian[numEqn][numDof]
Storage for the element local Jacobian matrix.
localIndex localRow
Index of the local row corresponding to this element.
globalIndex dofIndices[numDof]
Index of the matrix row/column corresponding to the dof in this element.
real64 localResidual[numEqn]
Storage for the element local residual vector.
real64 dPoreVolume_dPres
Derivative of pore volume with respect to pressure.
Kernel variables (dof numbers, jacobian and residual) located on the stack.
real64 dSolidEnergy_dTemp
Derivative of solid internal energy with respect to temperature.
real64 dPoreVolume_dTemp
Derivative of pore volume with respect to temperature.
real64 dSolidEnergy_dPres
Derivative of solid internal energy with respect to pressure.