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_COMPOSITIONAL_STABILIZEDFLUXCOMPUTEKERNEL_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_STABILIZEDFLUXCOMPUTEKERNEL_HPP
22 
24 #include "constitutive/relativePermeability/RelativePermeabilityBase.hpp"
25 #include "constitutive/relativePermeability/RelativePermeabilityFields.hpp"
26 
27 namespace geos
28 {
29 
30 namespace stabilizedCompositionalMultiphaseFVMKernels
31 {
32 
33 /******************************** FluxComputeKernel ********************************/
34 
42 template< integer NUM_COMP, integer NUM_DOF, typename STENCILWRAPPER >
43 class FluxComputeKernel : public isothermalCompositionalMultiphaseFVMKernels::FluxComputeKernel< NUM_COMP, NUM_DOF, STENCILWRAPPER >
44 {
45 public:
46 
53  template< typename VIEWTYPE >
55 
57  using DofNumberAccessor = AbstractBase::DofNumberAccessor;
62 
63  using StabCompFlowAccessors =
64  StencilAccessors< fields::flow::macroElementIndex,
65  fields::flow::elementStabConstant,
66  fields::flow::pressure_n >;
67 
69  StencilMaterialAccessors< constitutive::MultiFluidBase,
70  fields::multifluid::phaseDensity_n,
71  fields::multifluid::phaseCompFraction_n >;
72 
73  using RelPermAccessors =
75 
76  using AbstractBase::m_dt;
78  using AbstractBase::m_kernelFlags;
82  using AbstractBase::m_gravCoef;
86 
88  using Base::numComp;
89  using Base::numDof;
90  using Base::numEqn;
92  using Base::maxNumElems;
93  using Base::maxNumConns;
95  using Base::m_phaseMob;
96  using Base::m_dPhaseMassDens;
98  using Base::m_seri;
99  using Base::m_sesri;
100  using Base::m_sei;
101 
120  FluxComputeKernel( integer const numPhases,
121  globalIndex const rankOffset,
122  STENCILWRAPPER const & stencilWrapper,
123  DofNumberAccessor const & dofNumberAccessor,
124  CompFlowAccessors const & compFlowAccessors,
125  StabCompFlowAccessors const & stabCompFlowAccessors,
126  MultiFluidAccessors const & multiFluidAccessors,
127  StabMultiFluidAccessors const & stabMultiFluidAccessors,
128  CapPressureAccessors const & capPressureAccessors,
129  PermeabilityAccessors const & permeabilityAccessors,
130  RelPermAccessors const & relPermAccessors,
131  real64 const & dt,
132  CRSMatrixView< real64, globalIndex const > const & localMatrix,
133  arrayView1d< real64 > const & localRhs,
134  BitFlags< isothermalCompositionalMultiphaseFVMKernels::KernelFlags > kernelFlags )
135  : Base( numPhases,
136  rankOffset,
137  stencilWrapper,
138  dofNumberAccessor,
139  compFlowAccessors,
140  multiFluidAccessors,
141  capPressureAccessors,
142  permeabilityAccessors,
143  dt,
144  localMatrix,
145  localRhs,
146  kernelFlags ),
147  m_pres_n( stabCompFlowAccessors.get( fields::flow::pressure_n {} ) ),
148  m_phaseDens_n( stabMultiFluidAccessors.get( fields::multifluid::phaseDensity_n {} ) ),
149  m_phaseCompFrac_n( stabMultiFluidAccessors.get( fields::multifluid::phaseCompFraction_n {} ) ),
150  m_phaseRelPerm_n( relPermAccessors.get( fields::relperm::phaseRelPerm_n {} ) ),
151  m_macroElementIndex( stabCompFlowAccessors.get( fields::flow::macroElementIndex {} ) ),
152  m_elementStabConstant( stabCompFlowAccessors.get( fields::flow::elementStabConstant {} ) )
153  {}
154 
156  {
157 public:
158 
160  StackVariables( localIndex const size, localIndex numElems )
161  : Base::StackVariables( size, numElems )
162  {}
163 
171 
174 
175  };
176 
183  void computeFlux( localIndex const iconn,
184  StackVariables & stack ) const
185  {
186 
187  m_stencilWrapper.computeStabilizationWeights( iconn,
188  stack.stabTransmissibility );
189 
190  // ***********************************************
191  // First, we call the base computeFlux to compute:
192  // 1) compFlux and its derivatives,
193  //
194  // We use the lambda below (called **inside** the phase loop of the base computeFlux) to compute stabilization terms
195  Base::computeFlux( iconn, stack, [&] ( integer const ip,
196  localIndex const (&k)[2],
197  localIndex const (&seri)[2],
198  localIndex const (&sesri)[2],
199  localIndex const (&sei)[2],
200  localIndex const connectionIndex,
201  localIndex const k_up,
202  localIndex const er_up,
203  localIndex const esr_up,
204  localIndex const ei_up,
205  real64 const potGrad,
206  real64 const phaseFlux,
207  real64 const (&dPhaseFlux_dP)[2],
208  real64 const (&dPhaseFlux_dC)[2][numComp] )
209  {
210  GEOS_UNUSED_VAR( k_up, potGrad, phaseFlux, dPhaseFlux_dP, dPhaseFlux_dC, er_up, esr_up, ei_up );
211 
213  real64 stabFlux[numComp]{};
214  real64 dStabFlux_dP[numFluxSupportPoints][numComp]{};
215 
216  real64 const stabTrans[numFluxSupportPoints] = { stack.stabTransmissibility[connectionIndex][0],
217  stack.stabTransmissibility[connectionIndex][1] };
218 
219  // we are in the loop over phases, ip provides the current phase index.
220 
221  real64 dPresGradStab = 0.0;
222  integer stencilMacroElements[numFluxSupportPoints]{};
223 
224  // Step 1: compute the pressure jump at the interface
225  for( integer ke = 0; ke < numFluxSupportPoints; ++ke )
226  {
227  localIndex const er = seri[ke];
228  localIndex const esr = sesri[ke];
229  localIndex const ei = sei[ke];
230 
231  stencilMacroElements[ke] = m_macroElementIndex[er][esr][ei];
232 
233  // use the jump in *delta* pressure in the stabilization term
234  dPresGradStab +=
235  m_elementStabConstant[er][esr][ei] * stabTrans[ke] * (m_pres[er][esr][ei] - m_pres_n[er][esr][ei]);
236  }
237 
238  // Step 2: compute the stabilization flux
239  integer const k_up_stab = (dPresGradStab >= 0) ? 0 : 1;
240 
241  localIndex const er_up_stab = seri[k_up_stab];
242  localIndex const esr_up_stab = sesri[k_up_stab];
243  localIndex const ei_up_stab = sei[k_up_stab];
244 
245  bool const areInSameMacroElement = stencilMacroElements[0] == stencilMacroElements[1];
246  bool const isStabilizationActive = stencilMacroElements[0] >= 0 && stencilMacroElements[1] >= 0;
247  if( isStabilizationActive && areInSameMacroElement )
248  {
249 
250  for( integer ic = 0; ic < numComp; ++ic )
251  {
252  real64 const laggedUpwindCoef = m_phaseDens_n[er_up_stab][esr_up_stab][ei_up_stab][0][ip]
253  * m_phaseCompFrac_n[er_up_stab][esr_up_stab][ei_up_stab][0][ip][ic]
254  * m_phaseRelPerm_n[er_up_stab][esr_up_stab][ei_up_stab][0][ip];
255  stabFlux[ic] += dPresGradStab * laggedUpwindCoef;
256 
257  for( integer ke = 0; ke < numFluxSupportPoints; ++ke )
258  {
259  real64 const tauStab = m_elementStabConstant[seri[ke]][sesri[ke]][sei[ke]];
260  dStabFlux_dP[ke][ic] += tauStab * stabTrans[ke] * laggedUpwindCoef;
261  }
262  }
263  }
264 
265  // Step 3: add the stabilization flux and its derivatives to the residual and Jacobian
266  for( integer ic = 0; ic < numComp; ++ic )
267  {
268  integer const eqIndex0 = k[0] * numEqn + ic;
269  integer const eqIndex1 = k[1] * numEqn + ic;
270 
271  stack.localFlux[eqIndex0] += stabFlux[ic];
272  stack.localFlux[eqIndex1] += -stabFlux[ic];
273 
274  for( integer ke = 0; ke < numFluxSupportPoints; ++ke )
275  {
276  localIndex const localDofIndexPres = k[ke] * numDof;
277  stack.localFluxJacobian[eqIndex0][localDofIndexPres] += dStabFlux_dP[ke][ic];
278  stack.localFluxJacobian[eqIndex1][localDofIndexPres] += -dStabFlux_dP[ke][ic];
279  }
280  }
281 
282  } ); // end call to Base::computeFlux
283 
284  }
285 
286 protected:
287 
293 
296  ElementViewConst< arrayView1d< real64 const > > const m_elementStabConstant;
297 
298 };
299 
304 {
305 public:
306 
323  template< typename POLICY, typename STENCILWRAPPER >
324  static void
325  createAndLaunch( integer const numComps,
326  integer const numPhases,
327  globalIndex const rankOffset,
328  string const & dofKey,
329  integer const hasCapPressure,
330  integer const useTotalMassEquation,
331  string const & solverName,
332  ElementRegionManager const & elemManager,
333  STENCILWRAPPER const & stencilWrapper,
334  real64 const dt,
335  CRSMatrixView< real64, globalIndex const > const & localMatrix,
336  arrayView1d< real64 > const & localRhs )
337  {
338  isothermalCompositionalMultiphaseBaseKernels::
339  internal::kernelLaunchSelectorCompSwitch( numComps, [&]( auto NC )
340  {
341  integer constexpr NUM_COMP = NC();
342  integer constexpr NUM_DOF = NC() + 1;
343 
345  elemManager.constructArrayViewAccessor< globalIndex, 1 >( dofKey );
346  dofNumberAccessor.setName( solverName + "/accessors/" + dofKey );
347 
348  BitFlags< isothermalCompositionalMultiphaseFVMKernels::KernelFlags > kernelFlags;
349  if( hasCapPressure )
350  kernelFlags.set( isothermalCompositionalMultiphaseFVMKernels::KernelFlags::CapPressure );
351  if( useTotalMassEquation )
352  kernelFlags.set( isothermalCompositionalMultiphaseFVMKernels::KernelFlags::TotalMassEquation );
353 
355  typename KERNEL_TYPE::CompFlowAccessors compFlowAccessors( elemManager, solverName );
356  typename KERNEL_TYPE::MultiFluidAccessors multiFluidAccessors( elemManager, solverName );
357  typename KERNEL_TYPE::StabCompFlowAccessors stabCompFlowAccessors( elemManager, solverName );
358  typename KERNEL_TYPE::StabMultiFluidAccessors stabMultiFluidAccessors( elemManager, solverName );
359  typename KERNEL_TYPE::CapPressureAccessors capPressureAccessors( elemManager, solverName );
360  typename KERNEL_TYPE::PermeabilityAccessors permeabilityAccessors( elemManager, solverName );
361  typename KERNEL_TYPE::RelPermAccessors relPermAccessors( elemManager, solverName );
362 
363  KERNEL_TYPE kernel( numPhases, rankOffset, stencilWrapper, dofNumberAccessor,
364  compFlowAccessors, stabCompFlowAccessors, multiFluidAccessors, stabMultiFluidAccessors,
365  capPressureAccessors, permeabilityAccessors, relPermAccessors,
366  dt, localMatrix, localRhs, kernelFlags );
367  KERNEL_TYPE::template launch< POLICY >( stencilWrapper.size(), kernel );
368  } );
369  }
370 };
371 
372 } // namespace stabilizedCompositionalMultiphaseFVMKernels
373 
374 } // namespace geos
375 
376 
377 #endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_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< globalIndex const > > const m_dofNumber
Views on dof numbers.
ElementViewConst< arrayView1d< real64 const > > const m_pres
Views on pressure.
ElementViewConst< arrayView1d< integer const > > const m_ghostRank
Views on ghost rank numbers and gravity coefficients.
ElementViewConst< arrayView4d< real64 const, constitutive::multifluid::USD_PHASE_COMP > > const m_phaseCompFrac
Views on phase component fractions.
ElementViewConst< arrayView3d< real64 const, compflow::USD_COMP_DC > > const m_dCompFrac_dCompDens
Views on derivatives of comp fractions.
Define the interface for the assembly kernel in charge of flux terms.
static constexpr localIndex maxStencilSize
Maximum number of points in the stencil.
GEOS_HOST_DEVICE void computeFlux(localIndex const iconn, StackVariables &stack, FUNC &&compFluxKernelOp=NoOpFunc{}) const
Compute the local flux contributions to the residual and Jacobian.
static constexpr integer numFluxSupportPoints
Number of flux support points (hard-coded for TFPA)
static constexpr integer numEqn
Compute time value for the number of equations (all of them, except the volume balance equation)
static constexpr integer numComp
Compile time value for the number of components.
ElementViewConst< arrayView2d< real64 const, compflow::USD_PHASE > > const m_phaseMob
Views on phase mobilities.
STENCILWRAPPER::IndexContainerViewConstType const m_seri
Connection to element maps.
static constexpr localIndex maxNumElems
Maximum number of elements at the face.
static constexpr integer numDof
Compute time value for the number of degrees of freedom.
STENCILWRAPPER const m_stencilWrapper
Reference to the stencil wrapper.
static constexpr localIndex maxNumConns
Maximum number of connections at the face.
static void createAndLaunch(integer const numComps, integer const numPhases, globalIndex const rankOffset, string const &dofKey, integer const hasCapPressure, integer const useTotalMassEquation, 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.
ElementViewConst< arrayView1d< real64 const > > const m_pres_n
Views on flow properties at the previous converged time step.
ElementViewConst< arrayView1d< integer const > > const m_macroElementIndex
Views on the macroelement indices and stab constant.
ElementViewConst< arrayView1d< real64 const > > const m_pres
Views on pressure.
static constexpr integer numFluxSupportPoints
Number of flux support points (hard-coded for TFPA)
static constexpr integer numEqn
Compute time value for the number of equations (all of them, except the volume balance equation)
static constexpr integer numComp
Compile time value for the number of components.
GEOS_HOST_DEVICE void computeFlux(localIndex const iconn, StackVariables &stack) const
Compute the local flux contributions to the residual and Jacobian, including stabilization.
FluxComputeKernel(integer const numPhases, globalIndex const rankOffset, STENCILWRAPPER const &stencilWrapper, DofNumberAccessor const &dofNumberAccessor, CompFlowAccessors const &compFlowAccessors, StabCompFlowAccessors const &stabCompFlowAccessors, MultiFluidAccessors const &multiFluidAccessors, StabMultiFluidAccessors const &stabMultiFluidAccessors, CapPressureAccessors const &capPressureAccessors, PermeabilityAccessors const &permeabilityAccessors, RelPermAccessors const &relPermAccessors, real64 const &dt, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs, BitFlags< isothermalCompositionalMultiphaseFVMKernels::KernelFlags > kernelFlags)
Constructor for the kernel interface.
ElementRegionManager::ElementViewConst< VIEWTYPE > ElementViewConst
The type for element-based data. Consists entirely of ArrayView's.
static constexpr integer numDof
Compute time value for the number of degrees of freedom.
STENCILWRAPPER const m_stencilWrapper
Reference to the stencil wrapper.
static constexpr localIndex maxNumConns
Maximum number of connections at the face.
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][numFluxSupportPoints]
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.
stackArray2d< real64, maxNumElems *numEqn *maxStencilSize *numDof > localFluxJacobian
Storage for the face local Jacobian matrix.
stackArray1d< real64, maxNumElems *numEqn > localFlux
Storage for the face local residual vector (all equations except volume balance)
localIndex const numConnectedElems
Number of elements connected at a given connection.
real64 transmissibility[maxNumConns][numFluxSupportPoints]
Transmissibility.
real64 stabTransmissibility[maxNumConns][numFluxSupportPoints]
Stabilization transmissibility.