GEOS
DissipationFluxComputeKernel.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_COMPOSITIONAL_DISSIPATIONFLUXCOMPUTEKERNEL_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_DISSIPATIONFLUXCOMPUTEKERNEL_HPP
22 
25 #include "constitutive/solid/porosity/PorosityBase.hpp"
26 #include "constitutive/solid/porosity/PorosityFields.hpp"
27 
28 namespace geos
29 {
30 
31 namespace dissipationCompositionalMultiphaseFVMKernels
32 {
33 
34 static constexpr integer newtonContinuationCutoffIteration = 5;
35 static constexpr real64 initialDirectionalCoef = 100;
36 static constexpr real64 multiplierDirectionalCoef = 1000;
37 
38 /******************************** FluxComputeKernel ********************************/
39 
47 template< integer NUM_COMP, integer NUM_DOF, typename STENCILWRAPPER >
48 class FluxComputeKernel : public isothermalCompositionalMultiphaseFVMKernels::FluxComputeKernel< NUM_COMP, NUM_DOF, STENCILWRAPPER >
49 {
50 public:
51 
58  template< typename VIEWTYPE >
60 
62  using DofNumberAccessor = AbstractBase::DofNumberAccessor;
67 
68  using AbstractBase::m_dt;
69  using AbstractBase::m_gravCoef;
71 
73  using Base::numComp;
74  using Base::numDof;
75  using Base::numEqn;
78  using Base::m_dPerm_dPres;
79 
80  using DissCompFlowAccessors =
81  StencilAccessors< fields::flow::pressure_n,
82  fields::flow::globalCompDensity,
83  fields::flow::globalCompFraction,
85 
86  using PorosityAccessors =
88 
89  using Deriv = constitutive::multifluid::DerivativeOffset;
90 
114  FluxComputeKernel( integer const numPhases,
115  globalIndex const rankOffset,
116  STENCILWRAPPER const & stencilWrapper,
117  DofNumberAccessor const & dofNumberAccessor,
118  CompFlowAccessors const & compFlowAccessors,
119  DissCompFlowAccessors const & dissCompFlowAccessors,
120  MultiFluidAccessors const & multiFluidAccessors,
121  CapPressureAccessors const & capPressureAccessors,
122  PermeabilityAccessors const & permeabilityAccessors,
123  PorosityAccessors const & porosityAccessors,
124  real64 const & dt,
125  CRSMatrixView< real64, globalIndex const > const & localMatrix,
126  arrayView1d< real64 > const & localRhs,
127  BitFlags< isothermalCompositionalMultiphaseFVMKernels::KernelFlags > kernelFlags,
128  real64 const omega,
129  integer const curNewton,
130  integer const continuation,
131  integer const miscible,
132  real64 const kappamin,
133  real64 const contMultiplier )
134  : Base( numPhases,
135  rankOffset,
136  stencilWrapper,
137  dofNumberAccessor,
138  compFlowAccessors,
139  multiFluidAccessors,
140  capPressureAccessors,
141  permeabilityAccessors,
142  dt,
143  localMatrix,
144  localRhs,
145  kernelFlags ),
146  m_pres_n( dissCompFlowAccessors.get( fields::flow::pressure_n {} ) ),
147  m_porosity_n( porosityAccessors.get( fields::porosity::porosity_n {} ) ),
148  m_volume( dissCompFlowAccessors.get( fields::elementVolume {} ) ),
149  m_compFrac( dissCompFlowAccessors.get( fields::flow::globalCompFraction {} ) ),
150  m_omegaDBC( omega ),
151  m_miscibleDBC( miscible )
152  {
154  m_kappaDBC = 1.0; // default value
155 
156  if( continuation ) // if continuation is enabled
157  {
158  if( curNewton >= newtonContinuationCutoffIteration )
159  {
160  m_kappaDBC = kappamin;
161  }
162  else
163  {
164  for( int mp = 0; mp < curNewton; mp++ )
165  {
166  m_kappaDBC *= contMultiplier;
167  }
168  m_kappaDBC = std::max( m_kappaDBC, kappamin );
169  }
170  }
171  }
172 
179  void computeFlux( localIndex const iconn,
180  typename Base::StackVariables & stack ) const
181  {
182  // ***********************************************
183  // First, we call the base computeFlux to compute:
184  // 1) compFlux and its derivatives,
185  //
186  // We use the lambda below (called **inside** the phase loop of the base computeFlux) to compute dissipation terms
187  Base::computeFlux( iconn, stack, [&] ( integer const ip,
188  integer const GEOS_UNUSED_PARAM( checkPhasePresenceInGravity ),
189  localIndex const (&k)[2],
190  localIndex const (&seri)[2],
191  localIndex const (&sesri)[2],
192  localIndex const (&sei)[2],
193  localIndex const connectionIndex,
194  localIndex const k_up,
195  localIndex const er_up,
196  localIndex const esr_up,
197  localIndex const ei_up,
198  real64 const & potGrad,
199  real64 const & phaseFlux,
200  real64 const (&dPhaseFlux_dP)[2],
201  real64 const (&dPhaseFlux_dC)[2][numComp] )
202  {
203  GEOS_UNUSED_VAR( k_up, potGrad, phaseFlux, dPhaseFlux_dP, dPhaseFlux_dC, er_up, esr_up, ei_up );
204 
206  real64 dissFlux[numComp]{};
207  real64 dDissFlux_dP[numFluxSupportPoints][numComp]{};
208  real64 dDissFlux_dC[numFluxSupportPoints][numComp][numComp]{};
209  real64 fluxPointCoef[numFluxSupportPoints] = {1.0, -1.0}; // for gradients
210 
211  real64 viscosityMult[3] = {1.0, 1.0, 1.0}; // for viscosity
212 
214  real64 poreVolume_n = 0.0; // Pore volume contribution
215  for( integer ke = 0; ke < numFluxSupportPoints; ++ke )
216  {
217  poreVolume_n += m_volume[seri[ke]][sesri[ke]][sei[ke]] * m_porosity_n[seri[ke]][sesri[ke]][sei[ke]][0];
218  }
219  poreVolume_n /= numFluxSupportPoints;
220 
221  // potential gradient contribution
222  // pressure
223  real64 pressure_gradient = 0;
224  for( integer ke = 0; ke < numFluxSupportPoints; ++ke )
225  pressure_gradient += fluxPointCoef[ke] * m_pres_n[seri[ke]][sesri[ke]][sei[ke]];
226 
227  real64 const potential_gradient = LvArray::math::abs( pressure_gradient );
228 
229  real64 grad_depth = 0;
230  for( integer ke = 0; ke < numFluxSupportPoints; ++ke )
231  {
232  grad_depth += fluxPointCoef[ke] * m_gravCoef[seri[ke]][sesri[ke]][sei[ke]];
233  }
234 
235  // bias towards x and y direction for miscible
236  /* The point of this "directional coefficient" was to add less dissipation flux in the direction of gravity and
237  more in all other directions. These hard-coded values of 1000 and 100 were picked by some tuning and as
238  expected are not robust. Further research/testing is needed to generalize this idea.
239  */
240  real64 directional_coef = 1.0;
241  if( m_miscibleDBC )
242  {
243  directional_coef = initialDirectionalCoef;
244  if( LvArray::math::abs( grad_depth ) > 0.0 )
245  {
246  real64 const d2 = LvArray::math::abs( grad_depth * grad_depth );
247  if( multiplierDirectionalCoef / d2 < initialDirectionalCoef )
248  directional_coef = multiplierDirectionalCoef / d2;
249  }
250  }
251 
252  // multiplier with all contributions
253  real64 const multiplier = m_kappaDBC * m_omegaDBC / poreVolume_n * m_dt * potential_gradient * directional_coef;
254 
256  for( integer ke = 0; ke < numFluxSupportPoints; ++ke )
257  {
258  real64 const coef = multiplier * viscosityMult[ip] * stack.transmissibility[connectionIndex][ke];
259  for( integer ic = 0; ic < numComp; ++ic )
260  {
261  localIndex const er = seri[ke];
262  localIndex const esr = sesri[ke];
263  localIndex const ei = sei[ke];
264 
265  // composition gradient contribution to the dissipation flux
266  dissFlux[ic] += coef * m_compFrac[er][esr][ei][ic];
267 
268  dDissFlux_dP[ke][ic] = 0; // no dependency on pressure at n+1, compFrad is global component fraction (z_c)
269 
270  for( integer jc = 0; jc < numComp; ++jc )
271  {
272  // composition gradient derivative with respect to component density contribution to the dissipation flux
273  dDissFlux_dC[ke][ic][jc] += coef * m_dCompFrac_dCompDens[er][esr][ei][ic][jc];
274  }
275  }
276  }
277 
279  for( integer ic = 0; ic < numComp; ++ic )
280  {
281  integer const eqIndex0 = k[0] * numEqn + ic;
282  integer const eqIndex1 = k[1] * numEqn + ic;
283 
284  stack.localFlux[eqIndex0] += m_dt * dissFlux[ic];
285  stack.localFlux[eqIndex1] -= m_dt * dissFlux[ic];
286 
287  for( integer ke = 0; ke < numFluxSupportPoints; ++ke )
288  {
289  localIndex const localDofIndexPres = k[ke] * numDof;
290  stack.localFluxJacobian[eqIndex0][localDofIndexPres] += m_dt * dDissFlux_dP[ke][ic];
291  stack.localFluxJacobian[eqIndex1][localDofIndexPres] -= m_dt * dDissFlux_dP[ke][ic];
292 
293  for( integer jc = 0; jc < numComp; ++jc )
294  {
295  localIndex const localDofIndexComp = localDofIndexPres + jc + 1;
296  stack.localFluxJacobian[eqIndex0][localDofIndexComp] += m_dt * dDissFlux_dC[ke][ic][jc];
297  stack.localFluxJacobian[eqIndex1][localDofIndexComp] -= m_dt * dDissFlux_dC[ke][ic][jc];
298  }
299  }
300  }
301 
302  } ); // end call to Base::computeFlux
303 
304  }
305 
306 protected:
307 
311 
314 
315  // DBC specific parameters
316  // input
317  real64 m_omegaDBC;
318  integer m_miscibleDBC;
319  // computed
320  real64 m_kappaDBC;
321 };
322 
327 {
328 public:
329 
346  template< typename POLICY, typename STENCILWRAPPER >
347  static void
348  createAndLaunch( integer const numComps,
349  integer const numPhases,
350  globalIndex const rankOffset,
351  string const & dofKey,
352  BitFlags< isothermalCompositionalMultiphaseFVMKernels::KernelFlags > kernelFlags,
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  real64 const omega,
360  integer const curNewton,
361  integer const continuation,
362  integer const miscible,
363  real64 const kappamin,
364  real64 const contMultiplier )
365  {
366  isothermalCompositionalMultiphaseBaseKernels::
367  internal::kernelLaunchSelectorCompSwitch( numComps, [&]( auto NC )
368  {
369  integer constexpr NUM_COMP = NC();
370  integer constexpr NUM_DOF = NC() + 1;
371 
373  elemManager.constructArrayViewAccessor< globalIndex, 1 >( dofKey );
374  dofNumberAccessor.setName( solverName + "/accessors/" + dofKey );
375 
377  typename KERNEL_TYPE::CompFlowAccessors compFlowAccessors( elemManager, solverName );
378  typename KERNEL_TYPE::MultiFluidAccessors multiFluidAccessors( elemManager, solverName );
379  typename KERNEL_TYPE::CapPressureAccessors capPressureAccessors( elemManager, solverName );
380  typename KERNEL_TYPE::PermeabilityAccessors permeabilityAccessors( elemManager, solverName );
381  typename KERNEL_TYPE::PorosityAccessors porosityAccessors( elemManager, solverName );
382  typename KERNEL_TYPE::DissCompFlowAccessors dissCompFlowAccessors( elemManager, solverName );
383 
384  KERNEL_TYPE kernel( numPhases, rankOffset, stencilWrapper, dofNumberAccessor, compFlowAccessors, dissCompFlowAccessors,
385  multiFluidAccessors, capPressureAccessors, permeabilityAccessors, porosityAccessors,
386  dt, localMatrix, localRhs, kernelFlags, omega, curNewton, continuation, miscible, kappamin, contMultiplier );
387  KERNEL_TYPE::template launch< POLICY >( stencilWrapper.size(), kernel );
388  } );
389  }
390 };
391 
392 } // namespace DissipationCompositionalMultiphaseFVMKernels
393 
394 } // namespace geos
395 
396 
397 #endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_DISSIPATIONFLUXCOMPUTEKERNEL_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
#define GEOS_UNUSED_PARAM(X)
Mark an unused argument and silence compiler warnings.
Definition: GeosxMacros.hpp:72
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.
static void createAndLaunch(integer const numComps, integer const numPhases, globalIndex const rankOffset, string const &dofKey, BitFlags< isothermalCompositionalMultiphaseFVMKernels::KernelFlags > kernelFlags, string const &solverName, ElementRegionManager const &elemManager, STENCILWRAPPER const &stencilWrapper, real64 const &dt, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs, real64 const omega, integer const curNewton, integer const continuation, integer const miscible, real64 const kappamin, real64 const contMultiplier)
Create a new kernel and launch.
Define the interface for the assembly kernel in charge of flux terms.
ElementRegionManager::ElementViewConst< VIEWTYPE > ElementViewConst
The type for element-based data. Consists entirely of ArrayView's.
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< arrayView1d< real64 const > > const m_pres_n
Views on flow properties at the previous converged time step.
GEOS_HOST_DEVICE void computeFlux(localIndex const iconn, typename Base::StackVariables &stack) const
Compute the local flux contributions to the residual and Jacobian, including dissipation.
static constexpr integer numComp
Compile time value for the number of components.
FluxComputeKernel(integer const numPhases, globalIndex const rankOffset, STENCILWRAPPER const &stencilWrapper, DofNumberAccessor const &dofNumberAccessor, CompFlowAccessors const &compFlowAccessors, DissCompFlowAccessors const &dissCompFlowAccessors, MultiFluidAccessors const &multiFluidAccessors, CapPressureAccessors const &capPressureAccessors, PermeabilityAccessors const &permeabilityAccessors, PorosityAccessors const &porosityAccessors, real64 const &dt, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs, BitFlags< isothermalCompositionalMultiphaseFVMKernels::KernelFlags > kernelFlags, real64 const omega, integer const curNewton, integer const continuation, integer const miscible, real64 const kappamin, real64 const contMultiplier)
Constructor for the kernel interface.
static constexpr integer numDof
Compute time value for the number of degrees of freedom.
ElementViewConst< arrayView3d< real64 const, compflow::USD_COMP_DC > > const m_dCompFrac_dCompDens
Views on derivatives of comp fractions.
Base class for FluxComputeKernel that holds all data not dependent on template parameters (like stenc...
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.
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.
static constexpr integer numDof
Compute time value for the number of degrees of freedom.
ElementViewConst< arrayView3d< real64 const > > const m_permeability
Views on permeability.
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
Trait struct for elementVolume data.
Definition: MeshFields.hpp:108
Kernel variables (dof numbers, jacobian and residual) located on the stack.
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)
real64 transmissibility[maxNumConns][numFluxSupportPoints]
Transmissibility.