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