GEOS
StabilizedFluxComputeKernel.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_SINGLEPHASE_STABILIZEDFLUXCOMPUTEKERNEL_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_STABILIZEDFLUXCOMPUTEKERNEL_HPP
22 
24 
25 namespace geos
26 {
27 
28 namespace stabilizedSinglePhaseFVMKernels
29 {
30 
31 /******************************** FluxComputeKernel ********************************/
32 
39 template< integer NUM_EQN, integer NUM_DOF, typename STENCILWRAPPER >
40 class FluxComputeKernel : public singlePhaseFVMKernels::FluxComputeKernel< NUM_EQN, NUM_DOF, STENCILWRAPPER >
41 {
42 public:
43 
44  template< typename VIEWTYPE >
46 
48  using DofNumberAccessor = AbstractBase::DofNumberAccessor;
52 
54  StencilAccessors< fields::flow::macroElementIndex,
55  fields::flow::elementStabConstant,
56  fields::flow::pressure_n >;
57 
59  StencilMaterialAccessors< constitutive::SingleFluidBase,
60  fields::singlefluid::density_n >;
61 
62  using AbstractBase::m_dt;
66  using AbstractBase::m_gravCoef;
68 
70  using Base::numDof;
71  using Base::numEqn;
72  using Base::maxNumElems;
73  using Base::maxNumConns;
76  using Base::m_seri;
77  using Base::m_sesri;
78  using Base::m_sei;
79 
94  FluxComputeKernel( globalIndex const rankOffset,
95  STENCILWRAPPER const & stencilWrapper,
96  DofNumberAccessor const & dofNumberAccessor,
97  SinglePhaseFlowAccessors const & singlePhaseFlowAccessors,
98  StabSinglePhaseFlowAccessors const & stabSinglePhaseFlowAccessors,
99  SinglePhaseFluidAccessors const & singlePhaseFluidAccessors,
100  StabSinglePhaseFluidAccessors const & stabSinglePhaseFluidAccessors,
101  PermeabilityAccessors const & permeabilityAccessors,
102  real64 const & dt,
103  CRSMatrixView< real64, globalIndex const > const & localMatrix,
104  arrayView1d< real64 > const & localRhs )
105  : Base( rankOffset,
106  stencilWrapper,
107  dofNumberAccessor,
108  singlePhaseFlowAccessors,
109  singlePhaseFluidAccessors,
110  permeabilityAccessors,
111  dt,
112  localMatrix,
113  localRhs ),
114  m_pres_n( stabSinglePhaseFlowAccessors.get( fields::flow::pressure_n {} ) ),
115  m_dens_n( stabSinglePhaseFluidAccessors.get( fields::singlefluid::density_n {} ) ),
116  m_macroElementIndex( stabSinglePhaseFlowAccessors.get( fields::flow::macroElementIndex {} ) ),
117  m_elementStabConstant( stabSinglePhaseFlowAccessors.get( fields::flow::elementStabConstant {} ) )
118  {}
119 
121  {
122 public:
123 
125  StackVariables( localIndex const size, localIndex numElems )
126  : Base::StackVariables( size, numElems )
127  {}
128 
136 
139 
140  };
141 
148  void computeFlux( localIndex const iconn,
149  StackVariables & stack ) const
150  {
151 
152  m_stencilWrapper.computeStabilizationWeights( iconn,
153  stack.stabTransmissibility );
154 
155  // ***********************************************
156  // We call the base computeFlux,
157  //
158  // We use the lambda below to compute stabilization terms
159  Base::computeFlux( iconn, stack, [&] ( localIndex const (&k)[2],
160  localIndex const (&seri)[2],
161  localIndex const (&sesri)[2],
162  localIndex const (&sei)[2],
163  localIndex const connectionIndex,
164  real64 const alpha,
165  real64 const mobility,
166  real64 const potGrad,
167  real64 const fluxVal,
168  real64 const (&dFlux_dP)[2] )
169  {
170 
171  GEOS_UNUSED_VAR( alpha, mobility, potGrad, fluxVal, dFlux_dP );
172 
174  real64 stabFlux{};
175  real64 dStabFlux_dP[2]{};
176 
177  real64 const stabTrans[2] = { stack.stabTransmissibility[connectionIndex][0],
178  stack.stabTransmissibility[connectionIndex][1] };
179 
180 
181  real64 dPresGradStab = 0.0;
182  integer stencilMacroElements[2]{};
183 
184  // Step 1: compute the pressure jump at the interface
185  for( integer ke = 0; ke < stack.numFluxElems; ++ke )
186  {
187  localIndex const er = seri[ke];
188  localIndex const esr = sesri[ke];
189  localIndex const ei = sei[ke];
190 
191  stencilMacroElements[ke] = m_macroElementIndex[er][esr][ei];
192 
193  // use the jump in *delta* pressure in the stabilization term
194  dPresGradStab += m_elementStabConstant[er][esr][ei] * stabTrans[ke] * (m_pres[er][esr][ei] - m_pres_n[er][esr][ei]);
195  }
196 
197  // Step 2: compute the stabilization flux
198  integer const k_up_stab = (dPresGradStab >= 0) ? 0 : 1;
199 
200  localIndex const er_up_stab = seri[k_up_stab];
201  localIndex const esr_up_stab = sesri[k_up_stab];
202  localIndex const ei_up_stab = sei[k_up_stab];
203 
204  bool const areInSameMacroElement = stencilMacroElements[0] == stencilMacroElements[1];
205  bool const isStabilizationActive = stencilMacroElements[0] >= 0 && stencilMacroElements[1] >= 0;
206  if( isStabilizationActive && areInSameMacroElement )
207  {
208 
209  real64 const laggedUpwindCoef = m_dens_n[er_up_stab][esr_up_stab][ei_up_stab][0];
210  stabFlux += dPresGradStab * laggedUpwindCoef;
211 
212  for( integer ke = 0; ke < stack.numFluxElems; ++ke )
213  {
214  real64 const tauStab = m_elementStabConstant[seri[ke]][sesri[ke]][sei[ke]];
215  dStabFlux_dP[ke] += tauStab * stabTrans[ke] * laggedUpwindCoef;
216  }
217  }
218 
219  // Step 3: add the stabilization flux and its derivatives to the residual and Jacobian
220  integer const eqIndex0 = k[0] * numEqn;
221  integer const eqIndex1 = k[1] * numEqn;
222 
223  stack.localFlux[eqIndex0] += stabFlux;
224  stack.localFlux[eqIndex1] += -stabFlux;
225 
226  for( integer ke = 0; ke < stack.numFluxElems; ++ke )
227  {
228  localIndex const localDofIndexPres = k[ke] * numDof;
229  stack.localFluxJacobian[eqIndex0][localDofIndexPres] += dStabFlux_dP[ke];
230  stack.localFluxJacobian[eqIndex1][localDofIndexPres] += -dStabFlux_dP[ke];
231  }
232 
233  } ); // end call to Base::computeFlux
234 
235  }
236 
237 protected:
238 
240  ElementViewConst< arrayView1d< real64 const > > const m_pres_n;
241  ElementViewConst< arrayView2d< real64 const > > const m_dens_n;
242 
244  ElementViewConst< arrayView1d< integer const > > const m_macroElementIndex;
245  ElementViewConst< arrayView1d< real64 const > > const m_elementStabConstant;
246 
247 };
248 
253 {
254 public:
255 
269  template< typename POLICY, typename STENCILWRAPPER >
270  static void
271  createAndLaunch( globalIndex const rankOffset,
272  string const & dofKey,
273  string const & solverName,
274  ElementRegionManager const & elemManager,
275  STENCILWRAPPER const & stencilWrapper,
276  real64 const dt,
277  CRSMatrixView< real64, globalIndex const > const & localMatrix,
278  arrayView1d< real64 > const & localRhs )
279  {
280 
281  integer constexpr NUM_EQN = 1;
282  integer constexpr NUM_DOF = 1;
283 
285  elemManager.constructArrayViewAccessor< globalIndex, 1 >( dofKey );
286  dofNumberAccessor.setName( solverName + "/accessors/" + dofKey );
287 
289  typename KERNEL_TYPE::SinglePhaseFlowAccessors singlePhaseFlowAccessors( elemManager, solverName );
290  typename KERNEL_TYPE::SinglePhaseFluidAccessors singlePhaseFluidAccessors( elemManager, solverName );
291  typename KERNEL_TYPE::StabSinglePhaseFlowAccessors stabSinglePhaseFlowAccessors( elemManager, solverName );
292  typename KERNEL_TYPE::StabSinglePhaseFluidAccessors stabSinglePhaseFluidAccessors( elemManager, solverName );
293  typename KERNEL_TYPE::PermeabilityAccessors permeabilityAccessors( elemManager, solverName );
294 
295  KERNEL_TYPE kernel( rankOffset, stencilWrapper, dofNumberAccessor,
296  singlePhaseFlowAccessors, stabSinglePhaseFlowAccessors, singlePhaseFluidAccessors, stabSinglePhaseFluidAccessors,
297  permeabilityAccessors,
298  dt, localMatrix, localRhs );
299  KERNEL_TYPE::template launch< POLICY >( stencilWrapper.size(), kernel );
300  }
301 };
302 
303 } // namespace stabilizedSinglePhaseFVMKernels
304 
305 } // namespace geos
306 
307 
308 #endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_STABILIZEDFLUXCOMPUTEKERNEL_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
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.
typename ElementViewAccessor< VIEWTYPE >::NestedViewTypeConst ElementViewConst
The ElementViewAccessor at the ElementRegionManager level is the type resulting from ElementViewAcces...
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< 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.
globalIndex const m_rankOffset
Offset for my MPI rank.
Define the interface for the assembly kernel in charge of flux terms.
static constexpr integer numEqn
Compute time value for the number of equations.
static constexpr localIndex maxNumConns
Maximum number of connections at the face.
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.
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.
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.
ElementViewConst< arrayView1d< integer const > > const m_macroElementIndex
Views on the macroelement indices and stab constant.
FluxComputeKernel(globalIndex const rankOffset, STENCILWRAPPER const &stencilWrapper, DofNumberAccessor const &dofNumberAccessor, SinglePhaseFlowAccessors const &singlePhaseFlowAccessors, StabSinglePhaseFlowAccessors const &stabSinglePhaseFlowAccessors, SinglePhaseFluidAccessors const &singlePhaseFluidAccessors, StabSinglePhaseFluidAccessors const &stabSinglePhaseFluidAccessors, PermeabilityAccessors const &permeabilityAccessors, real64 const &dt, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs)
Constructor for the kernel interface.
static constexpr localIndex maxNumConns
Maximum number of connections at the face.
ElementViewConst< arrayView1d< real64 const > > const m_pres
Views on pressure.
ElementViewConst< arrayView1d< real64 const > > const m_pres_n
Views on flow properties at the previous converged time step.
static constexpr integer numDof
Compute time value for the number of degrees of freedom.
GEOS_HOST_DEVICE void computeFlux(localIndex const iconn, StackVariables &stack) const
Compute the local flux contributions to the residual and Jacobian, including stabilization.
STENCILWRAPPER const m_stencilWrapper
Reference to the stencil wrapper.
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
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.
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.
real64 stabTransmissibility[maxNumConns][2]
Stabilization transmissibility.