20 #ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_FLUXKERNELSHELPER_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_FLUXKERNELSHELPER_HPP
29 namespace singlePhaseFluxKernelsHelper
38 template<
typename VIEWTYPE >
43 void computeSinglePhaseFlux(
localIndex const ( &seri )[2],
46 real64 const ( &transmissibility )[2],
47 real64 const ( &dTrans_dPres )[2],
67 densMean += 0.5 * dens[seri[ke]][sesri[ke]][sei[ke]][0];
68 dDensMean_dP[ke] = 0.5 * dDens_dPres[seri[ke]][sesri[ke]][sei[ke]][0];
72 real64 dpotGrad_dTrans = 0.0;
73 real64 sumWeightGrav = 0.0;
75 int signpotGradf[2] = {1, -1};
83 real64 const pressure = pres[er][esr][ei];
84 real64 const gravD = gravCoef[er][esr][ei];
85 real64 const pot = transmissibility[ke] * ( pressure - densMean * gravD );
88 dpotGrad_dTrans += signpotGradf[ke] * ( pressure - densMean * gravD );
89 sumWeightGrav += transmissibility[ke] * gravD;
91 potScale = fmax( potScale, fabs( pot ) );
95 real64 constexpr upwRelTol = 1e-8;
96 real64 const upwAbsTol = fmax( potScale * upwRelTol, LvArray::NumericLimits< real64 >::epsilon );
99 alpha = ( potGrad + upwAbsTol ) / ( 2 * upwAbsTol );
102 if( alpha <= 0.0 || alpha >= 1.0 )
106 mobility = mob[seri[ke]][sesri[ke]][sei[ke]];
107 dMobility_dP[ke] = dMob_dPres[seri[ke]][sesri[ke]][sei[ke]];
112 real64 const mobWeights[2] = { alpha, 1.0 - alpha };
115 mobility += mobWeights[ke] * mob[seri[ke]][sesri[ke]][sei[ke]];
116 dMobility_dP[ke] = mobWeights[ke] * dMob_dPres[seri[ke]][sesri[ke]][sei[ke]];
121 fluxVal = mobility * potGrad;
123 dFlux_dTrans = mobility * dpotGrad_dTrans;
127 dFlux_dP[ke] = mobility * ( transmissibility[ke] - dDensMean_dP[ke] * sumWeightGrav )
128 + dMobility_dP[ke] * potGrad + dFlux_dTrans * dTrans_dPres[ke];
134 template<
typename ENERGYFLUX_DERIVATIVE_TYPE >
136 void computeEnthalpyFlux(
localIndex const ( &seri )[2],
139 real64 const ( &transmissibility )[2],
150 real64 const & dMassFlux_dTrans,
151 real64 const ( &dMassFlux_dP )[2],
152 real64 ( & dMassFlux_dT )[2],
154 real64 & dEnergyFlux_dTrans,
155 ENERGYFLUX_DERIVATIVE_TYPE & dEnergyFlux_dP,
156 ENERGYFLUX_DERIVATIVE_TYPE & dEnergyFlux_dT )
160 real64 dDensMean_dT[2]{0.0, 0.0};
162 for(
integer ke = 0; ke < 2; ++ke )
164 real64 const dDens_dT = dDens_dTemp[seri[ke]][sesri[ke]][sei[ke]][0];
165 dDensMean_dT[ke] = 0.5 * dDens_dT;
171 real64 dGravHead_dT[2]{0.0, 0.0};
174 for(
integer ke = 0; ke < 2; ++ke )
181 real64 const gravD = transmissibility[ke] * gravCoef[er][esr][ei];
183 for(
integer i = 0; i < 2; ++i )
185 dGravHead_dT[i] += dDensMean_dT[i] * gravD;
193 for(
integer ke = 0; ke < 2; ++ke )
195 dMassFlux_dT[ke] -= dGravHead_dT[ke];
198 for(
integer ke = 0; ke < 2; ++ke )
200 dMassFlux_dT[ke] *= mobility;
205 if( alpha <= 0.0 || alpha >= 1.0 )
209 dMob_dT[k_up] = dMob_dTemp[seri[k_up]][sesri[k_up]][sei[k_up]];
213 real64 const mobWeights[2] = { alpha, 1.0 - alpha };
214 for(
integer ke = 0; ke < 2; ++ke )
216 dMob_dT[ke] = mobWeights[ke] * dMob_dTemp[seri[ke]][sesri[ke]][sei[ke]];
221 for(
integer ke = 0; ke < 2; ++ke )
223 dMassFlux_dT[ke] += dMob_dT[ke] * potGrad;
227 real64 enthalpyTimesMobWeight = 0.0;
228 real64 dEnthalpy_dP[2]{0.0, 0.0};
229 real64 dEnthalpy_dT[2]{0.0, 0.0};
231 if( alpha <= 0.0 || alpha >= 1.0 )
235 enthalpyTimesMobWeight = enthalpy[seri[k_up]][sesri[k_up]][sei[k_up]][0];
236 dEnthalpy_dP[k_up] = dEnthalpy_dPressure[seri[k_up]][sesri[k_up]][sei[k_up]][0];
237 dEnthalpy_dT[k_up] = dEnthalpy_dTemperature[seri[k_up]][sesri[k_up]][sei[k_up]][0];
241 real64 const mobWeights[2] = { alpha, 1.0 - alpha };
242 for(
integer ke = 0; ke < 2; ++ke )
244 enthalpyTimesMobWeight += mobWeights[ke] * enthalpy[seri[ke]][sesri[ke]][sei[ke]][0];
245 dEnthalpy_dP[ke] = mobWeights[ke] * dEnthalpy_dPressure[seri[ke]][sesri[ke]][sei[ke]][0];
246 dEnthalpy_dT[ke] = mobWeights[ke] * dEnthalpy_dTemperature[seri[ke]][sesri[ke]][sei[ke]][0];
250 energyFlux += massFlux * enthalpyTimesMobWeight;
251 dEnergyFlux_dTrans = enthalpyTimesMobWeight * dMassFlux_dTrans;
253 for(
integer ke = 0; ke < 2; ++ke )
255 dEnergyFlux_dP[ke] += dMassFlux_dP[ke] * enthalpyTimesMobWeight;
256 dEnergyFlux_dT[ke] += dMassFlux_dT[ke] * enthalpyTimesMobWeight;
259 for(
integer ke = 0; ke < 2; ++ke )
261 dEnergyFlux_dP[ke] += massFlux * dEnthalpy_dP[ke];
262 dEnergyFlux_dT[ke] += massFlux * dEnthalpy_dT[ke];
267 template<
typename ENERGYFLUX_DERIVATIVE_TYPE >
269 void computeConductiveFlux(
localIndex const ( &seri )[2],
272 ElementViewConst< arrayView1d< real64 const > >
const & temperature,
273 real64 const ( &thermalTrans )[2],
275 ENERGYFLUX_DERIVATIVE_TYPE & dEnergyFlux_dT )
277 for(
integer ke = 0; ke < 2; ++ke )
283 energyFlux += thermalTrans[ke] * temperature[er][esr][ei];
284 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.