GEOS
ThermalDiffusionDispersionFluxComputeKernel.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_THERMALDIFFUSIONDISPERSIONFLUXCOMPUTEKERNEL_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_THERMALDIFFUSIONDISPERSIONFLUXCOMPUTEKERNEL_HPP
22 
24 
25 namespace geos
26 {
27 
28 namespace thermalCompositionalMultiphaseFVMKernels
29 {
30 
31 /******************************** DiffusionDispersionFluxComputeKernel ********************************/
32 
40 template< integer NUM_COMP, integer NUM_DOF, typename STENCILWRAPPER >
43 {
44 public:
45 
52  template< typename VIEWTYPE >
54 
56  using DofNumberAccessor = AbstractBase::DofNumberAccessor;
59  using AbstractBase::m_dt;
60  using AbstractBase::m_dPhaseCompFrac;
61  using AbstractBase::m_dPhaseVolFrac;
62 
64  using DiffusionAccessors = typename Base::DiffusionAccessors;
65  using DispersionAccessors = typename Base::DispersionAccessors;
66  using PorosityAccessors = typename Base::PorosityAccessors;
67  using Base::numFluxSupportPoints;
68  using Base::numEqn;
69  using Base::numComp;
70  using Base::numDof;
71  using Base::m_referencePorosity;
72  using Base::m_phaseVolFrac;
73  using Base::m_phaseDens;
74  using Base::m_dPhaseDens;
75  using Base::m_phaseDiffusivityMultiplier;
76 
94  globalIndex const rankOffset,
95  STENCILWRAPPER const & stencilWrapper,
96  DofNumberAccessor const & dofNumberAccessor,
97  CompFlowAccessors const & compFlowAccessors,
98  MultiFluidAccessors const & multiFluidAccessors,
99  DiffusionAccessors const & diffusionAccessors,
100  DispersionAccessors const & dispersionAccessors,
101  PorosityAccessors const & porosityAccessors,
102  real64 const dt,
103  CRSMatrixView< real64, globalIndex const > const & localMatrix,
104  arrayView1d< real64 > const & localRhs,
105  BitFlags< isothermalCompositionalMultiphaseFVMKernels::KernelFlags > kernelFlags )
106  : Base( numPhases,
107  rankOffset,
108  stencilWrapper,
109  dofNumberAccessor,
110  compFlowAccessors,
111  multiFluidAccessors,
112  diffusionAccessors,
113  dispersionAccessors,
114  porosityAccessors,
115  dt,
116  localMatrix,
117  localRhs,
118  kernelFlags )
119  {}
120 
121  struct StackVariables : public Base::StackVariables
122  {
123 public:
124 
126  StackVariables( localIndex const size, localIndex numElems )
127  : Base::StackVariables( size, numElems )
128  {}
129 
130  using Base::StackVariables::transmissibility;
131  using Base::StackVariables::localFlux;
132  using Base::StackVariables::localFluxJacobian;
133 
134  };
135 
142  inline
143  void computeDiffusionFlux( localIndex const iconn,
144  StackVariables & stack ) const
145  {
146  using Deriv = constitutive::multifluid::DerivativeOffset;
147 
148  // ***********************************************
149  // First, we call the base computeFlux to compute the diffusionFlux and its derivatives (including derivatives wrt temperature),
150  //
151  // We use the lambda below (called **inside** the phase loop of the base computeFlux) to access these variables
152  Base::computeDiffusionFlux( iconn, stack, [&] ( integer const ip,
153  integer const ic,
154  localIndex const (&k)[2],
155  localIndex const (&seri)[2],
156  localIndex const (&sesri)[2],
157  localIndex const (&sei)[2],
158  localIndex const connectionIndex,
159  localIndex const k_up,
160  localIndex const er_up,
161  localIndex const esr_up,
162  localIndex const ei_up,
163  real64 const compFracGrad,
164  real64 const upwindCoefficient )
165  {
166  // We are in the loop over phases and components, ip provides the current phase index.
167 
168  real64 dCompFracGrad_dT[numFluxSupportPoints]{};
169  real64 dDiffusionFlux_dT[numFluxSupportPoints]{};
170 
172  for( integer i = 0; i < numFluxSupportPoints; i++ )
173  {
174  localIndex const er = seri[i];
175  localIndex const esr = sesri[i];
176  localIndex const ei = sei[i];
177 
178  dCompFracGrad_dT[i] += stack.transmissibility[connectionIndex][i] * m_dPhaseCompFrac[er][esr][ei][0][ip][ic][Deriv::dT];
179  }
180 
181  // add contributions of the derivatives of component fractions wrt pressure/component fractions
182  for( integer ke = 0; ke < numFluxSupportPoints; ++ke )
183  {
184  dDiffusionFlux_dT[ke] += upwindCoefficient * dCompFracGrad_dT[ke];
185  }
186 
187  // add contributions of the derivatives of upwind coefficient wrt temperature
188  real64 const dUpwindCoefficient_dT =
189  m_referencePorosity[er_up][esr_up][ei_up] *
190  m_phaseDiffusivityMultiplier[er_up][esr_up][ei_up][0][ip] *
191  ( m_dPhaseDens[er_up][esr_up][ei_up][0][ip][Deriv::dT] * m_phaseVolFrac[er_up][esr_up][ei_up][ip]
192  + m_phaseDens[er_up][esr_up][ei_up][0][ip] * m_dPhaseVolFrac[er_up][esr_up][ei_up][ip][Deriv::dT] );
193  dDiffusionFlux_dT[k_up] += dUpwindCoefficient_dT * compFracGrad;
194 
195  // finally, increment local flux and local Jacobian
196  integer const eqIndex0 = k[0] * numEqn + ic;
197  integer const eqIndex1 = k[1] * numEqn + ic;
198 
199  for( integer ke = 0; ke < numFluxSupportPoints; ++ke )
200  {
201  localIndex const localDofIndexTemp = k[ke] * numDof + numComp + 1;
202  stack.localFluxJacobian[eqIndex0][localDofIndexTemp] += m_dt * dDiffusionFlux_dT[ke];
203  stack.localFluxJacobian[eqIndex1][localDofIndexTemp] -= m_dt * dDiffusionFlux_dT[ke];
204  }
205  } );
206  }
207 
214  inline
216  StackVariables & stack ) const
217  {
218  using Deriv = constitutive::multifluid::DerivativeOffset;
219 
220  // ***********************************************
221  // First, we call the base computeFlux to compute the dispersionFlux and its derivatives (including derivatives wrt temperature),
222  //
223  // We use the lambda below (called **inside** the phase loop of the base computeFlux) to access these variables
224  Base::computeDispersionFlux( iconn, stack, [&] ( integer const ip,
225  integer const ic,
226  localIndex const (&k)[2],
227  localIndex const (&seri)[2],
228  localIndex const (&sesri)[2],
229  localIndex const (&sei)[2],
230  localIndex const connectionIndex,
231  localIndex const k_up,
232  localIndex const er_up,
233  localIndex const esr_up,
234  localIndex const ei_up,
235  real64 const compFracGrad )
236  {
237  // We are in the loop over phases and components, ip provides the current phase index.
238 
239  real64 dCompFracGrad_dT[numFluxSupportPoints]{};
240  real64 dDispersionFlux_dT[numFluxSupportPoints]{};
241 
243  for( integer i = 0; i < numFluxSupportPoints; i++ )
244  {
245  localIndex const er = seri[i];
246  localIndex const esr = sesri[i];
247  localIndex const ei = sei[i];
248 
249  dCompFracGrad_dT[i] += stack.transmissibility[connectionIndex][i] * m_dPhaseCompFrac[er][esr][ei][0][ip][ic][Deriv::dT];
250  }
251 
252  // add contributions of the derivatives of component fractions wrt pressure/component fractions
253  for( integer ke = 0; ke < numFluxSupportPoints; ++ke )
254  {
255  dDispersionFlux_dT[ke] += m_phaseDens[er_up][esr_up][ei_up][0][ip] * dCompFracGrad_dT[ke];
256  }
257 
258  // add contributions of the derivatives of upwind coefficient wrt temperature
259  dDispersionFlux_dT[k_up] += m_dPhaseDens[er_up][esr_up][ei_up][0][ip][Deriv::dT] * compFracGrad;
260 
261  // finally, increment local flux and local Jacobian
262  integer const eqIndex0 = k[0] * numEqn + ic;
263  integer const eqIndex1 = k[1] * numEqn + ic;
264 
265  for( integer ke = 0; ke < numFluxSupportPoints; ++ke )
266  {
267  localIndex const localDofIndexTemp = k[ke] * numDof + numComp + 1;
268  stack.localFluxJacobian[eqIndex0][localDofIndexTemp] += m_dt * dDispersionFlux_dT[ke];
269  stack.localFluxJacobian[eqIndex1][localDofIndexTemp] -= m_dt * dDispersionFlux_dT[ke];
270  }
271  } );
272  }
273 };
274 
279 {
280 public:
281 
299  template< typename POLICY, typename STENCILWRAPPER >
300  static void
301  createAndLaunch( integer const numComps,
302  integer const numPhases,
303  globalIndex const rankOffset,
304  string const & dofKey,
305  integer const hasDiffusion,
306  integer const hasDispersion,
307  integer const useTotalMassEquation,
308  string const & solverName,
309  ElementRegionManager const & elemManager,
310  STENCILWRAPPER const & stencilWrapper,
311  real64 const dt,
312  CRSMatrixView< real64, globalIndex const > const & localMatrix,
313  arrayView1d< real64 > const & localRhs )
314  {
315  isothermalCompositionalMultiphaseBaseKernels::
316  internal::kernelLaunchSelectorCompSwitch( numComps, [&]( auto NC )
317  {
318  integer constexpr NUM_COMP = NC();
319  integer constexpr NUM_DOF = NC() + 2;
320 
322  elemManager.constructArrayViewAccessor< globalIndex, 1 >( dofKey );
323  dofNumberAccessor.setName( solverName + "/accessors/" + dofKey );
324 
325  BitFlags< isothermalCompositionalMultiphaseFVMKernels::KernelFlags > kernelFlags;
326  if( useTotalMassEquation )
327  kernelFlags.set( isothermalCompositionalMultiphaseFVMKernels::KernelFlags::TotalMassEquation );
328 
330  typename kernelType::CompFlowAccessors compFlowAccessors( elemManager, solverName );
331  typename kernelType::MultiFluidAccessors multiFluidAccessors( elemManager, solverName );
332  typename kernelType::DiffusionAccessors diffusionAccessors( elemManager, solverName );
333  typename kernelType::DispersionAccessors dispersionAccessors( elemManager, solverName );
334  typename kernelType::PorosityAccessors porosityAccessors( elemManager, solverName );
335 
336  kernelType kernel( numPhases, rankOffset, stencilWrapper,
337  dofNumberAccessor, compFlowAccessors, multiFluidAccessors,
338  diffusionAccessors, dispersionAccessors, porosityAccessors,
339  dt, localMatrix, localRhs, kernelFlags );
340  kernelType::template launch< POLICY >( stencilWrapper.size(),
341  hasDiffusion, hasDispersion,
342  kernel );
343  } );
344  }
345 };
346 
347 } // namespace thermalCompositionalMultiphaseFVMKernels
348 
349 } // namespace geos
350 
351 
352 #endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_THERMALDIFFUSIONDISPERSIONFLUXCOMPUTEKERNEL_HPP
#define GEOS_HOST_DEVICE
Marks a host-device function.
Definition: GeosxMacros.hpp:49
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.
Define the interface for the assembly kernel in charge of diffusion/dispersion flux terms.
ElementViewConst< arrayView1d< real64 const > > const m_referencePorosity
View on the reference porosity.
ElementViewConst< arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > > const m_phaseDens
Views on phase densities.
static constexpr integer numDof
Compute time value for the number of degrees of freedom.
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)
ElementViewConst< arrayView2d< real64 const, compflow::USD_PHASE > > const m_phaseVolFrac
Views on phase volume fraction.
Base class for FluxComputeKernel that holds all data not dependent on template parameters (like stenc...
ElementRegionManager::ElementViewConst< VIEWTYPE > ElementViewConst
The type for element-based data. Consists entirely of ArrayView's.
static void createAndLaunch(integer const numComps, integer const numPhases, globalIndex const rankOffset, string const &dofKey, integer const hasDiffusion, integer const hasDispersion, 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 diffusion/dispersion flux terms.
DiffusionDispersionFluxComputeKernel(integer const numPhases, globalIndex const rankOffset, STENCILWRAPPER const &stencilWrapper, DofNumberAccessor const &dofNumberAccessor, CompFlowAccessors const &compFlowAccessors, MultiFluidAccessors const &multiFluidAccessors, DiffusionAccessors const &diffusionAccessors, DispersionAccessors const &dispersionAccessors, PorosityAccessors const &porosityAccessors, real64 const dt, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs, BitFlags< isothermalCompositionalMultiphaseFVMKernels::KernelFlags > kernelFlags)
Constructor for the kernel interface.
GEOS_HOST_DEVICE void computeDiffusionFlux(localIndex const iconn, StackVariables &stack) const
Compute the local diffusion flux contributions to the residual and Jacobian.
GEOS_HOST_DEVICE void computeDispersionFlux(localIndex const iconn, StackVariables &stack) const
Compute the local dispersion flux contributions to the residual and Jacobian.
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