20 #ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_KERNELS_COMPOSITIONAL_CAPILLARYPRESSUREINVERSIONKERNEL_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_KERNELS_COMPOSITIONAL_CAPILLARYPRESSUREINVERSIONKERNEL_HPP
23 #include "constitutive/capillaryPressure/InverseCapillaryPressure.hpp"
24 #include "constitutive/capillaryPressure/CapillaryPressureFields.hpp"
25 #include "codingUtilities/Utilities.hpp"
30 namespace isothermalCompositionalMultiphaseBaseKernels
37 template<
typename CAP_PRESSURE = NoOpFunc >
40 template<
integer numComps,
integer numPhases >
42 CAP_PRESSURE & capPressure,
51 constitutive::InverseCapillaryPressure< CAP_PRESSURE > inverseCapPressureType( capPressure );
52 auto capPressureWrapper = inverseCapPressureType.createKernelWrapper();
56 constexpr
bool isJFunction = std::is_same_v< CAP_PRESSURE, constitutive::JFunctionCapillaryPressure >;
57 if constexpr ( isJFunction )
59 jFuncMultiplier = capPressure.template getField< geos::fields::cappres::jFuncMultiplier >().reference().toViewConst();
62 integer const ipGas = phaseOrder[constitutive::CapillaryPressureBase::PhaseType::GAS];
63 integer const ipWater = phaseOrder[constitutive::CapillaryPressureBase::PhaseType::WATER];
64 integer const ipOil = phaseOrder[constitutive::CapillaryPressureBase::PhaseType::OIL];
66 if constexpr ( numPhases == 2 )
68 if( 0 <= ipGas && 0 <= ipWater )
73 if( 0 <= ipOil && 0 <= ipWater )
78 if( 0 <= ipGas && 0 <= ipOil )
84 if constexpr ( numPhases == 3 )
91 localIndex const numPoints = pressureValues.size( 0 );
93 forAll< parallelDevicePolicy<> >( targetSet.size(), [targetSet,
102 phaseComponentFractions,
106 real64 const elevation = elementCenter[k][2];
108 real64 ea = elevationIndexTable.compute( &elevation );
109 integer const en = LvArray::math::min(
static_cast< integer >(ea), numPoints - 2 );
114 calculateCapillaryPressure< numPhases >( ea,
115 pressureValues[en][0],
116 pressureValues[en+1][0],
118 targetPhaseCapPressure[0][0] );
121 real64 constexpr initialPhaseVolumeFractionGuess = 1.0 / numPhases;
122 for(
integer ip = 0; ip < numPhases; ++ip )
124 targetPhaseVolumeFraction[0][ip] = initialPhaseVolumeFractionGuess;
127 localIndex const jFunctionIndex = isJFunction ? k : 0;
128 capPressureWrapper.compute( targetPhaseCapPressure[0][0],
129 jFuncMultiplier[jFunctionIndex],
130 targetPhaseVolumeFraction[0] );
132 for(
integer ic = 0; ic < numComps; ++ic )
134 globalComponentFractions[k][ic] = 0.0;
137 for(
integer ip = 0; ip < numPhases; ++ip )
139 real64 const density0 = phaseDensityValues[en][0][ip];
140 real64 const density1 = phaseDensityValues[en+1][0][ip];
141 real64 const phaseMass = ((1.0-ea)*density0 + ea*density1) * targetPhaseVolumeFraction[0][ip];
142 for(
integer ic = 0; ic < numComps; ++ic )
144 real64 const fraction0 = phaseComponentFractions[en][0][ip][ic];
145 real64 const fraction1 = phaseComponentFractions[en+1][0][ip][ic];
146 real64 const componentMass = phaseMass * ((1.0-ea)*fraction0 + ea*fraction1);
147 globalComponentFractions[k][ic] += componentMass;
148 totalMass += componentMass;
151 for(
integer ic = 0; ic < numComps; ++ic )
153 globalComponentFractions[k][ic] /= totalMass;
158 template<
integer numPhases >
162 integer const phaseOrder[numPhases],
165 if constexpr (numPhases == 2)
167 real64 const capPressure0 = phasePressures0[phaseOrder[0]] - phasePressures0[phaseOrder[1]];
168 real64 const capPressure1 = phasePressures1[phaseOrder[0]] - phasePressures1[phaseOrder[1]];
169 phaseCapPressure[phaseOrder[1]] = (1.0-alpha)*capPressure0 + alpha*capPressure1;
171 if constexpr (numPhases == 3)
173 real64 const capPressure00 = phasePressures0[phaseOrder[1]] - phasePressures0[phaseOrder[0]];
174 real64 const capPressure01 = phasePressures1[phaseOrder[1]] - phasePressures1[phaseOrder[0]];
175 phaseCapPressure[phaseOrder[0]] = (1.0-alpha)*capPressure00 + alpha*capPressure01;
176 real64 const capPressure10 = phasePressures0[phaseOrder[1]] - phasePressures0[phaseOrder[2]];
177 real64 const capPressure11 = phasePressures1[phaseOrder[1]] - phasePressures1[phaseOrder[2]];
178 phaseCapPressure[phaseOrder[2]] = (1.0-alpha)*capPressure10 + alpha*capPressure11;
#define GEOS_HOST_DEVICE
Marks a host-device function.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Array< T, 2, PERMUTATION > array2d
Alias for 2D array.
LvArray::StackArray< T, NDIM, PERMUTATION, localIndex, MAXSIZE > StackArray
Multidimensional stack-based array type. See LvArray:StackArray for details.
double real64
64-bit floating point type.
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
ArraySlice< T, 1, USD > arraySlice1d
Alias for 1D array slice.
LvArray::SortedArrayView< T, localIndex, LvArray::ChaiBuffer > SortedArrayView
A sorted array view of local indices.
ArrayView< T, 4, USD > arrayView4d
Alias for 4D array view.
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.
int integer
Signed integer type.
ArrayView< T, 3, USD > arrayView3d
Alias for 3D array view.
Kernel for the inversion of capillary pressure to saturation when we have multiphase initialisation.