GEOS
PhaseMobilityKernel.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_PHASEMOBILITYKERNEL_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_PHASEMOBILITYKERNEL_HPP
22 
24 
25 namespace geos
26 {
27 
28 namespace isothermalCompositionalMultiphaseFVMKernels
29 {
30 
31 /******************************** PhaseMobilityKernel ********************************/
32 
39 template< integer NUM_COMP, integer NUM_PHASE >
41 {
42 public:
43 
45  using Base::numComp;
46 
48  static constexpr integer numPhase = NUM_PHASE;
49 
57  constitutive::MultiFluidBase const & fluid,
58  constitutive::RelativePermeabilityBase const & relperm )
59  : Base(),
60  m_phaseVolFrac( subRegion.getField< fields::flow::phaseVolumeFraction >() ),
61  m_dPhaseVolFrac( subRegion.getField< fields::flow::dPhaseVolumeFraction >() ),
62  m_dCompFrac_dCompDens( subRegion.getField< fields::flow::dGlobalCompFraction_dGlobalCompDensity >() ),
63  m_phaseDens( fluid.phaseDensity() ),
64  m_dPhaseDens( fluid.dPhaseDensity() ),
65  m_phaseVisc( fluid.phaseViscosity() ),
66  m_dPhaseVisc( fluid.dPhaseViscosity() ),
67  m_phaseRelPerm( relperm.phaseRelPerm() ),
68  m_dPhaseRelPerm_dPhaseVolFrac( relperm.dPhaseRelPerm_dPhaseVolFraction() ),
69  m_phaseMob( subRegion.getField< fields::flow::phaseMobility >() ),
70  m_dPhaseMob( subRegion.getField< fields::flow::dPhaseMobility >() )
71  {}
72 
79  template< typename FUNC = NoOpFunc >
81  void compute( localIndex const ei,
82  FUNC && phaseMobilityKernelOp = NoOpFunc{} ) const
83  {
84  using Deriv = constitutive::multifluid::DerivativeOffset;
85 
86  arraySlice2d< real64 const, compflow::USD_COMP_DC - 1 > const dCompFrac_dCompDens = m_dCompFrac_dCompDens[ei];
87  arraySlice1d< real64 const, constitutive::multifluid::USD_PHASE - 2 > const phaseDens = m_phaseDens[ei][0];
88  arraySlice2d< real64 const, constitutive::multifluid::USD_PHASE_DC - 2 > const dPhaseDens = m_dPhaseDens[ei][0];
89  arraySlice1d< real64 const, constitutive::multifluid::USD_PHASE - 2 > const phaseVisc = m_phaseVisc[ei][0];
90  arraySlice2d< real64 const, constitutive::multifluid::USD_PHASE_DC - 2 > const dPhaseVisc = m_dPhaseVisc[ei][0];
91  arraySlice1d< real64 const, constitutive::relperm::USD_RELPERM - 2 > const phaseRelPerm = m_phaseRelPerm[ei][0];
92  arraySlice2d< real64 const, constitutive::relperm::USD_RELPERM_DS - 2 > const dPhaseRelPerm_dPhaseVolFrac = m_dPhaseRelPerm_dPhaseVolFrac[ei][0];
93  arraySlice1d< real64 const, compflow::USD_PHASE - 1 > const phaseVolFrac = m_phaseVolFrac[ei];
94  arraySlice2d< real64 const, compflow::USD_PHASE_DC - 1 > const dPhaseVolFrac = m_dPhaseVolFrac[ei];
95  arraySlice1d< real64, compflow::USD_PHASE - 1 > const phaseMob = m_phaseMob[ei];
96  arraySlice2d< real64, compflow::USD_PHASE_DC - 1 > const dPhaseMob = m_dPhaseMob[ei];
97 
98  real64 dRelPerm_dC[numComp]{};
99  real64 dDens_dC[numComp]{};
100  real64 dVisc_dC[numComp]{};
101 
102  for( integer ip = 0; ip < numPhase; ++ip )
103  {
104 
105  // compute the phase mobility only if the phase is present
106  bool const phaseExists = (phaseVolFrac[ip] > 0);
107  if( !phaseExists )
108  {
109  phaseMob[ip] = 0.0;
110  for( integer jc = 0; jc < numComp + 2; ++jc )
111  {
112  dPhaseMob[ip][jc] = 0.0;
113  }
114  continue;
115  }
116 
117  real64 const density = phaseDens[ip];
118  real64 const dDens_dP = dPhaseDens[ip][Deriv::dP];
119  applyChainRule( numComp, dCompFrac_dCompDens, dPhaseDens[ip], dDens_dC, Deriv::dC );
120 
121  real64 const viscosity = phaseVisc[ip];
122  real64 const dVisc_dP = dPhaseVisc[ip][Deriv::dP];
123  applyChainRule( numComp, dCompFrac_dCompDens, dPhaseVisc[ip], dVisc_dC, Deriv::dC );
124 
125  real64 const relPerm = phaseRelPerm[ip];
126  real64 dRelPerm_dP = 0.0;
127  for( integer ic = 0; ic < numComp; ++ic )
128  {
129  dRelPerm_dC[ic] = 0.0;
130  }
131 
132  for( integer jp = 0; jp < numPhase; ++jp )
133  {
134  real64 const dRelPerm_dS = dPhaseRelPerm_dPhaseVolFrac[ip][jp];
135  dRelPerm_dP += dRelPerm_dS * dPhaseVolFrac[jp][Deriv::dP];
136 
137  for( integer jc = 0; jc < numComp; ++jc )
138  {
139  dRelPerm_dC[jc] += dRelPerm_dS * dPhaseVolFrac[jp][Deriv::dC+jc];
140  }
141  }
142 
143  real64 const mobility = relPerm * density / viscosity;
144 
145  phaseMob[ip] = mobility;
146  dPhaseMob[ip][Deriv::dP] = dRelPerm_dP * density / viscosity
147  + mobility * (dDens_dP / density - dVisc_dP / viscosity);
148 
149  // compositional derivatives
150  for( integer jc = 0; jc < numComp; ++jc )
151  {
152  dPhaseMob[ip][Deriv::dC+jc] = dRelPerm_dC[jc] * density / viscosity
153  + mobility * (dDens_dC[jc] / density - dVisc_dC[jc] / viscosity);
154  }
155 
156  // call the lambda in the phase loop to allow the reuse of the relperm, density, viscosity, and mobility
157  // possible use: assemble the derivatives wrt temperature
158  phaseMobilityKernelOp( ip, phaseMob[ip], dPhaseMob[ip] );
159  }
160  }
161 
162 protected:
163 
164  // inputs
165 
170 
174 
178 
182 
183  // outputs
184 
188 
189 };
190 
195 {
196 public:
197 
207  template< typename POLICY >
208  static void
209  createAndLaunch( integer const numComp,
210  integer const numPhase,
211  ObjectManagerBase & subRegion,
212  constitutive::MultiFluidBase const & fluid,
213  constitutive::RelativePermeabilityBase const & relperm )
214  {
215  if( numPhase == 2 )
216  {
217  isothermalCompositionalMultiphaseBaseKernels::internal::kernelLaunchSelectorCompSwitch( numComp, [&] ( auto NC )
218  {
219  integer constexpr NUM_COMP = NC();
220  PhaseMobilityKernel< NUM_COMP, 2 > kernel( subRegion, fluid, relperm );
221  PhaseMobilityKernel< NUM_COMP, 2 >::template launch< POLICY >( subRegion.size(), kernel );
222  } );
223  }
224  else if( numPhase == 3 )
225  {
226  isothermalCompositionalMultiphaseBaseKernels::internal::kernelLaunchSelectorCompSwitch( numComp, [&] ( auto NC )
227  {
228  integer constexpr NUM_COMP = NC();
229  PhaseMobilityKernel< NUM_COMP, 3 > kernel( subRegion, fluid, relperm );
230  PhaseMobilityKernel< NUM_COMP, 3 >::template launch< POLICY >( subRegion.size(), kernel );
231  } );
232  }
233  }
234 };
235 
236 } // namespace isothermalCompositionalMultiphaseFVMKernels
237 
238 } // namespace geos
239 
240 
241 #endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_PHASEMOBILITYKERNEL_HPP
#define GEOS_HOST_DEVICE
Marks a host-device function.
Definition: GeosxMacros.hpp:49
The ObjectManagerBase is the base object of all object managers in the mesh data hierachy.
localIndex size() const
Get the "size" of the group, which determines the number of elements in resizable wrappers.
Definition: Group.hpp:1315
Define the base interface for the property update kernels.
static constexpr integer numComp
Compile time value for the number of components.
static void createAndLaunch(integer const numComp, integer const numPhase, ObjectManagerBase &subRegion, constitutive::MultiFluidBase const &fluid, constitutive::RelativePermeabilityBase const &relperm)
Create a new kernel and launch.
Defines the interface for the property kernel in charge of computing the phase mobilities.
arrayView2d< real64 const, compflow::USD_PHASE > m_phaseVolFrac
Views on the phase volume fractions.
PhaseMobilityKernel(ObjectManagerBase &subRegion, constitutive::MultiFluidBase const &fluid, constitutive::RelativePermeabilityBase const &relperm)
Constructor.
arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > m_phaseDens
Views on the phase densities.
arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > m_phaseVisc
Views on the phase viscosities.
static constexpr integer numPhase
Compile time value for the number of phases.
GEOS_HOST_DEVICE void compute(localIndex const ei, FUNC &&phaseMobilityKernelOp=NoOpFunc{}) const
Compute the phase mobilities in an element.
arrayView3d< real64 const, constitutive::relperm::USD_RELPERM > m_phaseRelPerm
Views on the phase relative permeabilities.
static constexpr integer numComp
Compile time value for the number of components.
arrayView2d< real64, compflow::USD_PHASE > m_phaseMob
Views on the phase mobilities.
ArraySlice< T, 2, USD > arraySlice2d
Alias for 2D array slice.
Definition: DataTypes.hpp:200
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