GEOS
C1PPUPhaseFlux.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_C1PPUPHASEFLUX_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_C1PPUPHASEFLUX_HPP
22 
23 #include "common/DataLayouts.hpp"
24 #include "common/DataTypes.hpp"
25 #include "constitutive/fluid/multifluid/Layouts.hpp"
26 #include "constitutive/capillaryPressure/layouts.hpp"
30 
31 
32 namespace geos
33 {
34 
35 namespace isothermalCompositionalMultiphaseFVMKernelUtilities
36 {
37 
38 // TODO make input parameter
39 static constexpr real64 epsC1PPU = 5000;
40 
41 template< typename VIEWTYPE >
42 using ElementViewConst = ElementRegionManager::ElementViewConst< VIEWTYPE >;
43 
44 using Deriv = constitutive::multifluid::DerivativeOffset;
45 
47 {
76  template< integer numComp, integer numFluxSupportPoints >
78  static void
79  compute( integer const numPhase,
80  integer const ip,
81  integer const hasCapPressure,
82  integer const checkPhasePresenceInGravity,
83  localIndex const ( &seri )[numFluxSupportPoints],
84  localIndex const ( &sesri )[numFluxSupportPoints],
85  localIndex const ( &sei )[numFluxSupportPoints],
86  real64 const ( &trans )[2],
87  real64 const ( &dTrans_dPres )[2],
88  ElementViewConst< arrayView1d< real64 const > > const & pres,
89  ElementViewConst< arrayView1d< real64 const > > const & gravCoef,
90  ElementViewConst< arrayView2d< real64 const, compflow::USD_PHASE > > const & phaseMob,
91  ElementViewConst< arrayView3d< real64 const, compflow::USD_PHASE_DC > > const & dPhaseMob,
92  ElementViewConst< arrayView2d< real64 const, compflow::USD_PHASE > > const & phaseVolFrac,
93  ElementViewConst< arrayView3d< real64 const, compflow::USD_PHASE_DC > > const & dPhaseVolFrac,
94  ElementViewConst< arrayView4d< real64 const, constitutive::multifluid::USD_PHASE_COMP > > const & phaseCompFrac,
95  ElementViewConst< arrayView5d< real64 const, constitutive::multifluid::USD_PHASE_COMP_DC > > const & dPhaseCompFrac,
96  ElementViewConst< arrayView3d< real64 const, compflow::USD_COMP_DC > > const & dCompFrac_dCompDens,
97  ElementViewConst< arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > > const & phaseMassDens,
98  ElementViewConst< arrayView4d< real64 const, constitutive::multifluid::USD_PHASE_DC > > const & dPhaseMassDens,
99  ElementViewConst< arrayView3d< real64 const, constitutive::cappres::USD_CAPPRES > > const & phaseCapPressure,
100  ElementViewConst< arrayView4d< real64 const, constitutive::cappres::USD_CAPPRES_DS > > const & dPhaseCapPressure_dPhaseVolFrac,
101  localIndex & k_up,
102  real64 & potGrad,
103  real64 ( &phaseFlux ),
104  real64 ( & dPhaseFlux_dP )[numFluxSupportPoints],
105  real64 ( & dPhaseFlux_dC )[numFluxSupportPoints][numComp],
106  real64 ( & compFlux )[numComp],
107  real64 ( & dCompFlux_dP )[numFluxSupportPoints][numComp],
108  real64 ( & dCompFlux_dC )[numFluxSupportPoints][numComp][numComp] )
109  {
110  real64 dPresGrad_dP[numFluxSupportPoints]{};
111  real64 dPresGrad_dC[numFluxSupportPoints][numComp]{};
112  real64 dGravHead_dP[numFluxSupportPoints]{};
113  real64 dGravHead_dC[numFluxSupportPoints][numComp]{};
114  PotGrad::compute< numComp, numFluxSupportPoints >( numPhase, ip, hasCapPressure, checkPhasePresenceInGravity,
115  seri, sesri, sei, trans, dTrans_dPres, pres, gravCoef,
116  phaseVolFrac, dPhaseVolFrac, dCompFrac_dCompDens, phaseMassDens, dPhaseMassDens,
117  phaseCapPressure, dPhaseCapPressure_dPhaseVolFrac, potGrad, dPresGrad_dP,
118  dPresGrad_dC, dGravHead_dP, dGravHead_dC );
119 
120  // gravity head
121  real64 gravHead = 0.0;
122  for( integer i = 0; i < numFluxSupportPoints; i++ )
123  {
124  localIndex const er = seri[i];
125  localIndex const esr = sesri[i];
126  localIndex const ei = sei[i];
127 
128  real64 const gravD = trans[i] * gravCoef[er][esr][ei];
129 
130  gravHead += gravD;
131  }
132 
133  // *** upwinding ***
134 
135  // phase flux and derivatives
136 
137  // assuming TPFA in the code below
138 
139  real64 Ttrans = fabs( trans[0] );
140  potGrad = potGrad / Ttrans;
141 
142  real64 const mobility_i = phaseMob[seri[0]][sesri[0]][sei[0]][ip];
143  real64 const mobility_j = phaseMob[seri[1]][sesri[1]][sei[1]][ip];
144 
145  // compute phase flux, see Eqs. (66) and (69) from the reference above
146  real64 smoEps = epsC1PPU;
147  if( fabs( gravHead ) <= 1e-20 )
148  smoEps = 1000;
149  real64 const tmpSqrt = sqrt( potGrad * potGrad + smoEps * smoEps );
150  real64 const smoMax = 0.5 * (-potGrad + tmpSqrt);
151 
152  phaseFlux = Ttrans * ( potGrad * mobility_i - smoMax * (mobility_j - mobility_i) );
153 
154  // derivativess
155 
156  // first part, mobility derivative
157 
158  // dP
159  {
160  real64 const dMob_dP = dPhaseMob[seri[0]][sesri[0]][sei[0]][ip][Deriv::dP];
161  dPhaseFlux_dP[0] += Ttrans * potGrad * dMob_dP;
162  }
163 
164  // dC
165  {
166  arraySlice1d< real64 const, compflow::USD_PHASE_DC - 2 >
167  dPhaseMobSub = dPhaseMob[seri[0]][sesri[0]][sei[0]][ip];
168  for( integer jc = 0; jc < numComp; ++jc )
169  {
170  dPhaseFlux_dC[0][jc] += Ttrans * potGrad * dPhaseMobSub[Deriv::dC + jc];
171  }
172  }
173 
174  real64 const tmpInv = 1.0 / tmpSqrt;
175  real64 const dSmoMax_x = 0.5 * (1.0 - potGrad * tmpInv);
176 
177  // pressure gradient and mobility difference depend on all points in the stencil
178  real64 const dMobDiff_sign[numFluxSupportPoints] = {-1.0, 1.0};
179  for( integer ke = 0; ke < numFluxSupportPoints; ++ke )
180  {
181  // dP
182 
183  real64 const dPotGrad_dP = dPresGrad_dP[ke] - dGravHead_dP[ke];
184 
185  // first part
186  dPhaseFlux_dP[ke] += dPotGrad_dP * mobility_i;
187 
188  // second part
189  real64 const dSmoMax_dP = -dPotGrad_dP * dSmoMax_x;
190  dPhaseFlux_dP[ke] += -dSmoMax_dP * (mobility_j - mobility_i);
191 
192  real64 const dMob_dP = dPhaseMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dP];
193  dPhaseFlux_dP[ke] += -Ttrans * smoMax * dMobDiff_sign[ke] * dMob_dP;
194 
195  // dC
196 
197  arraySlice1d< real64 const, compflow::USD_PHASE_DC - 2 >
198  dPhaseMobSub = dPhaseMob[seri[ke]][sesri[ke]][sei[ke]][ip];
199 
200  for( integer jc = 0; jc < numComp; ++jc )
201  {
202  real64 const dPotGrad_dC = dPresGrad_dC[ke][jc] - dGravHead_dC[ke][jc];
203 
204  // first part
205  dPhaseFlux_dC[ke][jc] += dPotGrad_dC * mobility_i;
206 
207  // second part
208  real64 const dSmoMax_dC = -dPotGrad_dC * dSmoMax_x;
209  dPhaseFlux_dC[ke][jc] += -dSmoMax_dC * (mobility_j - mobility_i);
210  dPhaseFlux_dC[ke][jc] += -Ttrans * smoMax * dMobDiff_sign[ke] * dPhaseMobSub[Deriv::dC + jc];
211  }
212  }
213 
214  potGrad = potGrad * Ttrans;
215 
216  // choose upstream cell for composition upwinding
217  k_up = (phaseFlux >= 0) ? 0 : 1;
218 
219  //distribute on phaseComponentFlux here
220  PhaseComponentFlux::compute( ip, k_up, seri, sesri, sei, phaseCompFrac, dPhaseCompFrac, dCompFrac_dCompDens, phaseFlux
221  , dPhaseFlux_dP, dPhaseFlux_dC, compFlux, dCompFlux_dP, dCompFlux_dC );
222  }
223 };
224 
225 } // namespace isothermalCompositionalMultiPhaseFVMKernelUtilities
226 
227 } // namespace geos
228 
229 
230 #endif // GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_C1PPUPHASEFLUX_HPP
#define GEOS_HOST_DEVICE
Marks a host-device function.
Definition: GeosxMacros.hpp:49
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Definition: DataTypes.hpp:180
ArrayView< T, 5, USD > arrayView5d
Alias for 5D array view.
Definition: DataTypes.hpp:244
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
ArraySlice< T, 1, USD > arraySlice1d
Alias for 1D array slice.
Definition: DataTypes.hpp:184
std::int32_t integer
Signed integer type.
Definition: DataTypes.hpp:82
ArrayView< T, 4, USD > arrayView4d
Alias for 4D array view.
Definition: DataTypes.hpp:228
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.
Definition: DataTypes.hpp:196
ArrayView< T, 3, USD > arrayView3d
Alias for 3D array view.
Definition: DataTypes.hpp:212
static GEOS_HOST_DEVICE void compute(integer const numPhase, integer const ip, integer const hasCapPressure, integer const checkPhasePresenceInGravity, localIndex const (&seri)[numFluxSupportPoints], localIndex const (&sesri)[numFluxSupportPoints], localIndex const (&sei)[numFluxSupportPoints], real64 const (&trans)[2], real64 const (&dTrans_dPres)[2], ElementViewConst< arrayView1d< real64 const > > const &pres, ElementViewConst< arrayView1d< real64 const > > const &gravCoef, ElementViewConst< arrayView2d< real64 const, compflow::USD_PHASE > > const &phaseMob, ElementViewConst< arrayView3d< real64 const, compflow::USD_PHASE_DC > > const &dPhaseMob, ElementViewConst< arrayView2d< real64 const, compflow::USD_PHASE > > const &phaseVolFrac, ElementViewConst< arrayView3d< real64 const, compflow::USD_PHASE_DC > > const &dPhaseVolFrac, ElementViewConst< arrayView4d< real64 const, constitutive::multifluid::USD_PHASE_COMP > > const &phaseCompFrac, ElementViewConst< arrayView5d< real64 const, constitutive::multifluid::USD_PHASE_COMP_DC > > const &dPhaseCompFrac, ElementViewConst< arrayView3d< real64 const, compflow::USD_COMP_DC > > const &dCompFrac_dCompDens, ElementViewConst< arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > > const &phaseMassDens, ElementViewConst< arrayView4d< real64 const, constitutive::multifluid::USD_PHASE_DC > > const &dPhaseMassDens, ElementViewConst< arrayView3d< real64 const, constitutive::cappres::USD_CAPPRES > > const &phaseCapPressure, ElementViewConst< arrayView4d< real64 const, constitutive::cappres::USD_CAPPRES_DS > > const &dPhaseCapPressure_dPhaseVolFrac, localIndex &k_up, real64 &potGrad, real64(&phaseFlux), real64(&dPhaseFlux_dP)[numFluxSupportPoints], real64(&dPhaseFlux_dC)[numFluxSupportPoints][numComp], real64(&compFlux)[numComp], real64(&dCompFlux_dP)[numFluxSupportPoints][numComp], real64(&dCompFlux_dC)[numFluxSupportPoints][numComp][numComp])
Form the PhasePotentialUpwind from pressure gradient and gravitational head.
static GEOS_HOST_DEVICE void compute(localIndex const ip, localIndex const k_up, localIndex const (&seri)[numFluxSupportPoints], localIndex const (&sesri)[numFluxSupportPoints], localIndex const (&sei)[numFluxSupportPoints], ElementViewConst< arrayView4d< real64 const, constitutive::multifluid::USD_PHASE_COMP > > const &phaseCompFrac, ElementViewConst< arrayView5d< real64 const, constitutive::multifluid::USD_PHASE_COMP_DC > > const &dPhaseCompFrac, ElementViewConst< arrayView3d< real64 const, compflow::USD_COMP_DC > > const &dCompFrac_dCompDens, real64 const &phaseFlux, real64 const (&dPhaseFlux_dP)[numFluxSupportPoints], real64 const (&dPhaseFlux_dC)[numFluxSupportPoints][numComp], real64(&compFlux)[numComp], real64(&dCompFlux_dP)[numFluxSupportPoints][numComp], real64(&dCompFlux_dC)[numFluxSupportPoints][numComp][numComp])
Compute the component flux for a given phase.