GEOS
FluxComputeKernel.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_FLUXCOMPUTEKERNEL_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_FLUXCOMPUTEKERNEL_HPP
22 
24 
25 
26 namespace geos
27 {
28 
29 namespace singlePhaseFVMKernels
30 {
31 
38 template< integer NUM_EQN, integer NUM_DOF, typename STENCILWRAPPER >
40 {
41 public:
42 
44  static constexpr integer numDof = NUM_DOF;
45 
47  static constexpr integer numEqn = NUM_EQN;
48 
50  static constexpr localIndex maxNumElems = STENCILWRAPPER::maxNumPointsInFlux;
51 
53  static constexpr localIndex maxNumConns = STENCILWRAPPER::maxNumConnections;
54 
56  static constexpr localIndex maxStencilSize = STENCILWRAPPER::maxStencilSize;
57 
70  FluxComputeKernel( globalIndex const rankOffset,
71  STENCILWRAPPER const & stencilWrapper,
72  DofNumberAccessor const & dofNumberAccessor,
73  SinglePhaseFlowAccessors const & singlePhaseFlowAccessors,
74  SinglePhaseFluidAccessors const & singlePhaseFluidAccessors,
75  PermeabilityAccessors const & permeabilityAccessors,
76  real64 const & dt,
78  arrayView1d< real64 > const & localRhs )
79  : FluxComputeKernelBase( rankOffset,
80  dofNumberAccessor,
81  singlePhaseFlowAccessors,
82  singlePhaseFluidAccessors,
83  permeabilityAccessors,
84  dt,
85  localMatrix,
86  localRhs ),
87  m_stencilWrapper( stencilWrapper ),
88  m_seri( stencilWrapper.getElementRegionIndices() ),
89  m_sesri( stencilWrapper.getElementSubRegionIndices() ),
90  m_sei( stencilWrapper.getElementIndices() )
91  {}
92 
98  {
99 public:
100 
107  StackVariables( localIndex const size, localIndex numElems )
108  : stencilSize( size ),
109  numFluxElems( numElems ),
110  dofColIndices( size * numDof ),
111  localFlux( numElems * numEqn ),
112  localFluxJacobian( numElems * numEqn, size * numDof )
113  {}
114 
115  // Stencil information
116 
119 
122 
123  // Transmissibility and derivatives
124 
129 
130  // Local degrees of freedom and local residual/jacobian
131 
134 
139 
140  };
141 
148  localIndex stencilSize( localIndex const iconn ) const
149  { return m_sei[iconn].size(); }
150 
157  localIndex numPointsInFlux( localIndex const iconn ) const
158  { return m_stencilWrapper.numPointsInFlux( iconn ); }
159 
166  void setup( localIndex const iconn,
167  StackVariables & stack ) const
168  {
169  // set degrees of freedom indices for this face
170  for( integer i = 0; i < stack.stencilSize; ++i )
171  {
172  globalIndex const offset = m_dofNumber[m_seri( iconn, i )][m_sesri( iconn, i )][m_sei( iconn, i )];
173 
174  for( integer jdof = 0; jdof < numDof; ++jdof )
175  {
176  stack.dofColIndices[i * numDof + jdof] = offset + jdof;
177  }
178  }
179  }
180 
188  template< typename FUNC = NoOpFunc >
190  void computeFlux( localIndex const iconn,
191  StackVariables & stack,
192  FUNC && kernelOp = NoOpFunc{} ) const
193  {
194  // first, compute the transmissibilities at this face
195  m_stencilWrapper.computeWeights( iconn,
197  m_dPerm_dPres,
198  stack.transmissibility,
199  stack.dTrans_dPres );
200 
201  localIndex k[2];
202  localIndex connectionIndex = 0;
203 
204  for( k[0] = 0; k[0] < stack.numFluxElems; ++k[0] )
205  {
206  for( k[1] = k[0] + 1; k[1] < stack.numFluxElems; ++k[1] )
207  {
208  real64 fluxVal = 0.0;
209  real64 dFlux_dTrans = 0.0;
210  real64 alpha = 0.0;
211  real64 mobility = 0.0;
212  real64 potGrad = 0.0;
213  real64 trans[2] = { stack.transmissibility[connectionIndex][0], stack.transmissibility[connectionIndex][1] };
214  real64 dTrans[2] = { stack.dTrans_dPres[connectionIndex][0], stack.dTrans_dPres[connectionIndex][1] };
215  real64 dFlux_dP[2] = {0.0, 0.0};
216  localIndex const regionIndex[2] = {m_seri( iconn, k[0] ), m_seri( iconn, k[1] )};
217  localIndex const subRegionIndex[2] = {m_sesri( iconn, k[0] ), m_sesri( iconn, k[1] )};
218  localIndex const elementIndex[2] = {m_sei( iconn, k[0] ), m_sei( iconn, k[1] )};
219 
220  singlePhaseFluxKernelsHelper::computeSinglePhaseFlux( regionIndex, subRegionIndex, elementIndex,
221  trans,
222  dTrans,
223  m_pres,
224  m_gravCoef,
225  m_dens,
226  m_dDens_dPres,
227  m_mob,
228  m_dMob_dPres,
229  alpha,
230  mobility,
231  potGrad,
232  fluxVal,
233  dFlux_dP,
234  dFlux_dTrans );
235 
236  // populate local flux vector and derivatives
237  stack.localFlux[k[0]*numEqn] += m_dt * fluxVal;
238  stack.localFlux[k[1]*numEqn] -= m_dt * fluxVal;
239 
240  for( integer ke = 0; ke < 2; ++ke )
241  {
242  localIndex const localDofIndexPres = k[ke] * numDof;
243  stack.localFluxJacobian[k[0]*numEqn][localDofIndexPres] += m_dt * dFlux_dP[ke];
244  stack.localFluxJacobian[k[1]*numEqn][localDofIndexPres] -= m_dt * dFlux_dP[ke];
245  }
246 
247  // Customize the kernel with this lambda
248  kernelOp( k, regionIndex, subRegionIndex, elementIndex, connectionIndex, alpha, mobility, potGrad, fluxVal, dFlux_dP );
249 
250  connectionIndex++;
251  }
252  }
253  }
254 
260  template< typename FUNC = NoOpFunc >
262  void complete( localIndex const iconn,
263  StackVariables & stack,
264  FUNC && kernelOp = NoOpFunc{} ) const
265  {
266  // add contribution to residual and jacobian into:
267  // - the mass balance equation
268  // note that numDof includes derivatives wrt temperature if this class is derived in ThermalKernels
269  for( integer i = 0; i < stack.numFluxElems; ++i )
270  {
271  if( m_ghostRank[m_seri( iconn, i )][m_sesri( iconn, i )][m_sei( iconn, i )] < 0 )
272  {
273  globalIndex const globalRow = m_dofNumber[m_seri( iconn, i )][m_sesri( iconn, i )][m_sei( iconn, i )];
274  localIndex const localRow = LvArray::integerConversion< localIndex >( globalRow - m_rankOffset );
275  GEOS_ASSERT_GE( localRow, 0 );
276  GEOS_ASSERT_GT( m_localMatrix.numRows(), localRow );
277 
278  RAJA::atomicAdd( parallelDeviceAtomic{}, &m_localRhs[localRow], stack.localFlux[i * numEqn] );
279  m_localMatrix.addToRowBinarySearchUnsorted< parallelDeviceAtomic >( localRow,
280  stack.dofColIndices.data(),
281  stack.localFluxJacobian[i * numEqn].dataIfContiguous(),
282  stack.stencilSize * numDof );
283 
284  // call the lambda to assemble additional terms, such as thermal terms
285  kernelOp( i, localRow );
286  }
287  }
288  }
289 
297  template< typename POLICY, typename KERNEL_TYPE >
298  static void
299  launch( localIndex const numConnections,
300  KERNEL_TYPE const & kernelComponent )
301  {
303 
304  forAll< POLICY >( numConnections, [=] GEOS_HOST_DEVICE ( localIndex const iconn )
305  {
306  typename KERNEL_TYPE::StackVariables stack( kernelComponent.stencilSize( iconn ),
307  kernelComponent.numPointsInFlux( iconn ) );
308 
309  kernelComponent.setup( iconn, stack );
310  kernelComponent.computeFlux( iconn, stack );
311  kernelComponent.complete( iconn, stack );
312  } );
313  }
314 
315 
316 protected:
317 
318  // Stencil information
319 
321  STENCILWRAPPER const m_stencilWrapper;
322 
324  typename STENCILWRAPPER::IndexContainerViewConstType const m_seri;
325  typename STENCILWRAPPER::IndexContainerViewConstType const m_sesri;
326  typename STENCILWRAPPER::IndexContainerViewConstType const m_sei;
327 };
328 
333 {
334 public:
335 
349  template< typename POLICY, typename STENCILWRAPPER >
350  static void
351  createAndLaunch( globalIndex const rankOffset,
352  string const & dofKey,
353  string const & solverName,
354  ElementRegionManager const & elemManager,
355  STENCILWRAPPER const & stencilWrapper,
356  real64 const & dt,
357  CRSMatrixView< real64, globalIndex const > const & localMatrix,
358  arrayView1d< real64 > const & localRhs )
359  {
360  integer constexpr NUM_EQN = 1;
361  integer constexpr NUM_DOF = 1;
362 
364  elemManager.constructArrayViewAccessor< globalIndex, 1 >( dofKey );
365  dofNumberAccessor.setName( solverName + "/accessors/" + dofKey );
366 
368  typename kernelType::SinglePhaseFlowAccessors flowAccessors( elemManager, solverName );
369  typename kernelType::SinglePhaseFluidAccessors fluidAccessors( elemManager, solverName );
370  typename kernelType::PermeabilityAccessors permAccessors( elemManager, solverName );
371 
372  kernelType kernel( rankOffset, stencilWrapper, dofNumberAccessor,
373  flowAccessors, fluidAccessors, permAccessors,
374  dt, localMatrix, localRhs );
375  kernelType::template launch< POLICY >( stencilWrapper.size(), kernel );
376  }
377 };
378 
379 } // namespace singlePhaseFVMKernels
380 
381 } // namespace geos
382 
383 #endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_FLUXCOMPUTEKERNEL_HPP
#define GEOS_HOST_DEVICE
Marks a host-device function.
Definition: GeosxMacros.hpp:49
#define GEOS_ASSERT_GT(lhs, rhs)
Assert that one value compares greater than the other in debug builds.
Definition: Logger.hpp:440
#define GEOS_ASSERT_GE(lhs, rhs)
Assert that one value compares greater than or equal to the other in debug builds.
Definition: Logger.hpp:455
#define GEOS_MARK_FUNCTION
Mark function with both Caliper and NVTX if enabled.
The ElementRegionManager class provides an interface to ObjectManagerBase in order to manage ElementR...
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< VIEWTYPE > > ElementViewAccessor
The ElementViewAccessor at the ElementRegionManager level is an array of array of VIEWTYPE.
A struct to automatically construct and store element view accessors.
A struct to automatically construct and store element view accessors.
Base class for FluxComputeKernel that holds all data not dependent on template parameters (like stenc...
ElementViewConst< arrayView1d< real64 const > > const m_mob
Views on fluid mobility.
ElementViewConst< arrayView1d< integer const > > const m_ghostRank
Views on ghost rank numbers and gravity coefficients.
ElementViewConst< arrayView1d< globalIndex const > > const m_dofNumber
Views on dof numbers.
ElementViewConst< arrayView1d< real64 const > > const m_pres
Views on pressure.
arrayView1d< real64 > const m_localRhs
View on the local RHS.
ElementViewConst< arrayView3d< real64 const > > m_permeability
Views on permeability.
ElementViewConst< arrayView2d< real64 const > > const m_dens
Views on fluid density.
globalIndex const m_rankOffset
Offset for my MPI rank.
CRSMatrixView< real64, globalIndex const > const m_localMatrix
View on the local CRS matrix.
static void createAndLaunch(globalIndex const rankOffset, string const &dofKey, string const &solverName, ElementRegionManager const &elemManager, STENCILWRAPPER const &stencilWrapper, real64 const &dt, 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 flux terms.
static constexpr integer numEqn
Compute time value for the number of equations.
GEOS_HOST_DEVICE void setup(localIndex const iconn, StackVariables &stack) const
Performs the setup phase for the kernel.
static constexpr localIndex maxNumConns
Maximum number of connections at the face.
static void launch(localIndex const numConnections, KERNEL_TYPE const &kernelComponent)
Performs the kernel launch.
GEOS_HOST_DEVICE void complete(localIndex const iconn, StackVariables &stack, FUNC &&kernelOp=NoOpFunc{}) const
Performs the complete phase for the kernel.
static constexpr localIndex maxStencilSize
Maximum number of points in the stencil.
STENCILWRAPPER::IndexContainerViewConstType const m_seri
Connection to element maps.
static constexpr integer numDof
Compute time value for the number of degrees of freedom.
FluxComputeKernel(globalIndex const rankOffset, STENCILWRAPPER const &stencilWrapper, DofNumberAccessor const &dofNumberAccessor, SinglePhaseFlowAccessors const &singlePhaseFlowAccessors, SinglePhaseFluidAccessors const &singlePhaseFluidAccessors, PermeabilityAccessors const &permeabilityAccessors, real64 const &dt, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs)
Constructor for the kernel interface.
GEOS_HOST_DEVICE localIndex stencilSize(localIndex const iconn) const
Getter for the stencil size at this connection.
GEOS_HOST_DEVICE localIndex numPointsInFlux(localIndex const iconn) const
Getter for the number of elements at this connection.
STENCILWRAPPER const m_stencilWrapper
Reference to the stencil wrapper.
GEOS_HOST_DEVICE void computeFlux(localIndex const iconn, StackVariables &stack, FUNC &&kernelOp=NoOpFunc{}) const
Compute the local flux contributions to the residual and Jacobian.
static constexpr localIndex maxNumElems
Maximum number of elements at the face.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Definition: DataTypes.hpp:180
StackArray< T, 2, MAXSIZE > stackArray2d
Alias for 2D stack array.
Definition: DataTypes.hpp:204
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
StackArray< T, 1, MAXSIZE > stackArray1d
Alias for 1D stack array.
Definition: DataTypes.hpp:188
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
Kernel variables (dof numbers, jacobian and residual) located on the stack.
real64 dTrans_dPres[maxNumConns][2]
Derivatives of transmissibility with respect to pressure.
stackArray1d< globalIndex, maxNumElems *numDof > dofColIndices
Indices of the matrix rows/columns corresponding to the dofs in this face.
GEOS_HOST_DEVICE StackVariables(localIndex const size, localIndex numElems)
Constructor for the stack variables.
stackArray1d< real64, maxNumElems *numEqn > localFlux
Storage for the face local residual vector (all equations except volume balance)
localIndex const stencilSize
Stencil size for a given connection.
stackArray2d< real64, maxNumElems *numEqn *maxStencilSize *numDof > localFluxJacobian
Storage for the face local Jacobian matrix.
localIndex const numFluxElems
Number of elements for a given connection.