GEOS
ThermalAccumulationKernel.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_FLUIDFLOW_COMPOSITIONAL_THERMALACCUMULATIONKERNEL_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_THERMALACCUMULATIONKERNEL_HPP
22 
23 #include "physicsSolvers/fluidFlow/kernels/compositional/AccumulationKernel.hpp"
24 
25 namespace geos
26 {
27 
28 namespace thermalCompositionalMultiphaseBaseKernels
29 {
30 
31 /******************************** AccumulationKernel ********************************/
32 
39 template< localIndex NUM_COMP, localIndex NUM_DOF >
41 {
42 public:
43 
45  using Base::numComp;
46  using Base::numDof;
47  using Base::numEqn;
48  using Base::m_numPhases;
49  using Base::m_rankOffset;
50  using Base::m_dofNumber;
52  using Base::m_volume;
53  using Base::m_porosity;
54  using Base::m_dPoro_dPres;
57  using Base::m_dPhaseVolFrac;
58  using Base::m_phaseDens;
59  using Base::m_dPhaseDens;
61  using Base::m_dPhaseCompFrac;
62  using Base::m_localMatrix;
63  using Base::m_localRhs;
64 
76  AccumulationKernel( localIndex const numPhases,
77  globalIndex const rankOffset,
78  string const dofKey,
79  ElementSubRegionBase const & subRegion,
80  constitutive::MultiFluidBase const & fluid,
81  constitutive::CoupledSolidBase const & solid,
83  arrayView1d< real64 > const & localRhs,
84  BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > const kernelFlags )
85  : Base( numPhases, rankOffset, dofKey, subRegion, fluid, solid, localMatrix, localRhs, kernelFlags ),
86  m_dPoro_dTemp( solid.getDporosity_dTemperature() ),
87  m_phaseInternalEnergy( fluid.phaseInternalEnergy() ),
88  m_dPhaseInternalEnergy( fluid.dPhaseInternalEnergy() ),
89  m_rockInternalEnergy( solid.getInternalEnergy() ),
90  m_dRockInternalEnergy_dTemp( solid.getDinternalEnergy_dTemperature() ),
91  m_energy_n( subRegion.getField< fields::flow::energy_n >() )
92  {}
93 
95  {
96 public:
97 
101  {}
102 
107 
108  // derivative of pore volume wrt temperature
109  real64 dPoreVolume_dTemp = 0.0;
110 
111  // Solid energy
112 
115 
118 
121 
122  };
123 
130  void setup( localIndex const ei,
131  StackVariables & stack ) const
132  {
133  Base::setup( ei, stack );
134 
135  // derivative of pore volume wrt temperature
136  stack.dPoreVolume_dTemp = m_volume[ei] * m_dPoro_dTemp[ei][0];
137 
138  // initialize the solid volume
139  real64 const solidVolume = m_volume[ei] * ( 1.0 - m_porosity[ei][0] );
140  real64 const dSolidVolume_dPres = -m_volume[ei] * m_dPoro_dPres[ei][0];
141  real64 const dSolidVolume_dTemp = -stack.dPoreVolume_dTemp;
142 
143  // initialize the solid internal energy
144  stack.solidEnergy = solidVolume * m_rockInternalEnergy[ei][0];
145  stack.dSolidEnergy_dPres = dSolidVolume_dPres * m_rockInternalEnergy[ei][0];
146  stack.dSolidEnergy_dTemp = solidVolume * m_dRockInternalEnergy_dTemp[ei][0]
147  + dSolidVolume_dTemp * m_rockInternalEnergy[ei][0];
148  }
149 
158  StackVariables & stack ) const
159  {
160  using Deriv = constitutive::multifluid::DerivativeOffset;
161 
162  // start with old time step value
163  stack.localResidual[numEqn-1] = -m_energy_n[ei];
164 
165  Base::computeAccumulation( ei, stack, [&] ( integer const ip,
166  real64 const & phaseAmount,
167  real64 const & dPhaseAmount_dP,
168  real64 const (&dPhaseAmount_dC)[numComp] )
169  {
170  // We are in the loop over phases, ip provides the current phase index.
171  // We have to do two things:
172  // 1- Assemble the derivatives of the component mass balance equations with respect to temperature
173  // 2- Assemble the phase-dependent part of the accumulation term of the energy equation
174 
175  real64 dPhaseInternalEnergy_dC[numComp]{};
176 
177  // construct the slices
178  arraySlice2d< real64 const, compflow::USD_COMP_DC - 1 > dCompFrac_dCompDens = m_dCompFrac_dCompDens[ei];
179  arraySlice1d< real64 const, compflow::USD_PHASE - 1 > phaseVolFrac = m_phaseVolFrac[ei];
180  arraySlice2d< real64 const, compflow::USD_PHASE_DC - 1 > dPhaseVolFrac = m_dPhaseVolFrac[ei];
181  arraySlice1d< real64 const, constitutive::multifluid::USD_PHASE - 2 > phaseDens = m_phaseDens[ei][0];
182  arraySlice2d< real64 const, constitutive::multifluid::USD_PHASE_DC - 2 > dPhaseDens = m_dPhaseDens[ei][0];
183  arraySlice2d< real64 const, constitutive::multifluid::USD_PHASE_COMP - 2 > phaseCompFrac = m_phaseCompFrac[ei][0];
184  arraySlice3d< real64 const, constitutive::multifluid::USD_PHASE_COMP_DC - 2 > dPhaseCompFrac = m_dPhaseCompFrac[ei][0];
185  arraySlice1d< real64 const, constitutive::multifluid::USD_PHASE - 2 > phaseInternalEnergy = m_phaseInternalEnergy[ei][0];
186  arraySlice2d< real64 const, constitutive::multifluid::USD_PHASE_DC - 2 > dPhaseInternalEnergy = m_dPhaseInternalEnergy[ei][0];
187 
188  // Step 1: assemble the derivatives of the component mass balance equations with respect to temperature
189 
190  real64 const dPhaseAmount_dT = stack.dPoreVolume_dTemp * phaseVolFrac[ip] * phaseDens[ip]
191  + stack.poreVolume * (dPhaseVolFrac[ip][Deriv::dT] * phaseDens[ip] + phaseVolFrac[ip] * dPhaseDens[ip][Deriv::dT] );
192  for( integer ic = 0; ic < numComp; ++ic )
193  {
194  stack.localJacobian[ic][numDof-1] += dPhaseAmount_dT * phaseCompFrac[ip][ic]
195  + phaseAmount * dPhaseCompFrac[ip][ic][Deriv::dT];
196  }
197 
198  // Step 2: assemble the phase-dependent part of the accumulation term of the energy equation
199 
200  real64 const phaseEnergy = phaseAmount * phaseInternalEnergy[ip];
201  real64 const dPhaseEnergy_dP = dPhaseAmount_dP * phaseInternalEnergy[ip]
202  + phaseAmount * dPhaseInternalEnergy[ip][Deriv::dP];
203  real64 const dPhaseEnergy_dT = dPhaseAmount_dT * phaseInternalEnergy[ip]
204  + phaseAmount * dPhaseInternalEnergy[ip][Deriv::dT];
205 
206  // local accumulation
207  stack.localResidual[numEqn-1] += phaseEnergy;
208 
209  // derivatives w.r.t. pressure and temperature
210  stack.localJacobian[numEqn-1][0] += dPhaseEnergy_dP;
211  stack.localJacobian[numEqn-1][numDof-1] += dPhaseEnergy_dT;
212 
213  // derivatives w.r.t. component densities
214  applyChainRule( numComp, dCompFrac_dCompDens, dPhaseInternalEnergy[ip], dPhaseInternalEnergy_dC, Deriv::dC );
215  for( integer jc = 0; jc < numComp; ++jc )
216  {
217  stack.localJacobian[numEqn-1][jc + 1] += phaseInternalEnergy[ip] * dPhaseAmount_dC[jc]
218  + dPhaseInternalEnergy_dC[jc] * phaseAmount;
219  }
220  } );
221 
222  // Step 3: assemble the solid part of the accumulation term
223 
224  // local accumulation and derivatives w.r.t. pressure and temperature
225  stack.localResidual[numEqn-1] += stack.solidEnergy;
226  stack.localJacobian[numEqn-1][0] += stack.dSolidEnergy_dPres;
227  stack.localJacobian[numEqn-1][numDof-1] += stack.dSolidEnergy_dTemp;
228 
229  }
230 
239  StackVariables & stack ) const
240  {
241  using Deriv = constitutive::multifluid::DerivativeOffset;
242 
243  Base::computeVolumeBalance( ei, stack, [&] ( real64 const & oneMinusPhaseVolFraction )
244  {
245  GEOS_UNUSED_VAR( oneMinusPhaseVolFraction );
246 
247  arraySlice2d< real64 const, compflow::USD_PHASE_DC - 1 > dPhaseVolFrac = m_dPhaseVolFrac[ei];
248 
249  for( integer ip = 0; ip < m_numPhases; ++ip )
250  {
251  stack.localJacobian[numEqn-2][numDof-1] -= dPhaseVolFrac[ip][Deriv::dT];
252  }
253  } );
254  }
255 
257  void complete( localIndex const ei,
258  StackVariables & stack ) const
259  {
260  // Step 1: assemble the component mass balance equations and volume balance equations
261  Base::complete( ei, stack );
262 
263  // Step 2: assemble the energy equation
264  m_localRhs[stack.localRow + numEqn-1] += stack.localResidual[numEqn-1];
265  m_localMatrix.template addToRow< serialAtomic >( stack.localRow + numEqn-1,
266  stack.dofIndices,
267  stack.localJacobian[numEqn-1],
268  numDof );
269  }
270 
271 protected:
272 
275 
279 
282  arrayView2d< real64 const > m_dRockInternalEnergy_dTemp;
283 
286 
287 };
288 
293 {
294 public:
295 
309  template< typename POLICY >
310  static void
311  createAndLaunch( localIndex const numComps,
312  localIndex const numPhases,
313  globalIndex const rankOffset,
314  integer const useTotalMassEquation,
315  string const dofKey,
316  ElementSubRegionBase const & subRegion,
317  constitutive::MultiFluidBase const & fluid,
318  constitutive::CoupledSolidBase const & solid,
319  CRSMatrixView< real64, globalIndex const > const & localMatrix,
320  arrayView1d< real64 > const & localRhs )
321  {
322  isothermalCompositionalMultiphaseBaseKernels::
323  internal::kernelLaunchSelectorCompSwitch( numComps, [&] ( auto NC )
324  {
325  localIndex constexpr NUM_COMP = NC();
326  localIndex constexpr NUM_DOF = NC()+2;
327 
328  BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > kernelFlags;
329  if( useTotalMassEquation )
330  kernelFlags.set( isothermalCompositionalMultiphaseBaseKernels::KernelFlags::TotalMassEquation );
331 
332  AccumulationKernel< NUM_COMP, NUM_DOF > kernel( numPhases, rankOffset, dofKey, subRegion,
333  fluid, solid, localMatrix, localRhs, kernelFlags );
334  AccumulationKernel< NUM_COMP, NUM_DOF >::template launch< POLICY >( subRegion.size(), kernel );
335  } );
336  }
337 
338 };
339 
340 } // namespace thermalCompositionalMultiphaseBaseKernels
341 
342 } // namespace geos
343 
344 
345 #endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_THERMALACCUMULATIONKERNEL_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
localIndex size() const
Get the "size" of the group, which determines the number of elements in resizable wrappers.
Definition: Group.hpp:1315
Define the interface for the assembly kernel in charge of accumulation and volume balance.
static constexpr integer numDof
Compute time value for the number of degrees of freedom.
arrayView2d< real64 const, compflow::USD_PHASE > const m_phaseVolFrac
Views on the phase volume fractions.
GEOS_HOST_DEVICE void complete(localIndex const GEOS_UNUSED_PARAM(ei), StackVariables &stack) const
Performs the complete phase for the kernel.
arrayView1d< integer const > const m_elemGhostRank
View on the ghost ranks.
CRSMatrixView< real64, globalIndex const > const m_localMatrix
View on the local CRS matrix.
arrayView4d< real64 const, constitutive::multifluid::USD_PHASE_COMP > const m_phaseCompFrac
Views on the phase component fraction.
static constexpr integer numEqn
Compute time value for the number of equations.
GEOS_HOST_DEVICE void computeVolumeBalance(localIndex const ei, StackVariables &stack, FUNC &&phaseVolFractionSumKernelOp=NoOpFunc{}) const
Compute the local volume balance contributions to the residual and Jacobian.
arrayView3d< real64 const, compflow::USD_COMP_DC > const m_dCompFrac_dCompDens
Views on the derivatives of comp fractions wrt component density.
arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > const m_phaseDens
Views on the phase densities.
arrayView2d< real64 const > const m_porosity
Views on the porosity.
arrayView1d< real64 > const m_localRhs
View on the local RHS.
GEOS_HOST_DEVICE void computeAccumulation(localIndex const ei, StackVariables &stack, FUNC &&phaseAmountKernelOp=NoOpFunc{}) const
Compute the local accumulation contributions to the residual and Jacobian.
GEOS_HOST_DEVICE void setup(localIndex const ei, StackVariables &stack) const
Performs the setup phase for the kernel.
arrayView1d< real64 const > const m_volume
View on the element volumes.
static constexpr integer numComp
Compile time value for the number of components.
arrayView1d< globalIndex const > const m_dofNumber
View on the dof numbers.
static void createAndLaunch(localIndex const numComps, localIndex const numPhases, globalIndex const rankOffset, integer const useTotalMassEquation, string const dofKey, ElementSubRegionBase const &subRegion, constitutive::MultiFluidBase 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 thermal accumulation and volume balance.
static constexpr integer numDof
Compute time value for the number of degrees of freedom.
arrayView2d< real64 const, compflow::USD_PHASE > const m_phaseVolFrac
Views on the phase volume fractions.
arrayView2d< real64 const > m_rockInternalEnergy
Views on rock internal energy.
CRSMatrixView< real64, globalIndex const > const m_localMatrix
View on the local CRS matrix.
arrayView4d< real64 const, constitutive::multifluid::USD_PHASE_COMP > const m_phaseCompFrac
Views on the phase component fraction.
static constexpr integer numEqn
Compute time value for the number of equations.
AccumulationKernel(localIndex const numPhases, globalIndex const rankOffset, string const dofKey, ElementSubRegionBase const &subRegion, constitutive::MultiFluidBase const &fluid, constitutive::CoupledSolidBase const &solid, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs, BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > const kernelFlags)
Constructor.
arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > m_phaseInternalEnergy
Views on phase internal energy.
GEOS_HOST_DEVICE void computeVolumeBalance(localIndex const ei, StackVariables &stack) const
Compute the local volume balance contributions to the residual and Jacobian.
arrayView3d< real64 const, compflow::USD_COMP_DC > const m_dCompFrac_dCompDens
Views on the derivatives of comp fractions wrt component density.
arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > const m_phaseDens
Views on the phase densities.
arrayView2d< real64 const > const m_porosity
Views on the porosity.
GEOS_HOST_DEVICE void computeAccumulation(localIndex const ei, StackVariables &stack) const
Compute the local accumulation contributions to the residual and Jacobian.
arrayView1d< real64 > const m_localRhs
View on the local RHS.
arrayView1d< real64 const > const m_volume
View on the element volumes.
GEOS_HOST_DEVICE void setup(localIndex const ei, StackVariables &stack) const
Performs the setup phase for the kernel.
arrayView2d< real64 const > const m_dPoro_dTemp
View on derivative of porosity w.r.t temperature.
static constexpr integer numComp
Compile time value for the number of components.
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
ArraySlice< T, 2, USD > arraySlice2d
Alias for 2D array slice.
Definition: DataTypes.hpp:200
ArraySlice< T, 3, USD > arraySlice3d
Alias for 3D array slice.
Definition: DataTypes.hpp:216
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
ArraySlice< T, 1, USD > arraySlice1d
Alias for 1D array slice.
Definition: DataTypes.hpp:184
std::int32_t integer
Signed integer type.
Definition: DataTypes.hpp:82
ArrayView< T, 4, USD > arrayView4d
Alias for 4D array view.
Definition: DataTypes.hpp:228
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.
globalIndex dofIndices[numDof]
Indices of the matrix rows/columns corresponding to the dofs in this element.
localIndex localRow
Index of the local row corresponding to this element.
real64 localJacobian[numEqn][numDof]
C-array storage for the element local Jacobian matrix (all equations except volume balance,...
real64 localResidual[numEqn]
C-array storage for the element local residual vector (all equations except volume balance)
real64 dSolidEnergy_dPres
Derivative of solid internal energy with respect to pressure.
real64 dSolidEnergy_dTemp
Derivative of solid internal energy with respect to temperature.