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