GEOS
AccumulationZFormulationKernel.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_ACCUMULATIONZFORMULATIONKERNEL_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_ACCUMULATIONZFORMULATIONKERNEL_HPP
22 
23 #include "codingUtilities/Utilities.hpp"
24 #include "common/DataLayouts.hpp"
25 #include "common/DataTypes.hpp"
26 #include "common/GEOS_RAJA_Interface.hpp"
27 #include "constitutive/solid/CoupledSolidBase.hpp"
28 #include "constitutive/fluid/multifluid/MultiFluidBase.hpp"
33 #include "physicsSolvers/fluidFlow/kernels/compositional/KernelLaunchSelectors.hpp"
34 
35 namespace geos
36 {
37 
38 namespace isothermalCompositionalMultiphaseBaseKernels
39 {
40 
41 static constexpr real64 minCompFracForDivision = 0;
42 
43 /******************************** AccumulationKernel ********************************/
44 
51 template< integer NUM_COMP, integer NUM_DOF >
53 {
54 public:
55 
57  static constexpr integer numComp = NUM_COMP;
58 
60  static constexpr integer numDof = NUM_DOF;
61 
63  static constexpr integer numEqn = NUM_DOF;
64 
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< KernelFlags > const KernelFlags )
85  : m_numPhases( numPhases ),
86  m_rankOffset( rankOffset ),
87  m_dofNumber( subRegion.getReference< array1d< globalIndex > >( dofKey ) ),
88  m_elemGhostRank( subRegion.ghostRank() ),
89  m_volume( subRegion.getElementVolume() ),
90  m_porosity( solid.getPorosity() ),
91  m_dPoro_dPres( solid.getDporosity_dPressure() ),
92  m_phaseVolFrac( subRegion.getField< fields::flow::phaseVolumeFraction >() ),
93  m_dPhaseVolFrac( subRegion.getField< fields::flow::dPhaseVolumeFraction >() ),
94  m_totalDens( fluid.totalDensity() ),
95  m_dTotalDens( fluid.dTotalDensity() ),
96  m_compFrac( subRegion.getField< fields::flow::globalCompFraction >() ),
97  m_compAmount_n( subRegion.getField< fields::flow::compAmount_n >() ),
98  m_localMatrix( localMatrix ),
99  m_localRhs( localRhs ),
100  m_KernelFlags( KernelFlags )
101  {}
102 
108  {
109 public:
110 
111  // Pore volume information (used by both accumulation and volume balance)
112 
115 
118 
119  // Residual information
120 
123 
126 
129 
132 
133  };
134 
141  integer elemGhostRank( localIndex const ei ) const
142  { return m_elemGhostRank( ei ); }
143 
144 
151  void setup( localIndex const ei,
152  StackVariables & stack ) const
153  {
154  // initialize the pore volume
155  stack.poreVolume = m_volume[ei] * m_porosity[ei][0];
156  stack.dPoreVolume_dPres = m_volume[ei] * m_dPoro_dPres[ei][0];
157 
158  // set row index and degrees of freedom indices for this element
159  stack.localRow = m_dofNumber[ei] - m_rankOffset;
160  for( integer idof = 0; idof < numDof; ++idof )
161  {
162  stack.dofIndices[idof] = m_dofNumber[ei] + idof;
163  }
164  }
165 
173  template< typename FUNC = NoOpFunc >
176  StackVariables & stack ) const
177  {
178  using Deriv = constitutive::multifluid::DerivativeOffset;
179 
180  arraySlice1d< real64 const, compflow::USD_COMP - 1 > const compFrac = m_compFrac[ei];
181  real64 const totalDensity = m_totalDens[ei][0];
182  arraySlice1d< real64 const, constitutive::multifluid::USD_FLUID_DC - 2 > const dTotalDens = m_dTotalDens[ei][0];
183 
184  // ic - index of component whose conservation equation is assembled
185  // (i.e. row number in local matrix)
186  for( integer ic = 0; ic < numComp; ++ic )
187  {
188  real64 const compAmount = stack.poreVolume * totalDensity * compFrac[ic];
189  real64 const compAmount_n = m_compAmount_n[ei][ic];
190 
191  stack.localResidual[ic] += compAmount - compAmount_n;
192 
193  // derivatives with respect to pressure (p)
194  real64 const dCompAmount_dP = compFrac[ic] * (stack.dPoreVolume_dPres * totalDensity + stack.poreVolume * dTotalDens[Deriv::dP]);
195  stack.localJacobian[ic][0] += dCompAmount_dP;
196 
197  // derivatives with respect to global component fraction (zc)
198  for( integer jc = 0; jc < numComp; ++jc )
199  {
200  real64 dCompAmount_dC;
201  if( ic == jc )
202  dCompAmount_dC = stack.poreVolume * (totalDensity + dTotalDens[Deriv::dC+jc] * compFrac[ic]);
203  else
204  dCompAmount_dC = stack.poreVolume * (dTotalDens[Deriv::dC+jc] * compFrac[ic]);
205 
206  stack.localJacobian[ic][jc + 1] += dCompAmount_dC;
207  }
208  }
209  }
210 
218  template< typename FUNC = NoOpFunc >
221  StackVariables & stack ) const
222  {
223 
224  arraySlice1d< real64 const, compflow::USD_PHASE - 1 > compFrac = m_compFrac[ei];
225 
226  real64 oneMinusCompFracSum = 1.0;
227 
228  // sum contributions to component accumulation from each component
229  for( integer ic = 0; ic < numComp; ++ic )
230  {
231  oneMinusCompFracSum -= compFrac[ic];
232  // no derivatives w.r.t pressure
233 
234  // derivative w.r.t component fractions are unity: dzc_dzc = 1
235  stack.localJacobian[numComp][ic+1] -= 1;
236  }
237 
238  //phaseVolFractionSumKernelOp( oneMinusCompFracSum );
239 
240  // scale componentFraction-based volume balance by pore volume (for better scaling w.r.t. other equations)
241  stack.localResidual[numComp] = stack.poreVolume * oneMinusCompFracSum;
242  for( integer idof = 0; idof < numDof; ++idof )
243  {
244  stack.localJacobian[numComp][idof] *= stack.poreVolume;
245  }
246  stack.localJacobian[numComp][0] += stack.dPoreVolume_dPres * oneMinusCompFracSum;
247  }
248 
256  StackVariables & stack ) const
257  {
258  using namespace compositionalMultiphaseUtilities;
259 
260  if( m_KernelFlags.isSet( KernelFlags::TotalMassEquation ) )
261  {
262  // apply equation/variable change transformation to the component mass balance equations
263  real64 work[numDof]{};
264  shiftRowsAheadByOneAndReplaceFirstRowWithColumnSum( numComp, numDof, stack.localJacobian, work );
265  shiftElementsAheadByOneAndReplaceFirstElementWithSum( numComp, stack.localResidual );
266  }
267 
268  // add contribution to residual and jacobian into:
269  // - the component mass balance equations (i = 0 to i = numComp-1)
270  // - the volume balance equations (i = numComp)
271  // note that numDof includes derivatives wrt temperature if this class is derived in ThermalKernels
272  integer const numRows = numComp+1;
273  for( integer i = 0; i < numRows; ++i )
274  {
275  m_localRhs[stack.localRow + i] += stack.localResidual[i];
276  m_localMatrix.addToRow< serialAtomic >( stack.localRow + i,
277  stack.dofIndices,
278  stack.localJacobian[i],
279  numDof );
280  }
281  }
282 
290  template< typename POLICY, typename KERNEL_TYPE >
291  static void
292  launch( localIndex const numElems,
293  KERNEL_TYPE const & kernelComponent )
294  {
296 
297  forAll< POLICY >( numElems, [=] GEOS_HOST_DEVICE ( localIndex const ei )
298  {
299  if( kernelComponent.elemGhostRank( ei ) >= 0 )
300  {
301  return;
302  }
303 
304  typename KERNEL_TYPE::StackVariables stack;
305 
306  kernelComponent.setup( ei, stack );
307  kernelComponent.computeAccumulation( ei, stack );
308  kernelComponent.computeCompFracSum( ei, stack );
309  kernelComponent.complete( ei, stack );
310  } );
311  }
312 
313 protected:
314 
317 
320 
323 
326 
329 
332  arrayView2d< real64 const > const m_dPoro_dPres;
333 
336 
340 
344 
345  // View on component densities and component fractions
347 
348  // View on component amount (mass/moles) from previous time step
350 
355 
356  BitFlags< KernelFlags > const m_KernelFlags;
357 };
358 
363 {
364 public:
365 
379  template< typename POLICY >
380  static void
381  createAndLaunch( integer const numComps,
382  integer const numPhases,
383  globalIndex const rankOffset,
384  BitFlags< KernelFlags > kernelFlags,
385  string const dofKey,
386  ElementSubRegionBase const & subRegion,
387  constitutive::MultiFluidBase const & fluid,
388  constitutive::CoupledSolidBase const & solid,
389  CRSMatrixView< real64, globalIndex const > const & localMatrix,
390  arrayView1d< real64 > const & localRhs )
391  {
392  internal::kernelLaunchSelectorCompSwitch( numComps, [&] ( auto NC )
393  {
394  integer constexpr NUM_COMP = NC();
395  integer constexpr NUM_DOF = NC()+1;
396 
397  AccumulationZFormulationKernel< NUM_COMP, NUM_DOF > kernel( numPhases, rankOffset, dofKey, subRegion,
398  fluid, solid, localMatrix, localRhs, kernelFlags );
399  AccumulationZFormulationKernel< NUM_COMP, NUM_DOF >::template launch< POLICY >( subRegion.size(), kernel );
400  } );
401  }
402 
403 };
404 
405 } // namespace isothermalCompositionalMultiphaseBaseKernels
406 
407 } // namespace geos
408 
409 
410 #endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_ACCUMULATIONZFORMULATIONKERNEL_HPP
#define GEOS_HOST_DEVICE
Marks a host-device function.
Definition: GeosxMacros.hpp:49
#define GEOS_UNUSED_PARAM(X)
Mark an unused argument and silence compiler warnings.
Definition: GeosxMacros.hpp:72
#define GEOS_MARK_FUNCTION
Mark function with both Caliper and NVTX if enabled.
localIndex size() const
Get the "size" of the group, which determines the number of elements in resizable wrappers.
Definition: Group.hpp:1317
static void createAndLaunch(integer const numComps, integer const numPhases, globalIndex const rankOffset, BitFlags< KernelFlags > kernelFlags, 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 accumulation and volume balance.
GEOS_HOST_DEVICE void computeCompFracSum(localIndex const ei, StackVariables &stack) const
Compute the local volume balance contributions to the residual and Jacobian.
GEOS_HOST_DEVICE void setup(localIndex const ei, StackVariables &stack) const
Performs the setup phase for the kernel.
static constexpr integer numDof
Compute time value for the number of degrees of freedom.
static constexpr integer numComp
Compile time value for the number of components.
arrayView2d< real64 const, compflow::USD_PHASE > const m_phaseVolFrac
Views on the phase volume fractions.
static constexpr integer numEqn
Compute time value for the number of equations.
GEOS_HOST_DEVICE void complete(localIndex const GEOS_UNUSED_PARAM(ei), StackVariables &stack) const
Performs the complete phase for the kernel.
arrayView3d< real64 const, compflow::USD_COMP_DC > const m_dCompFrac_dCompDens
Views on the derivatives of comp fractions wrt component density.
GEOS_HOST_DEVICE integer elemGhostRank(localIndex const ei) const
Getter for the ghost rank of an element.
AccumulationZFormulationKernel(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< KernelFlags > const KernelFlags)
Constructor.
arrayView2d< real64 const, constitutive::multifluid::USD_FLUID > const m_totalDens
Views on the total density.
CRSMatrixView< real64, globalIndex const > const m_localMatrix
View on the local CRS matrix.
GEOS_HOST_DEVICE void computeAccumulation(localIndex const ei, StackVariables &stack) const
Compute the local accumulation contributions to the residual and Jacobian.
static void launch(localIndex const numElems, KERNEL_TYPE const &kernelComponent)
Performs the kernel launch.
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
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, 2, USD > arrayView2d
Alias for 2D array view.
Definition: DataTypes.hpp:196
Array< T, 1 > array1d
Alias for 1D array.
Definition: DataTypes.hpp:176
ArrayView< T, 3, USD > arrayView3d
Alias for 3D array view.
Definition: DataTypes.hpp:212
globalIndex dofIndices[numDof]
Indices of the matrix rows/columns corresponding to the dofs in 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)