GEOS
DiffusionDispersionFluxComputeKernel.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_DIFFUSIONDISPERSIONFLUXCOMPUTEKERNEL_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_DIFFUSIONDISPERSIONFLUXCOMPUTEKERNEL_HPP
22 
23 #include "codingUtilities/Utilities.hpp"
24 #include "common/DataLayouts.hpp"
25 #include "common/DataTypes.hpp"
26 #include "common/GEOS_RAJA_Interface.hpp"
27 #include "constitutive/diffusion/DiffusionFields.hpp"
28 #include "constitutive/diffusion/DiffusionBase.hpp"
29 #include "constitutive/dispersion/DispersionFields.hpp"
30 #include "constitutive/dispersion/DispersionBase.hpp"
31 #include "constitutive/solid/porosity/PorosityBase.hpp"
32 #include "constitutive/solid/porosity/PorosityFields.hpp"
36 
37 namespace geos
38 {
39 
40 namespace isothermalCompositionalMultiphaseFVMKernels
41 {
42 
43 /******************************** DiffusionDispersionFluxComputeKernel ********************************/
44 
52 template< integer NUM_COMP, integer NUM_DOF, typename STENCILWRAPPER >
54 {
55 public:
56 
58  static constexpr integer numComp = NUM_COMP;
59 
61  static constexpr integer numDof = NUM_DOF;
62 
64  static constexpr integer numEqn = NUM_DOF-1;
65 
67  static constexpr localIndex maxNumElems = STENCILWRAPPER::maxNumPointsInFlux;
68 
70  static constexpr localIndex maxNumConns = STENCILWRAPPER::maxNumConnections;
71 
73  static constexpr localIndex maxStencilSize = STENCILWRAPPER::maxStencilSize;
74 
76  static constexpr integer numFluxSupportPoints = 2;
77 
79  using AbstractBase::m_dPhaseVolFrac;
80  using AbstractBase::m_kernelFlags;
81 
82  using DiffusionAccessors =
83  StencilMaterialAccessors< constitutive::DiffusionBase,
84  fields::diffusion::diffusivity,
85  fields::diffusion::dDiffusivity_dTemperature,
86  fields::diffusion::phaseDiffusivityMultiplier >;
87 
88  using DispersionAccessors =
89  StencilMaterialAccessors< constitutive::DispersionBase,
90  fields::dispersion::dispersivity >;
91 
92  using PorosityAccessors =
93  StencilMaterialAccessors< constitutive::PorosityBase,
94  fields::porosity::referencePorosity >;
95 
113  globalIndex const rankOffset,
114  STENCILWRAPPER const & stencilWrapper,
115  DofNumberAccessor const & dofNumberAccessor,
116  CompFlowAccessors const & compFlowAccessors,
117  MultiFluidAccessors const & multiFluidAccessors,
118  DiffusionAccessors const & diffusionAccessors,
119  DispersionAccessors const & dispersionAccessors,
120  PorosityAccessors const & porosityAccessors,
121  real64 const dt,
122  CRSMatrixView< real64, globalIndex const > const & localMatrix,
123  arrayView1d< real64 > const & localRhs,
124  BitFlags< KernelFlags > kernelFlags )
125  : FluxComputeKernelBase( numPhases,
126  rankOffset,
127  dofNumberAccessor,
128  compFlowAccessors,
129  multiFluidAccessors,
130  dt,
131  localMatrix,
132  localRhs,
133  kernelFlags ),
134  m_phaseVolFrac( compFlowAccessors.get( fields::flow::phaseVolumeFraction {} ) ),
135  m_phaseDens( multiFluidAccessors.get( fields::multifluid::phaseDensity {} ) ),
136  m_dPhaseDens( multiFluidAccessors.get( fields::multifluid::dPhaseDensity {} ) ),
137  m_diffusivity( diffusionAccessors.get( fields::diffusion::diffusivity {} ) ),
138  m_dDiffusivity_dTemp( diffusionAccessors.get( fields::diffusion::dDiffusivity_dTemperature {} ) ),
139  m_phaseDiffusivityMultiplier( diffusionAccessors.get( fields::diffusion::phaseDiffusivityMultiplier {} ) ),
140  m_dispersivity( dispersionAccessors.get( fields::dispersion::dispersivity {} ) ),
141  m_referencePorosity( porosityAccessors.get( fields::porosity::referencePorosity {} ) ),
142  m_stencilWrapper( stencilWrapper ),
143  m_seri( stencilWrapper.getElementRegionIndices() ),
144  m_sesri( stencilWrapper.getElementSubRegionIndices() ),
145  m_sei( stencilWrapper.getElementIndices() )
146  { }
147 
153  {
154 public:
155 
162  StackVariables( localIndex const size, localIndex numElems )
163  : stencilSize( size ),
164  numConnectedElems( numElems ),
165  dofColIndices( size * numDof ),
166  localFlux( numElems * numEqn ),
167  localFluxJacobian( numElems * numEqn, size * numDof )
168  {}
169 
170  // Stencil information
171 
176 
181 
182  // Local degrees of freedom and local residual/jacobian
183 
186 
191  };
192 
193 
200  inline
201  localIndex stencilSize( localIndex const iconn ) const
202  { return m_sei[iconn].size(); }
203 
210  inline
211  localIndex numPointsInFlux( localIndex const iconn ) const
212  { return m_stencilWrapper.numPointsInFlux( iconn ); }
213 
214 
221  inline
222  void setup( localIndex const iconn,
223  StackVariables & stack ) const
224  {
225  // set degrees of freedom indices for this face
226  for( integer i = 0; i < stack.stencilSize; ++i )
227  {
228  globalIndex const offset = m_dofNumber[m_seri( iconn, i )][m_sesri( iconn, i )][m_sei( iconn, i )];
229 
230  for( integer jdof = 0; jdof < numDof; ++jdof )
231  {
232  stack.dofColIndices[i * numDof + jdof] = offset + jdof;
233  }
234  }
235  }
236 
244  template< typename FUNC = NoOpFunc >
246  inline
247  void computeDiffusionFlux( localIndex const iconn,
248  StackVariables & stack,
249  FUNC && diffusionFluxKernelOp = NoOpFunc{} ) const
250  {
251  using Deriv = constitutive::multifluid::DerivativeOffset;
252 
253  // first, compute the transmissibilities at this face
254  m_stencilWrapper.computeWeights( iconn,
256  m_dDiffusivity_dTemp,
257  stack.transmissibility,
258  stack.dTrans_dTemp );
259 
260 
262  localIndex connectionIndex = 0;
263  for( k[0] = 0; k[0] < stack.numConnectedElems; ++k[0] )
264  {
265  for( k[1] = k[0] + 1; k[1] < stack.numConnectedElems; ++k[1] )
266  {
268  localIndex const seri[numFluxSupportPoints] = {m_seri( iconn, k[0] ), m_seri( iconn, k[1] )};
269  localIndex const sesri[numFluxSupportPoints] = {m_sesri( iconn, k[0] ), m_sesri( iconn, k[1] )};
270  localIndex const sei[numFluxSupportPoints] = {m_sei( iconn, k[0] ), m_sei( iconn, k[1] )};
271 
272  // clear working arrays
273  real64 diffusionFlux[numComp]{};
274  real64 dDiffusionFlux_dP[numFluxSupportPoints][numComp]{};
275  real64 dDiffusionFlux_dC[numFluxSupportPoints][numComp][numComp]{};
276  real64 dDens_dC[numComp]{};
277 
278  real64 const trans[numFluxSupportPoints] = { stack.transmissibility[connectionIndex][0],
279  stack.transmissibility[connectionIndex][1] };
280 
281  //***** calculation of flux *****
282  // loop over phases, compute and upwind phase flux and sum contributions to each component's flux
283  for( integer ip = 0; ip < m_numPhases; ++ip )
284  {
285 
286  // loop over components
287  for( integer ic = 0; ic < numComp; ++ic )
288  {
289 
290  real64 compFracGrad = 0.0;
291  real64 dCompFracGrad_dP[numFluxSupportPoints]{};
292  real64 dCompFracGrad_dC[numFluxSupportPoints][numComp]{};
293 
294  // compute the component fraction gradient using the diffusion transmissibility
296  seri, sesri, sei,
297  trans,
298  compFracGrad,
299  dCompFracGrad_dP,
300  dCompFracGrad_dC );
301 
302  // choose upstream cell for composition upwinding
303  localIndex const k_up = (compFracGrad >= 0) ? 0 : 1;
304 
305  localIndex const er_up = seri[k_up];
306  localIndex const esr_up = sesri[k_up];
307  localIndex const ei_up = sei[k_up];
308 
309  // computation of the upwinded mass flux
310  real64 const upwindCoefficient =
311  m_referencePorosity[er_up][esr_up][ei_up] *
312  m_phaseDiffusivityMultiplier[er_up][esr_up][ei_up][0][ip] *
313  m_phaseDens[er_up][esr_up][ei_up][0][ip] * m_phaseVolFrac[er_up][esr_up][ei_up][ip];
314  diffusionFlux[ic] += upwindCoefficient * compFracGrad;
315 
316  // add contributions of the derivatives of component fractions wrt pressure/component fractions
317  for( integer ke = 0; ke < numFluxSupportPoints; ke++ )
318  {
319  dDiffusionFlux_dP[ke][ic] += upwindCoefficient * dCompFracGrad_dP[ke];
320  for( integer jc = 0; jc < numComp; ++jc )
321  {
322  dDiffusionFlux_dC[ke][ic][jc] += upwindCoefficient * dCompFracGrad_dC[ke][jc];
323  }
324  }
325 
326  // add contributions of the derivatives of upwind coefficient wrt pressure/component fractions
327  real64 const dUpwindCoefficient_dP =
328  m_referencePorosity[er_up][esr_up][ei_up] *
329  m_phaseDiffusivityMultiplier[er_up][esr_up][ei_up][0][ip] *
330  ( m_dPhaseDens[er_up][esr_up][ei_up][0][ip][Deriv::dP] * m_phaseVolFrac[er_up][esr_up][ei_up][ip]
331  + m_phaseDens[er_up][esr_up][ei_up][0][ip] * m_dPhaseVolFrac[er_up][esr_up][ei_up][ip][Deriv::dP] );
332  dDiffusionFlux_dP[k_up][ic] += dUpwindCoefficient_dP * compFracGrad;
333 
334  applyChainRule( numComp,
335  m_dCompFrac_dCompDens[er_up][esr_up][ei_up],
336  m_dPhaseDens[er_up][esr_up][ei_up][0][ip],
337  dDens_dC,
338  Deriv::dC );
339  for( integer jc = 0; jc < numComp; ++jc )
340  {
341  real64 const dUpwindCoefficient_dC =
342  m_referencePorosity[er_up][esr_up][ei_up] *
343  m_phaseDiffusivityMultiplier[er_up][esr_up][ei_up][0][ip] *
344  ( dDens_dC[jc] * m_phaseVolFrac[er_up][esr_up][ei_up][ip]
345  + m_phaseDens[er_up][esr_up][ei_up][0][ip] * m_dPhaseVolFrac[er_up][esr_up][ei_up][ip][Deriv::dC+jc] );
346  dDiffusionFlux_dC[k_up][ic][jc] += dUpwindCoefficient_dC * compFracGrad;
347  }
348 
349  // call the lambda in the phase loop to allow the reuse of the phase fluxes and their derivatives
350  // possible use: assemble the derivatives wrt temperature, and the flux term of the energy equation for this phase
351  diffusionFluxKernelOp( ip, ic, k, seri, sesri, sei, connectionIndex,
352  k_up, seri[k_up], sesri[k_up], sei[k_up],
353  compFracGrad, upwindCoefficient );
354 
355  } // loop over components
356  } // loop over phases
357 
358  // add diffusion flux to local flux and local flux jacobian
360  stack,
361  diffusionFlux,
362  dDiffusionFlux_dP,
363  dDiffusionFlux_dC );
364 
365  connectionIndex++;
366  } // loop over k[1]
367  } // loop over k[0]
368  }
369 
377  template< typename FUNC = NoOpFunc >
379  inline
381  StackVariables & stack,
382  FUNC && dispersionFluxKernelOp = NoOpFunc{} ) const
383  {
384  using Deriv = constitutive::multifluid::DerivativeOffset;
385 
386  // first, compute the transmissibilities at this face
387  // note that the dispersion tensor is lagged in iteration
388  m_stencilWrapper.computeWeights( iconn,
390  m_dispersivity, // this is just to pass something, but the resulting derivative won't be used
391  stack.transmissibility,
392  stack.dTrans_dTemp ); // will not be used
393 
394 
396  localIndex connectionIndex = 0;
397  for( k[0] = 0; k[0] < stack.numConnectedElems; ++k[0] )
398  {
399  for( k[1] = k[0] + 1; k[1] < stack.numConnectedElems; ++k[1] )
400  {
402  localIndex const seri[numFluxSupportPoints] = {m_seri( iconn, k[0] ), m_seri( iconn, k[1] )};
403  localIndex const sesri[numFluxSupportPoints] = {m_sesri( iconn, k[0] ), m_sesri( iconn, k[1] )};
404  localIndex const sei[numFluxSupportPoints] = {m_sei( iconn, k[0] ), m_sei( iconn, k[1] )};
405 
406  // clear working arrays
407  real64 dispersionFlux[numComp]{};
408  real64 dDispersionFlux_dP[numFluxSupportPoints][numComp]{};
409  real64 dDispersionFlux_dC[numFluxSupportPoints][numComp][numComp]{};
410  real64 dDens_dC[numComp]{};
411 
412  real64 const trans[numFluxSupportPoints] = { stack.transmissibility[connectionIndex][0],
413  stack.transmissibility[connectionIndex][1] };
414 
415  //***** calculation of flux *****
416  // loop over phases, compute and upwind phase flux and sum contributions to each component's flux
417  for( integer ip = 0; ip < m_numPhases; ++ip )
418  {
419 
420  // loop over components
421  for( integer ic = 0; ic < numComp; ++ic )
422  {
423 
424  real64 compFracGrad = 0.0;
425  real64 dCompFracGrad_dP[numFluxSupportPoints]{};
426  real64 dCompFracGrad_dC[numFluxSupportPoints][numComp]{};
427 
428  // compute the component fraction gradient using the dispersion transmissibility
430  seri, sesri, sei,
431  trans,
432  compFracGrad,
433  dCompFracGrad_dP,
434  dCompFracGrad_dC );
435 
436  // choose upstream cell for composition upwinding
437  localIndex const k_up = (compFracGrad >= 0) ? 0 : 1;
438 
439  localIndex const er_up = seri[k_up];
440  localIndex const esr_up = sesri[k_up];
441  localIndex const ei_up = sei[k_up];
442 
443  // computation of the upwinded mass flux
444  dispersionFlux[ic] += m_phaseDens[er_up][esr_up][ei_up][0][ip] * compFracGrad;
445 
446  // add contributions of the derivatives of component fractions wrt pressure/component fractions
447  for( integer ke = 0; ke < numFluxSupportPoints; ke++ )
448  {
449  dDispersionFlux_dP[ke][ic] += m_phaseDens[er_up][esr_up][ei_up][0][ip] * dCompFracGrad_dP[ke];
450  for( integer jc = 0; jc < numComp; ++jc )
451  {
452  dDispersionFlux_dC[ke][ic][jc] += m_phaseDens[er_up][esr_up][ei_up][0][ip] * dCompFracGrad_dC[ke][jc];
453  }
454  }
455 
456  // add contributions of the derivatives of upwind coefficient wrt pressure/component fractions
457  dDispersionFlux_dP[k_up][ic] += m_dPhaseDens[er_up][esr_up][ei_up][0][ip][Deriv::dP] * compFracGrad;
458 
459  applyChainRule( numComp,
460  m_dCompFrac_dCompDens[er_up][esr_up][ei_up],
461  m_dPhaseDens[er_up][esr_up][ei_up][0][ip],
462  dDens_dC,
463  Deriv::dC );
464  for( integer jc = 0; jc < numComp; ++jc )
465  {
466  dDispersionFlux_dC[k_up][ic][jc] += dDens_dC[jc] * compFracGrad;
467  }
468 
469  // call the lambda in the phase loop to allow the reuse of the phase fluxes and their derivatives
470  // possible use: assemble the derivatives wrt temperature, and the flux term of the energy equation for this phase
471  dispersionFluxKernelOp( ip, ic, k, seri, sesri, sei, connectionIndex,
472  k_up, seri[k_up], sesri[k_up], sei[k_up],
473  compFracGrad );
474 
475  } // loop over components
476  } // loop over phases
477 
478  // add dispersion flux to local flux and local flux jacobian
480  stack,
481  dispersionFlux,
482  dDispersionFlux_dP,
483  dDispersionFlux_dC );
484 
485  connectionIndex++;
486  } // loop over k[1]
487  } // loop over k[0]
488  }
489 
502  inline
504  integer const ic,
505  localIndex const (&seri)[numFluxSupportPoints],
506  localIndex const (&sesri)[numFluxSupportPoints],
507  localIndex const (&sei)[numFluxSupportPoints],
508  real64 const (&trans)[numFluxSupportPoints],
509  real64 & compFracGrad,
510  real64 (& dCompFracGrad_dP)[numFluxSupportPoints],
511  real64 (& dCompFracGrad_dC)[numFluxSupportPoints][numComp] ) const
512  {
513  using Deriv = constitutive::multifluid::DerivativeOffset;
514 
515  real64 dCompFrac_dC[numComp]{};
516 
517  for( integer i = 0; i < numFluxSupportPoints; i++ )
518  {
519  localIndex const er = seri[i];
520  localIndex const esr = sesri[i];
521  localIndex const ei = sei[i];
522 
523  compFracGrad += trans[i] * m_phaseCompFrac[er][esr][ei][0][ip][ic];
524  dCompFracGrad_dP[i] += trans[i] * m_dPhaseCompFrac[er][esr][ei][0][ip][ic][Deriv::dP];
525 
526  applyChainRule( numComp,
527  m_dCompFrac_dCompDens[er][esr][ei],
528  m_dPhaseCompFrac[er][esr][ei][0][ip][ic],
529  dCompFrac_dC,
530  Deriv::dC );
531  for( integer jc = 0; jc < numComp; ++jc )
532  {
533  dCompFracGrad_dC[i][jc] += trans[i] * dCompFrac_dC[jc];
534  }
535  }
536  }
537 
547  inline
549  StackVariables & stack,
550  real64 const (&flux)[numComp],
551  real64 const (&dFlux_dP)[numFluxSupportPoints][numComp],
552  real64 const (&dFlux_dC)[numFluxSupportPoints][numComp][numComp] ) const
553  {
554  // loop over components
555  for( integer ic = 0; ic < numComp; ++ic )
556  {
557  // finally, increment local flux and local Jacobian
558  integer const eqIndex0 = k[0] * numEqn + ic;
559  integer const eqIndex1 = k[1] * numEqn + ic;
560 
561  stack.localFlux[eqIndex0] += m_dt * flux[ic];
562  stack.localFlux[eqIndex1] -= m_dt * flux[ic];
563 
564  for( integer ke = 0; ke < numFluxSupportPoints; ++ke )
565  {
566  localIndex const localDofIndexPres = k[ke] * numDof;
567  stack.localFluxJacobian[eqIndex0][localDofIndexPres] += m_dt * dFlux_dP[ke][ic];
568  stack.localFluxJacobian[eqIndex1][localDofIndexPres] -= m_dt * dFlux_dP[ke][ic];
569 
570  for( integer jc = 0; jc < numComp; ++jc )
571  {
572  localIndex const localDofIndexComp = localDofIndexPres + jc + 1;
573  stack.localFluxJacobian[eqIndex0][localDofIndexComp] += m_dt * dFlux_dC[ke][ic][jc];
574  stack.localFluxJacobian[eqIndex1][localDofIndexComp] -= m_dt * dFlux_dC[ke][ic][jc];
575  }
576  }
577  }
578  }
579 
580 
586  template< typename FUNC = NoOpFunc >
588  inline
589  void complete( localIndex const iconn,
590  StackVariables & stack,
591  FUNC && assemblyKernelOp = NoOpFunc{} ) const
592  {
593  using namespace compositionalMultiphaseUtilities;
594 
595  if( m_kernelFlags.isSet( KernelFlags::TotalMassEquation ) )
596  {
597  // Apply equation/variable change transformation(s)
599  shiftBlockRowsAheadByOneAndReplaceFirstRowWithColumnSum( numComp, numEqn, numDof*stack.stencilSize, stack.numConnectedElems,
600  stack.localFluxJacobian, work );
601  shiftBlockElementsAheadByOneAndReplaceFirstElementWithSum( numComp, numEqn, stack.numConnectedElems,
602  stack.localFlux );
603  }
604 
605  // add contribution to residual and jacobian into:
606  // - the component mass balance equations (i = 0 to i = numComp-1)
607  // note that numDof includes derivatives wrt temperature if this class is derived in ThermalKernels
608  for( integer i = 0; i < stack.numConnectedElems; ++i )
609  {
610  if( m_ghostRank[m_seri( iconn, i )][m_sesri( iconn, i )][m_sei( iconn, i )] < 0 )
611  {
612  globalIndex const globalRow = m_dofNumber[m_seri( iconn, i )][m_sesri( iconn, i )][m_sei( iconn, i )];
613  localIndex const localRow = LvArray::integerConversion< localIndex >( globalRow - m_rankOffset );
614  GEOS_ASSERT_GE( localRow, 0 );
615  GEOS_ASSERT_GT( m_localMatrix.numRows(), localRow + numComp );
616 
617  for( integer ic = 0; ic < numComp; ++ic )
618  {
619  RAJA::atomicAdd( parallelDeviceAtomic{}, &m_localRhs[localRow + ic], stack.localFlux[i * numEqn + ic] );
620  m_localMatrix.addToRowBinarySearchUnsorted< parallelDeviceAtomic >
621  ( localRow + ic,
622  stack.dofColIndices.data(),
623  stack.localFluxJacobian[i * numEqn + ic].dataIfContiguous(),
624  stack.stencilSize * numDof );
625  }
626 
627  // call the lambda to assemble additional terms, such as thermal terms
628  assemblyKernelOp( i, localRow );
629  }
630  }
631  }
632 
640  template< typename POLICY, typename KERNEL_TYPE >
641  static void
642  launch( localIndex const numConnections,
643  integer const hasDiffusion,
644  integer const hasDispersion,
645  KERNEL_TYPE const & kernelComponent )
646  {
648  forAll< POLICY >( numConnections, [=] GEOS_HOST_DEVICE ( localIndex const iconn )
649  {
650  typename KERNEL_TYPE::StackVariables stack( kernelComponent.stencilSize( iconn ),
651  kernelComponent.numPointsInFlux( iconn ) );
652 
653  kernelComponent.setup( iconn, stack );
654  if( hasDiffusion )
655  {
656  kernelComponent.computeDiffusionFlux( iconn, stack );
657  }
658  if( hasDispersion )
659  {
660  kernelComponent.computeDispersionFlux( iconn, stack );
661  }
662  kernelComponent.complete( iconn, stack );
663  } );
664  }
665 
666 protected:
667 
670 
674 
677  ElementViewConst< arrayView3d< real64 const > > const m_dDiffusivity_dTemp;
678  ElementViewConst< arrayView3d< real64 const > > const m_phaseDiffusivityMultiplier;
679 
682 
685 
686  // Stencil information
687 
689  STENCILWRAPPER const m_stencilWrapper;
690 
692  typename STENCILWRAPPER::IndexContainerViewConstType const m_seri;
693  typename STENCILWRAPPER::IndexContainerViewConstType const m_sesri;
694  typename STENCILWRAPPER::IndexContainerViewConstType const m_sei;
695 
696 };
697 
702 {
703 public:
704 
722  template< typename POLICY, typename STENCILWRAPPER >
723  static void
724  createAndLaunch( integer const numComps,
725  integer const numPhases,
726  globalIndex const rankOffset,
727  string const & dofKey,
728  BitFlags< KernelFlags > kernelFlags,
729  string const & solverName,
730  ElementRegionManager const & elemManager,
731  STENCILWRAPPER const & stencilWrapper,
732  real64 const dt,
733  CRSMatrixView< real64, globalIndex const > const & localMatrix,
734  arrayView1d< real64 > const & localRhs )
735  {
736  isothermalCompositionalMultiphaseBaseKernels::internal::kernelLaunchSelectorCompSwitch( numComps, [&]( auto NC )
737  {
738  integer constexpr NUM_COMP = NC();
739  integer constexpr NUM_DOF = NC() + 1;
740 
742  elemManager.constructArrayViewAccessor< globalIndex, 1 >( dofKey );
743  dofNumberAccessor.setName( solverName + "/accessors/" + dofKey );
744 
746  typename kernelType::CompFlowAccessors compFlowAccessors( elemManager, solverName );
747  typename kernelType::MultiFluidAccessors multiFluidAccessors( elemManager, solverName );
748  typename kernelType::DiffusionAccessors diffusionAccessors( elemManager, solverName );
749  typename kernelType::DispersionAccessors dispersionAccessors( elemManager, solverName );
750  typename kernelType::PorosityAccessors porosityAccessors( elemManager, solverName );
751 
752  kernelType kernel( numPhases, rankOffset, stencilWrapper,
753  dofNumberAccessor, compFlowAccessors, multiFluidAccessors,
754  diffusionAccessors, dispersionAccessors, porosityAccessors,
755  dt, localMatrix, localRhs, kernelFlags );
756  kernelType::template launch< POLICY >( stencilWrapper.size(),
757  kernelFlags.isSet( KernelFlags::Diffusion ),
758  kernelFlags.isSet( KernelFlags::Dispersion ),
759  kernel );
760  } );
761  }
762 };
763 
764 } // namespace isothermalCompositionalMultiphaseFVMKernels
765 
766 } // namespace geos
767 
768 
769 #endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_DIFFUSIONDISPERSIONFLUXCOMPUTEKERNEL_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.
static void createAndLaunch(integer const numComps, integer const numPhases, globalIndex const rankOffset, string const &dofKey, BitFlags< KernelFlags > kernelFlags, 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.
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.
STENCILWRAPPER::IndexContainerViewConstType const m_seri
Connection to element maps.
GEOS_HOST_DEVICE void computeCompFractionGradient(integer const ip, integer const ic, localIndex const (&seri)[numFluxSupportPoints], localIndex const (&sesri)[numFluxSupportPoints], localIndex const (&sei)[numFluxSupportPoints], real64 const (&trans)[numFluxSupportPoints], real64 &compFracGrad, real64(&dCompFracGrad_dP)[numFluxSupportPoints], real64(&dCompFracGrad_dC)[numFluxSupportPoints][numComp]) const
Compute the component fraction gradient at this interface.
ElementViewConst< arrayView3d< real64 const > > const m_dispersivity
Views on dispersivity.
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< KernelFlags > kernelFlags)
Constructor for the kernel interface.
GEOS_HOST_DEVICE void addToLocalFluxAndJacobian(localIndex const (&k)[numFluxSupportPoints], StackVariables &stack, real64 const (&flux)[numComp], real64 const (&dFlux_dP)[numFluxSupportPoints][numComp], real64 const (&dFlux_dC)[numFluxSupportPoints][numComp][numComp]) const
Add the local diffusion/dispersion flux contributions to the residual and Jacobian.
GEOS_HOST_DEVICE localIndex stencilSize(localIndex const iconn) const
Getter for the stencil size at this connection.
static constexpr integer numDof
Compute time value for the number of degrees of freedom.
GEOS_HOST_DEVICE void computeDiffusionFlux(localIndex const iconn, StackVariables &stack, FUNC &&diffusionFluxKernelOp=NoOpFunc{}) const
Compute the local diffusion flux contributions to the residual and Jacobian.
static void launch(localIndex const numConnections, integer const hasDiffusion, integer const hasDispersion, KERNEL_TYPE const &kernelComponent)
Performs the kernel launch.
GEOS_HOST_DEVICE localIndex numPointsInFlux(localIndex const iconn) const
Getter for the number of elements at this connection.
ElementViewConst< arrayView3d< real64 const > > const m_diffusivity
Views on diffusivity.
static constexpr integer numFluxSupportPoints
Number of flux support points (hard-coded for TFPA)
GEOS_HOST_DEVICE void computeDispersionFlux(localIndex const iconn, StackVariables &stack, FUNC &&dispersionFluxKernelOp=NoOpFunc{}) const
Compute the local dispersion flux contributions to the residual and Jacobian.
GEOS_HOST_DEVICE void complete(localIndex const iconn, StackVariables &stack, FUNC &&assemblyKernelOp=NoOpFunc{}) const
Performs the complete phase for the kernel.
GEOS_HOST_DEVICE void setup(localIndex const iconn, StackVariables &stack) const
Performs the setup phase for the kernel.
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...
ElementViewConst< arrayView1d< globalIndex const > > const m_dofNumber
Views on dof numbers.
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.
CRSMatrixView< real64, globalIndex const > const m_localMatrix
View on the local CRS matrix.
ElementRegionManager::ElementViewConst< VIEWTYPE > ElementViewConst
The type for element-based data. Consists entirely of ArrayView's.
ElementViewConst< arrayView3d< real64 const, compflow::USD_COMP_DC > > const m_dCompFrac_dCompDens
Views on derivatives of comp fractions.
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
stackArray1d< real64, maxNumElems *numEqn > localFlux
Storage for the face local residual vector (all equations except volume balance)
stackArray1d< globalIndex, maxNumElems *numDof > dofColIndices
Indices of the matrix rows/columns corresponding to the dofs in this face.
real64 dTrans_dTemp[maxNumConns][numFluxSupportPoints]
Derivatives of transmissibility with respect to pressure.
GEOS_HOST_DEVICE StackVariables(localIndex const size, localIndex numElems)
Constructor for the stack variables.
stackArray2d< real64, maxNumElems *numEqn *maxStencilSize *numDof > localFluxJacobian
Storage for the face local Jacobian matrix.