GEOS
PotGrad.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_POTGRAD_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_POTGRAD_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"
28 
29 
30 namespace geos
31 {
32 
33 namespace isothermalCompositionalMultiphaseFVMKernelUtilities
34 {
35 
36 template< typename VIEWTYPE >
37 using ElementViewConst = ElementRegionManager::ElementViewConst< VIEWTYPE >;
38 
39 using Deriv = constitutive::multifluid::DerivativeOffset;
40 
41 struct PotGrad
42 {
43  template< integer numComp, integer numFluxSupportPoints >
45  static void
46  compute ( integer const numPhase,
47  integer const ip,
48  integer const hasCapPressure,
49  integer const checkPhasePresenceInGravity,
50  localIndex const ( &seri )[numFluxSupportPoints],
51  localIndex const ( &sesri )[numFluxSupportPoints],
52  localIndex const ( &sei )[numFluxSupportPoints],
53  real64 const ( &trans )[numFluxSupportPoints],
54  real64 const ( &dTrans_dPres )[numFluxSupportPoints],
55  ElementViewConst< arrayView1d< real64 const > > const & pres,
56  ElementViewConst< arrayView1d< real64 const > > const & gravCoef,
57  ElementViewConst< arrayView2d< real64 const, compflow::USD_PHASE > > const & phaseVolFrac,
58  ElementViewConst< arrayView3d< real64 const, compflow::USD_PHASE_DC > > const & dPhaseVolFrac,
59  ElementViewConst< arrayView3d< real64 const, compflow::USD_COMP_DC > > const & dCompFrac_dCompDens,
60  ElementViewConst< arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > > const & phaseMassDens,
61  ElementViewConst< arrayView4d< real64 const, constitutive::multifluid::USD_PHASE_DC > > const & dPhaseMassDens,
62  ElementViewConst< arrayView3d< real64 const, constitutive::cappres::USD_CAPPRES > > const & phaseCapPressure,
63  ElementViewConst< arrayView4d< real64 const, constitutive::cappres::USD_CAPPRES_DS > > const & dPhaseCapPressure_dPhaseVolFrac,
64  real64 & potGrad,
65  real64 & dPotGrad_dTrans,
66  real64 ( & dPresGrad_dP )[numFluxSupportPoints],
67  real64 ( & dPresGrad_dC )[numFluxSupportPoints][numComp],
68  real64 ( & dGravHead_dP )[numFluxSupportPoints],
69  real64 ( & dGravHead_dC )[numFluxSupportPoints][numComp] )
70  {
71  // assign derivatives arrays to zero
72  for( integer i = 0; i < numFluxSupportPoints; ++i )
73  {
74  dPresGrad_dP[i] = 0.0;
75  dGravHead_dP[i] = 0.0;
76  for( integer jc = 0; jc < numComp; ++jc )
77  {
78  dPresGrad_dC[i][jc] = 0.0;
79  dGravHead_dC[i][jc] = 0.0;
80  }
81  }
82 
83  // create local work arrays
84  real64 densMean = 0.0;
85  real64 dDensMean_dP[numFluxSupportPoints]{};
86  real64 dDensMean_dC[numFluxSupportPoints][numComp]{};
87 
88  real64 presGrad = 0.0;
89  real64 dPresGrad_dTrans = 0.0;
90  real64 gravHead = 0.0;
91  real64 dGravHead_dTrans = 0.0;
92  real64 dCapPressure_dC[numComp]{};
93 
94  calculateMeanDensity( checkPhasePresenceInGravity, ip,
95  seri, sesri, sei,
96  phaseVolFrac, dCompFrac_dCompDens,
97  phaseMassDens, dPhaseMassDens,
98  densMean, dDensMean_dP, dDensMean_dC );
99 
101  for( integer i = 0; i < numFluxSupportPoints; i++ )
102  {
103  localIndex const er = seri[i];
104  localIndex const esr = sesri[i];
105  localIndex const ei = sei[i];
106 
107  // capillary pressure
108  real64 capPressure = 0.0;
109  real64 dCapPressure_dP = 0.0;
110 
111  for( integer ic = 0; ic < numComp; ++ic )
112  {
113  dCapPressure_dC[ic] = 0.0;
114  }
115 
116  if( hasCapPressure )
117  {
118  capPressure = phaseCapPressure[er][esr][ei][0][ip];
119 
120  for( integer jp = 0; jp < numPhase; ++jp )
121  {
122  real64 const dCapPressure_dS = dPhaseCapPressure_dPhaseVolFrac[er][esr][ei][0][ip][jp];
123  dCapPressure_dP += dCapPressure_dS * dPhaseVolFrac[er][esr][ei][jp][Deriv::dP];
124 
125  for( integer jc = 0; jc < numComp; ++jc )
126  {
127  dCapPressure_dC[jc] += dCapPressure_dS * dPhaseVolFrac[er][esr][ei][jp][Deriv::dC+jc];
128  }
129  }
130  }
131 
132  real64 const dP = pres[er][esr][ei] - capPressure;
133  presGrad += trans[i] * dP;
134  dPresGrad_dTrans += dP;
135  dPresGrad_dP[i] += trans[i] * (1 - dCapPressure_dP) + dTrans_dPres[i] * dP;
136  for( integer jc = 0; jc < numComp; ++jc )
137  {
138  dPresGrad_dC[i][jc] += -trans[i] * dCapPressure_dC[jc];
139  }
140 
141  real64 const gC = gravCoef[er][esr][ei];
142  real64 const gravD = trans[i] * gC;
143  real64 const dGravD_dTrans = gC;
144  real64 const dGravD_dP = dTrans_dPres[i] * gC;
145 
146  // the density used in the potential difference is always a mass density
147  // unlike the density used in the phase mobility, which is a mass density
148  // if useMass == 1 and a molar density otherwise
149  gravHead += densMean * gravD;
150  dGravHead_dTrans += densMean * dGravD_dTrans;
151  // need to add contributions from both cells the mean density depends on
152  for( integer j = 0; j < numFluxSupportPoints; ++j )
153  {
154  dGravHead_dP[j] += dDensMean_dP[j] * gravD + dGravD_dP * densMean;
155  for( integer jc = 0; jc < numComp; ++jc )
156  {
157  dGravHead_dC[j][jc] += dDensMean_dC[j][jc] * gravD;
158  }
159  }
160  }
161 
162  // compute phase potential gradient
163  potGrad = presGrad - gravHead;
164  dPotGrad_dTrans = dPresGrad_dTrans - dGravHead_dTrans;
165  }
166 
167  template< integer numComp, integer numFluxSupportPoints >
169  static void
170  calculateMeanDensity( integer const checkPhasePresenceInGravity,
171  integer const ip,
172  localIndex const ( &seri )[numFluxSupportPoints],
173  localIndex const ( &sesri )[numFluxSupportPoints],
174  localIndex const ( &sei )[numFluxSupportPoints],
175  ElementViewConst< arrayView2d< real64 const, compflow::USD_PHASE > > const & phaseVolFrac,
176  ElementViewConst< arrayView3d< real64 const, compflow::USD_COMP_DC > > const & dCompFrac_dCompDens,
177  ElementViewConst< arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > > const & phaseMassDens,
178  ElementViewConst< arrayView4d< real64 const, constitutive::multifluid::USD_PHASE_DC > > const & dPhaseMassDens,
179  real64 & densMean, real64 ( & dDensMean_dP)[numFluxSupportPoints], real64 ( & dDensMean_dC )[numFluxSupportPoints][numComp] )
180  {
181  real64 dDens_dC[numComp]{};
182 
183  integer denom = 0;
184  for( integer i = 0; i < numFluxSupportPoints; ++i )
185  {
186  localIndex const er = seri[i];
187  localIndex const esr = sesri[i];
188  localIndex const ei = sei[i];
189 
190  bool const phaseExists = (phaseVolFrac[er][esr][ei][ip] > 0);
191  if( checkPhasePresenceInGravity && !phaseExists )
192  {
193  continue;
194  }
195 
196  // density
197  real64 const density = phaseMassDens[er][esr][ei][0][ip];
198  real64 const dDens_dP = dPhaseMassDens[er][esr][ei][0][ip][Deriv::dP];
199 
200  applyChainRule( numComp,
201  dCompFrac_dCompDens[er][esr][ei],
202  dPhaseMassDens[er][esr][ei][0][ip],
203  dDens_dC,
204  Deriv::dC );
205 
206  // average density and derivatives
207  densMean += density;
208  dDensMean_dP[i] = dDens_dP;
209  for( integer jc = 0; jc < numComp; ++jc )
210  {
211  dDensMean_dC[i][jc] = dDens_dC[jc];
212  }
213  denom++;
214  }
215  if( denom > 1 )
216  {
217  densMean /= denom;
218  for( integer i = 0; i < numFluxSupportPoints; ++i )
219  {
220  dDensMean_dP[i] /= denom;
221  for( integer jc = 0; jc < numComp; ++jc )
222  {
223  dDensMean_dC[i][jc] /= denom;
224  }
225  }
226  }
227  }
228 
229 };
230 
231 } // namespace isothermalCompositionalMultiPhaseFVMKernelUtilities
232 
233 } // namespace geos
234 
235 #endif // GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_POTGRAD_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
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
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)[numFluxSupportPoints], real64 const (&dTrans_dPres)[numFluxSupportPoints], ElementViewConst< arrayView1d< real64 const > > const &pres, ElementViewConst< arrayView1d< real64 const > > const &gravCoef, ElementViewConst< arrayView2d< real64 const, compflow::USD_PHASE > > const &phaseVolFrac, ElementViewConst< arrayView3d< real64 const, compflow::USD_PHASE_DC > > const &dPhaseVolFrac, 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, real64 &potGrad, real64 &dPotGrad_dTrans, real64(&dPresGrad_dP)[numFluxSupportPoints], real64(&dPresGrad_dC)[numFluxSupportPoints][numComp], real64(&dGravHead_dP)[numFluxSupportPoints], real64(&dGravHead_dC)[numFluxSupportPoints][numComp])
Definition: PotGrad.hpp:46