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