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;
55  using Base::m_localMatrix;
56  using Base::m_localRhs;
57 
59  static constexpr integer isThermal = NUM_DOF-1;
60  using DerivOffset = constitutive::singlefluid::DerivativeOffsetC< isThermal >;
71  AccumulationKernel( globalIndex const rankOffset,
72  string const dofKey,
73  SUBREGION_TYPE const & subRegion,
74  constitutive::SingleFluidBase const & fluid,
75  constitutive::CoupledSolidBase const & solid,
77  arrayView1d< real64 > const & localRhs )
78  : Base( rankOffset, dofKey, subRegion, fluid, solid, localMatrix, localRhs ),
79  m_dPoro_dTemp( solid.getDporosity_dTemperature() ),
80  m_internalEnergy( fluid.internalEnergy() ),
81  m_dInternalEnergy( fluid.dInternalEnergy() ),
82  m_rockInternalEnergy( solid.getInternalEnergy() ),
83  m_dRockInternalEnergy_dTemp( solid.getDinternalEnergy_dTemperature() ),
84  m_energy_n( subRegion.template getField< fields::flow::energy_n >() )
85  {}
86 
92  {
93 public:
94 
98  {}
99 
106 
109 
110  // Solid energy
111 
114 
117 
120  };
121 
122 
129  void setup( localIndex const ei,
130  StackVariables & stack ) const
131  {
132  Base::setup( ei, stack );
133 
134  stack.dPoreVolume_dTemp = ( m_volume[ei] + m_deltaVolume[ei] ) * m_dPoro_dTemp[ei][0];
135 
136  // initialize the solid volume
137  real64 const solidVolume = ( m_volume[ei] + m_deltaVolume[ei] ) * ( 1.0 - m_porosity[ei][0] );
138  real64 const dSolidVolume_dPres = -( m_volume[ei] + m_deltaVolume[ei] ) * m_dPoro_dPres[ei][0];
139  real64 const dSolidVolume_dTemp = -( m_volume[ei] + m_deltaVolume[ei] ) * m_dPoro_dTemp[ei][0];
140 
141  // initialize the solid internal energy
142  stack.solidEnergy = solidVolume * m_rockInternalEnergy[ei][0];
143  stack.dSolidEnergy_dPres = dSolidVolume_dPres * m_rockInternalEnergy[ei][0];
144  stack.dSolidEnergy_dTemp = solidVolume * m_dRockInternalEnergy_dTemp[ei][0] + dSolidVolume_dTemp * m_rockInternalEnergy[ei][0];
145  }
146 
156  StackVariables & stack ) const
157  {
158  stack.localResidual[numEqn-1] = -m_energy_n[ei];
159 
160  Base::computeAccumulation( ei, stack, [&] ()
161  {
162  // Step 1: assemble the derivatives of the mass balance equation w.r.t temperature
163  stack.localJacobian[0][numDof-1] = stack.poreVolume * m_dDensity[ei][0][DerivOffset::dT] + stack.dPoreVolume_dTemp * m_density[ei][0];
164 
165  // Step 2: assemble the fluid part of the accumulation term of the energy equation
166  real64 const fluidEnergy = stack.poreVolume * m_density[ei][0] * m_internalEnergy[ei][0];
167 
168  real64 const dFluidEnergy_dP = stack.dPoreVolume_dPres * m_density[ei][0] * m_internalEnergy[ei][0]
169  + stack.poreVolume * m_dDensity[ei][0][DerivOffset::dP] * m_internalEnergy[ei][0]
170  + stack.poreVolume * m_density[ei][0] * m_dInternalEnergy[ei][0][DerivOffset::dP];
171 
172  real64 const dFluidEnergy_dT = stack.poreVolume * m_dDensity[ei][0][DerivOffset::dT] * m_internalEnergy[ei][0]
173  + stack.poreVolume * m_density[ei][0] * m_dInternalEnergy[ei][0][DerivOffset::dT]
174  + stack.dPoreVolume_dTemp * m_density[ei][0] * m_internalEnergy[ei][0];
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 
211 
214 
218 
221  arrayView2d< real64 const > const m_dRockInternalEnergy_dTemp;
222 
225 
226 };
227 
232 class SurfaceElementAccumulationKernel : public AccumulationKernel< SurfaceElementSubRegion, 2 >
233 {
234 
235 public:
236 
238 
250  string const dofKey,
251  SurfaceElementSubRegion const & subRegion,
252  constitutive::SingleFluidBase const & fluid,
253  constitutive::CoupledSolidBase const & solid,
254  CRSMatrixView< real64, globalIndex const > const & localMatrix,
255  arrayView1d< real64 > const & localRhs )
256  : Base( rankOffset, dofKey, subRegion, fluid, solid, localMatrix, localRhs ),
257  m_creationMass( subRegion.getField< fields::flow::massCreated >() )
258  {}
259 
268  Base::StackVariables & stack ) const
269  {
270  Base::computeAccumulation( ei, stack );
271  if( Base::m_mass_n[ei] > 1.1 * m_creationMass[ei] )
272  {
273  stack.localResidual[0] += m_creationMass[ei] * 0.25;
274  }
275  }
276 
277 protected:
278 
279  arrayView1d< real64 const > const m_creationMass;
280 
281 };
282 
287 {
288 public:
289 
301  template< typename POLICY, typename SUBREGION_TYPE >
302  static void
303  createAndLaunch( globalIndex const rankOffset,
304  string const dofKey,
305  SUBREGION_TYPE const & subRegion,
306  constitutive::SingleFluidBase const & fluid,
307  constitutive::CoupledSolidBase const & solid,
308  CRSMatrixView< real64, globalIndex const > const & localMatrix,
309  arrayView1d< real64 > const & localRhs )
310  {
311  if constexpr ( std::is_base_of_v< CellElementSubRegion, SUBREGION_TYPE > )
312  {
313  integer constexpr NUM_DOF = 2;
314  AccumulationKernel< CellElementSubRegion, NUM_DOF > kernel( rankOffset, dofKey, subRegion, fluid, solid, localMatrix, localRhs );
315  AccumulationKernel< CellElementSubRegion, NUM_DOF >::template launch< POLICY >( subRegion.size(), kernel );
316  }
317  else if constexpr ( std::is_base_of_v< SurfaceElementSubRegion, SUBREGION_TYPE > )
318  {
319  SurfaceElementAccumulationKernel kernel( rankOffset, dofKey, subRegion, fluid, solid, localMatrix, localRhs );
320  SurfaceElementAccumulationKernel::launch< POLICY >( subRegion.size(), kernel );
321  }
322  else
323  {
324  GEOS_UNUSED_VAR( rankOffset, dofKey, subRegion, fluid, solid, localMatrix, localRhs );
325  GEOS_ERROR( "Unsupported subregion type: " << typeid(SUBREGION_TYPE).name() );
326  }
327  }
328 
329 };
330 
331 } // namespace thermalSinglePhaseBaseKernels
332 
333 } // namespace geos
334 
335 #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_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.
arrayView2d< real64 const, constitutive::singlefluid::USD_FLUID > const m_density
Views on density.
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_porosity
Views on the porosity.
arrayView2d< real64 const, constitutive::singlefluid::USD_FLUID > const m_density
Views on density.
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.
static constexpr integer isThermal
Note: Derivative lineup only supports dP & dT, not component terms.
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.
arrayView2d< real64 const, constitutive::singlefluid::USD_FLUID > const m_internalEnergy
Views on fluid internal energy.
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
ArrayView< T, 3, USD > arrayView3d
Alias for 3D array view.
Definition: DataTypes.hpp:212
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.