20 #ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_FLUXKERNELSHELPER_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_FLUXKERNELSHELPER_HPP
25 #include "constitutive/fluid/singlefluid/SingleFluidLayouts.hpp"
30 namespace singlePhaseFluxKernelsHelper
39 template<
typename VIEWTYPE >
44 void computeSinglePhaseFlux(
localIndex const ( &seri )[2],
47 real64 const ( &transmissibility )[2],
48 real64 const ( &dTrans_dPres )[2],
62 using DerivOffset = constitutive::singlefluid::DerivativeOffsetC< 0 >;
69 densMean += 0.5 * dens[seri[ke]][sesri[ke]][sei[ke]][0];
70 dDensMean_dP[ke] = 0.5 * dDens[seri[ke]][sesri[ke]][sei[ke]][0][DerivOffset::dP];
74 real64 dpotGrad_dTrans = 0.0;
75 real64 sumWeightGrav = 0.0;
77 int signpotGradf[2] = {1, -1};
85 real64 const pressure = pres[er][esr][ei];
86 real64 const gravD = gravCoef[er][esr][ei];
87 real64 const pot = transmissibility[ke] * ( pressure - densMean * gravD );
90 dpotGrad_dTrans += signpotGradf[ke] * ( pressure - densMean * gravD );
91 sumWeightGrav += transmissibility[ke] * gravD;
93 potScale = fmax( potScale, fabs( pot ) );
97 real64 constexpr upwRelTol = 1e-8;
98 real64 const upwAbsTol = fmax( potScale * upwRelTol, LvArray::NumericLimits< real64 >::epsilon );
101 alpha = ( potGrad + upwAbsTol ) / ( 2 * upwAbsTol );
104 if( alpha <= 0.0 || alpha >= 1.0 )
108 mobility = mob[seri[ke]][sesri[ke]][sei[ke]];
109 dMobility_dP[ke] = dMob[seri[ke]][sesri[ke]][sei[ke]][DerivOffset::dP];
114 real64 const mobWeights[2] = { alpha, 1.0 - alpha };
117 mobility += mobWeights[ke] * mob[seri[ke]][sesri[ke]][sei[ke]];
118 dMobility_dP[ke] = mobWeights[ke] * dMob[seri[ke]][sesri[ke]][sei[ke]][DerivOffset::dP];
123 fluxVal = mobility * potGrad;
125 dFlux_dTrans = mobility * dpotGrad_dTrans;
129 dFlux_dP[ke] = mobility * ( transmissibility[ke] - dDensMean_dP[ke] * sumWeightGrav )
130 + dMobility_dP[ke] * potGrad + dFlux_dTrans * dTrans_dPres[ke];
136 template<
typename ENERGYFLUX_DERIVATIVE_TYPE >
138 void computeEnthalpyFlux(
localIndex const ( &seri )[2],
141 real64 const ( &transmissibility )[2],
151 real64 const & dMassFlux_dTrans,
152 real64 const ( &dMassFlux_dP )[2],
153 real64 ( & dMassFlux_dT )[2],
155 real64 & dEnergyFlux_dTrans,
156 ENERGYFLUX_DERIVATIVE_TYPE & dEnergyFlux_dP,
157 ENERGYFLUX_DERIVATIVE_TYPE & dEnergyFlux_dT )
160 using DerivOffset = constitutive::singlefluid::DerivativeOffsetC< 1 >;
161 real64 dDensMean_dT[2]{0.0, 0.0};
163 for(
integer ke = 0; ke < 2; ++ke )
165 real64 const dDens_dT = dDens[seri[ke]][sesri[ke]][sei[ke]][0][DerivOffset::dT];
166 dDensMean_dT[ke] = 0.5 * dDens_dT;
172 real64 dGravHead_dT[2]{0.0, 0.0};
175 for(
integer ke = 0; ke < 2; ++ke )
182 real64 const gravD = transmissibility[ke] * gravCoef[er][esr][ei];
184 for(
integer i = 0; i < 2; ++i )
186 dGravHead_dT[i] += dDensMean_dT[i] * gravD;
194 for(
integer ke = 0; ke < 2; ++ke )
196 dMassFlux_dT[ke] -= dGravHead_dT[ke];
199 for(
integer ke = 0; ke < 2; ++ke )
201 dMassFlux_dT[ke] *= mobility;
206 if( alpha <= 0.0 || alpha >= 1.0 )
210 dMob_dT[k_up] = dMob[seri[k_up]][sesri[k_up]][sei[k_up]][DerivOffset::dT];
214 real64 const mobWeights[2] = { alpha, 1.0 - alpha };
215 for(
integer ke = 0; ke < 2; ++ke )
217 dMob_dT[ke] = mobWeights[ke] * dMob[seri[ke]][sesri[ke]][sei[ke]][DerivOffset::dT];
222 for(
integer ke = 0; ke < 2; ++ke )
224 dMassFlux_dT[ke] += dMob_dT[ke] * potGrad;
228 real64 enthalpyTimesMobWeight = 0.0;
229 real64 dEnthalpy_dP[2]{0.0, 0.0};
230 real64 dEnthalpy_dT[2]{0.0, 0.0};
232 if( alpha <= 0.0 || alpha >= 1.0 )
236 enthalpyTimesMobWeight = enthalpy[seri[k_up]][sesri[k_up]][sei[k_up]][0];
237 dEnthalpy_dP[k_up] = dEnthalpy[seri[k_up]][sesri[k_up]][sei[k_up]][0][DerivOffset::dP];
238 dEnthalpy_dT[k_up] = dEnthalpy[seri[k_up]][sesri[k_up]][sei[k_up]][0][DerivOffset::dT];
242 real64 const mobWeights[2] = { alpha, 1.0 - alpha };
243 for(
integer ke = 0; ke < 2; ++ke )
245 enthalpyTimesMobWeight += mobWeights[ke] * enthalpy[seri[ke]][sesri[ke]][sei[ke]][0];
246 dEnthalpy_dP[ke] = mobWeights[ke] * dEnthalpy[seri[ke]][sesri[ke]][sei[ke]][0][DerivOffset::dP];
247 dEnthalpy_dT[ke] = mobWeights[ke] * dEnthalpy[seri[ke]][sesri[ke]][sei[ke]][0][DerivOffset::dT];
251 energyFlux += massFlux * enthalpyTimesMobWeight;
252 dEnergyFlux_dTrans = enthalpyTimesMobWeight * dMassFlux_dTrans;
254 for(
integer ke = 0; ke < 2; ++ke )
256 dEnergyFlux_dP[ke] += dMassFlux_dP[ke] * enthalpyTimesMobWeight;
257 dEnergyFlux_dT[ke] += dMassFlux_dT[ke] * enthalpyTimesMobWeight;
260 for(
integer ke = 0; ke < 2; ++ke )
262 dEnergyFlux_dP[ke] += massFlux * dEnthalpy_dP[ke];
263 dEnergyFlux_dT[ke] += massFlux * dEnthalpy_dT[ke];
268 template<
typename ENERGYFLUX_DERIVATIVE_TYPE >
270 void computeConductiveFlux(
localIndex const ( &seri )[2],
273 ElementViewConst< arrayView1d< real64 const > >
const & temperature,
274 real64 const ( &thermalTrans )[2],
276 ENERGYFLUX_DERIVATIVE_TYPE & dEnergyFlux_dT )
278 for(
integer ke = 0; ke < 2; ++ke )
284 energyFlux += thermalTrans[ke] * temperature[er][esr][ei];
285 dEnergyFlux_dT[ke] += thermalTrans[ke];
ElementRegionManager::ElementViewConst< VIEWTYPE > ElementViewConst
The type for element-based data. Consists entirely of ArrayView's.
#define GEOS_HOST_DEVICE
Marks a host-device function.
typename ElementViewAccessor< VIEWTYPE >::NestedViewTypeConst ElementViewConst
The ElementViewAccessor at the ElementRegionManager level is the type resulting from ElementViewAcces...
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
double real64
64-bit floating point type.
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
std::int32_t integer
Signed integer type.
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.
ArrayView< T, 3, USD > arrayView3d
Alias for 3D array view.