GEOS
PotGradZFormulation.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_POTGRADZFORMULATION_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_POTGRADZFORMULATION_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 
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 useNewGravity,
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, 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  calculateMeanDensity( useNewGravity, ip, seri, sesri, sei, phaseVolFrac, phaseMassDens, dPhaseMassDens, densMean, dDensMean_dP, dDensMean_dC );
91 
93  for( integer i = 0; i < numFluxSupportPoints; i++ )
94  {
95  localIndex const er = seri[i];
96  localIndex const esr = sesri[i];
97  localIndex const ei = sei[i];
98 
99  // capillary pressure
100  real64 capPressure = 0.0;
101  real64 dCapPressure_dP = 0.0;
102 
103  for( integer ic = 0; ic < numComp; ++ic )
104  {
105  dCapPressure_dC[ic] = 0.0;
106  }
107 
108  if( hasCapPressure )
109  {
110  capPressure = phaseCapPressure[er][esr][ei][0][ip];
111 
112  for( integer jp = 0; jp < numPhase; ++jp )
113  {
114  real64 const dCapPressure_dS = dPhaseCapPressure_dPhaseVolFrac[er][esr][ei][0][ip][jp];
115  dCapPressure_dP += dCapPressure_dS * dPhaseVolFrac[er][esr][ei][jp][Deriv::dP];
116 
117  for( integer jc = 0; jc < numComp; ++jc )
118  {
119  dCapPressure_dC[jc] += dCapPressure_dS * dPhaseVolFrac[er][esr][ei][jp][Deriv::dC+jc];
120  }
121  }
122  }
123 
124  presGrad += trans[i] * (pres[er][esr][ei] - capPressure);
125  dPresGrad_dP[i] += trans[i] * (1 - dCapPressure_dP)
126  + dTrans_dPres[i] * (pres[er][esr][ei] - capPressure);
127  for( integer jc = 0; jc < numComp; ++jc )
128  {
129  dPresGrad_dC[i][jc] += -trans[i] * dCapPressure_dC[jc];
130  }
131 
132  real64 const gravD = trans[i] * gravCoef[er][esr][ei];
133  real64 const dGravD_dP = dTrans_dPres[i] * gravCoef[er][esr][ei];
134 
135  // the density used in the potential difference is always a mass density
136  // unlike the density used in the phase mobility, which is a mass density
137  // if useMass == 1 and a molar density otherwise
138  gravHead += densMean * gravD;
139 
140  // need to add contributions from both cells the mean density depends on
141  for( integer j = 0; j < numFluxSupportPoints; ++j )
142  {
143  dGravHead_dP[j] += dDensMean_dP[j] * gravD + dGravD_dP * densMean;
144  for( integer jc = 0; jc < numComp; ++jc )
145  {
146  dGravHead_dC[j][jc] += dDensMean_dC[j][jc] * gravD;
147  }
148  }
149  }
150 
151  // compute phase potential gradient
152  potGrad = presGrad - gravHead;
153 
154  }
155 
156  template< integer numComp, integer numFluxSupportPoints >
158  static void
159  calculateMeanDensity( integer const useNewGravity,
160  integer const ip,
161  localIndex const ( &seri )[numFluxSupportPoints],
162  localIndex const ( &sesri )[numFluxSupportPoints],
163  localIndex const ( &sei )[numFluxSupportPoints],
164  ElementViewConst< arrayView2d< real64 const, compflow::USD_PHASE > > const & phaseVolFrac,
165  ElementViewConst< arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > > const & phaseMassDens,
166  ElementViewConst< arrayView4d< real64 const, constitutive::multifluid::USD_PHASE_DC > > const & dPhaseMassDens,
167  real64 & densMean, real64 ( & dDensMean_dP)[numFluxSupportPoints], real64 ( & dDensMean_dC )[numFluxSupportPoints][numComp] )
168  {
169  // calculate quantities on primary connected cells
170  integer denom = 0;
171  for( integer i = 0; i < numFluxSupportPoints; ++i )
172  {
173  localIndex const er = seri[i];
174  localIndex const esr = sesri[i];
175  localIndex const ei = sei[i];
176 
177  bool const phaseExists = (phaseVolFrac[er][esr][ei][ip] > 0);
178  if( useNewGravity && !phaseExists )
179  {
180  continue;
181  }
182 
183  // density
184  real64 const density = phaseMassDens[er][esr][ei][0][ip];
185  real64 const dDens_dP = dPhaseMassDens[er][esr][ei][0][ip][Deriv::dP];
186 
187  // average density and derivatives
188  densMean += density;
189  dDensMean_dP[i] = dDens_dP;
190  for( integer jc = 0; jc < numComp; ++jc )
191  {
192  dDensMean_dC[i][jc] = dPhaseMassDens[er][esr][ei][0][ip][Deriv::dC+jc];
193  }
194  denom++;
195  }
196  if( denom > 1 )
197  {
198  densMean /= denom;
199  for( integer i = 0; i < numFluxSupportPoints; ++i )
200  {
201  dDensMean_dP[i] /= denom;
202  for( integer jc = 0; jc < numComp; ++jc )
203  {
204  dDensMean_dC[i][jc] /= denom;
205  }
206  }
207  }
208  }
209 
210 };
211 
212 } // namespace isothermalCompositionalMultiPhaseFVMKernelUtilities
213 
214 } // namespace geos
215 
216 #endif // GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_POTGRADZFORMULATION_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 useNewGravity, 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, 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])