20 #ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_WELLS_PERFORATIONFLUXLKERNELS_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_WELLS_PERFORATIONFLUXLKERNELS_HPP
23 #include "codingUtilities/Utilities.hpp"
25 #include "common/GEOS_RAJA_Interface.hpp"
26 #include "constitutive/fluid/multifluid/MultiFluidBase.hpp"
27 #include "constitutive/fluid/multifluid/MultiFluidFields.hpp"
28 #include "constitutive/relativePermeability/RelativePermeabilityBase.hpp"
29 #include "constitutive/relativePermeability/RelativePermeabilityFields.hpp"
50 namespace isothermalPerforationFluxKernels
55 template<
integer NC,
integer NP,
integer IS_THERMAL >
72 fields::flow::phaseVolumeFraction,
73 fields::flow::dPhaseVolumeFraction,
74 fields::flow::dGlobalCompFraction_dGlobalCompDensity >;
78 fields::multifluid::phaseDensity,
79 fields::multifluid::dPhaseDensity,
80 fields::multifluid::phaseViscosity,
81 fields::multifluid::dPhaseViscosity,
82 fields::multifluid::phaseCompFraction,
83 fields::multifluid::dPhaseCompFraction >;
87 fields::relperm::phaseRelPerm,
88 fields::relperm::dPhaseRelPerm_dPhaseVolFraction >;
98 template<
typename VIEWTYPE >
106 bool const isInjector,
107 bool const isCrossflowEnabled ):
108 m_resPres( compFlowAccessors.get( fields::flow::pressure {} )),
109 m_resPhaseVolFrac( compFlowAccessors.get( fields::flow::phaseVolumeFraction {} )),
110 m_dResPhaseVolFrac( compFlowAccessors.get( fields::flow::dPhaseVolumeFraction {} )),
111 m_dResCompFrac_dCompDens( compFlowAccessors.get( fields::flow::dGlobalCompFraction_dGlobalCompDensity {} )),
112 m_resPhaseDens( multiFluidAccessors.get( fields::multifluid::phaseDensity {} )),
113 m_dResPhaseDens( multiFluidAccessors.get( fields::multifluid::dPhaseDensity {} )),
114 m_resPhaseVisc( multiFluidAccessors.get( fields::multifluid::phaseViscosity {} )),
115 m_dResPhaseVisc( multiFluidAccessors.get( fields::multifluid::dPhaseViscosity {} )),
116 m_resPhaseCompFrac( multiFluidAccessors.get( fields::multifluid::phaseCompFraction {} )),
117 m_dResPhaseCompFrac( multiFluidAccessors.get( fields::multifluid::dPhaseCompFraction {} )),
118 m_resPhaseRelPerm( relPermAccessors.get( fields::relperm::phaseRelPerm {} )),
119 m_dResPhaseRelPerm_dPhaseVolFrac( relPermAccessors.get( fields::relperm::dPhaseRelPerm_dPhaseVolFraction {} )),
120 m_wellElemGravCoef( subRegion.getField< fields::well::gravityCoefficient >()),
121 m_wellElemPres( subRegion.getField< fields::well::pressure >()),
122 m_wellElemCompDens( subRegion.getField< fields::well::globalCompDensity >()),
123 m_wellElemTotalMassDens( subRegion.getField< fields::well::totalMassDensity >()),
124 m_dWellElemTotalMassDens( subRegion.getField< fields::well::dTotalMassDensity >()),
125 m_wellElemCompFrac( subRegion.getField< fields::well::globalCompFraction >()),
126 m_dWellElemCompFrac_dCompDens( subRegion.getField< fields::well::dGlobalCompFraction_dGlobalCompDensity >()),
127 m_perfGravCoef( perforationData->getField< fields::well::gravityCoefficient >()),
128 m_perfWellElemIndex( perforationData->getField< fields::perforation::wellElementIndex >()),
129 m_perfTrans( perforationData->getField< fields::perforation::wellTransmissibility >()),
130 m_resElementRegion( perforationData->getField< fields::perforation::reservoirElementRegion >()),
131 m_resElementSubRegion( perforationData->getField< fields::perforation::reservoirElementSubRegion >()),
132 m_resElementIndex( perforationData->getField< fields::perforation::reservoirElementIndex >()),
133 m_compPerfRate( perforationData->getField< fields::well::compPerforationRate >()),
134 m_dCompPerfRate( perforationData->getField< fields::well::dCompPerforationRate >()),
135 m_perfStatus( perforationData->getField< fields::perforation::perforationStatus >()),
136 m_isInjector( isInjector ),
137 m_isCrossflowEnabled( isCrossflowEnabled )
149 real64 m_dPotDiff[2][constitutive::multifluid::DerivativeOffsetC< NC, IS_THERMAL >::nDer];
158 using CP_Deriv = constitutive::multifluid::DerivativeOffsetC< NC, IS_THERMAL >;
159 stack.m_potDiff = 0.0;
160 for(
integer i = 0; i < 2; ++i )
162 for(
integer ic = 0; ic < CP_Deriv::nDer; ++ic )
164 stack.m_dPotDiff[i][ic] = 0.0;
167 for(
integer ic = 0; ic < NC; ++ic )
169 m_compPerfRate[iperf][ic] = 0.0;
170 for(
integer ke = 0; ke < 2; ++ke )
172 for(
integer jc = 0; jc < CP_Deriv::nDer; ++jc )
174 m_dCompPerfRate[iperf][ke][ic][jc] = 0.0;
183 using CP_Deriv = constitutive::multifluid::DerivativeOffsetC< NC, IS_THERMAL >;
184 using Deriv = constitutive::multifluid::DerivativeOffset;
185 real64 dPres[2][CP_Deriv::nDer]{};
192 pres[TAG::RES] = m_resPres[er][esr][ei];
193 dPres[TAG::RES][CP_Deriv::dP] = 1.0;
194 multiplier[TAG::RES] = 1.0;
200 pres[TAG::WELL] = m_wellElemPres[iwelem];
201 dPres[TAG::WELL][CP_Deriv::dP] = 1.0;
202 multiplier[TAG::WELL] = -1.0;
204 real64 const gravD = ( m_perfGravCoef[iperf] - m_wellElemGravCoef[iwelem] );
206 pres[TAG::WELL] += m_wellElemTotalMassDens[iwelem] * gravD;
208 dPres[TAG::WELL][CP_Deriv::dP] += m_dWellElemTotalMassDens[iwelem][Deriv::dP] * gravD;
209 if constexpr ( IS_THERMAL )
211 dPres[TAG::WELL][CP_Deriv::dT] += m_dWellElemTotalMassDens[iwelem][Deriv::dT] * gravD;
213 for(
integer ic = 0; ic < NC; ++ic )
215 dPres[TAG::WELL][CP_Deriv::dC+ic] += m_dWellElemTotalMassDens[iwelem][Deriv::dC+ic] * gravD;
219 stack.m_potDiff = 0.0;
220 for(
integer i = 0; i < 2; ++i )
222 stack.m_potDiff += multiplier[i] * m_perfTrans[iperf] * pres[i];
224 for(
integer ic = 0; ic < CP_Deriv::nDer; ++ic )
226 stack.m_dPotDiff[i][ic] += multiplier[i] * m_perfTrans[iperf] * dPres[i][ic];
234 real64 & mob,
real64 (& dMob)[constitutive::multifluid::DerivativeOffsetC< NC, IS_THERMAL >::nDer] )
const
236 using CP_Deriv = constitutive::multifluid::DerivativeOffsetC< NC, IS_THERMAL >;
237 using Deriv = constitutive::multifluid::DerivativeOffset;
241 real64 const resVisc = m_resPhaseVisc[er][esr][ei][0][ip];
242 real64 dVisc[CP_Deriv::nDer]{};
243 dVisc[CP_Deriv::dP] = m_dResPhaseVisc[er][esr][ei][0][ip][Deriv::dP];
244 if constexpr ( IS_THERMAL )
246 dVisc[CP_Deriv::dT] = m_dResPhaseVisc[er][esr][ei][0][ip][Deriv::dT];
249 applyChainRule( NC, m_dResCompFrac_dCompDens[er][esr][ei],
250 m_dResPhaseVisc[er][esr][ei][0][ip],
251 &dVisc[CP_Deriv::dC],
255 real64 const resRelPerm = m_resPhaseRelPerm[er][esr][ei][0][ip];
256 real64 dRelPerm[CP_Deriv::nDer]{};
257 for(
integer jp = 0; jp < NP; ++jp )
259 real64 const dResRelPerm_dS = m_dResPhaseRelPerm_dPhaseVolFrac[er][esr][ei][0][ip][jp];
260 dRelPerm[CP_Deriv::dP] += dResRelPerm_dS * m_dResPhaseVolFrac[er][esr][ei][jp][Deriv::dP];
261 if constexpr ( IS_THERMAL )
263 dRelPerm[CP_Deriv::dT] += dResRelPerm_dS * m_dResPhaseVolFrac[er][esr][ei][jp][Deriv::dT];
265 for(
integer jc = 0; jc < NC; ++jc )
267 dRelPerm[CP_Deriv::dC+jc] += dResRelPerm_dS * m_dResPhaseVolFrac[er][esr][ei][jp][Deriv::dC+jc];
271 mob += resRelPerm / resVisc;
272 for(
integer jc = 0; jc < CP_Deriv::nDer; ++jc )
274 dMob[jc] += (dRelPerm[jc] *resVisc - resRelPerm * dVisc[jc] )
275 / ( resVisc * resVisc);
283 real64 & mob,
real64 (& dMob)[constitutive::multifluid::DerivativeOffsetC< NC, IS_THERMAL >::nDer] )
const
285 using CP_Deriv = constitutive::multifluid::DerivativeOffsetC< NC, IS_THERMAL >;
286 using Deriv = constitutive::multifluid::DerivativeOffset;
289 real64 const resDens = m_resPhaseDens[er][esr][ei][0][ip];
290 real64 dDens[CP_Deriv::nDer]{};
292 dDens[CP_Deriv::dP] = m_dResPhaseDens[er][esr][ei][0][ip][Deriv::dP];
293 if constexpr ( IS_THERMAL )
295 dDens[CP_Deriv::dT] = m_dResPhaseDens[er][esr][ei][0][ip][Deriv::dT];
297 applyChainRule( NC, m_dResCompFrac_dCompDens[er][esr][ei],
298 m_dResPhaseDens[er][esr][ei][0][ip],
299 &dDens[CP_Deriv::dC],
303 real64 const resVisc = m_resPhaseVisc[er][esr][ei][0][ip];
304 real64 dVisc[CP_Deriv::nDer]{};
305 dVisc[CP_Deriv::dP] = m_dResPhaseVisc[er][esr][ei][0][ip][Deriv::dP];
306 if constexpr ( IS_THERMAL )
308 dVisc[CP_Deriv::dT] = m_dResPhaseVisc[er][esr][ei][0][ip][Deriv::dT];
311 applyChainRule( NC, m_dResCompFrac_dCompDens[er][esr][ei],
312 m_dResPhaseVisc[er][esr][ei][0][ip],
313 &dVisc[CP_Deriv::dC],
317 real64 const resRelPerm = m_resPhaseRelPerm[er][esr][ei][0][ip];
318 real64 dRelPerm[CP_Deriv::nDer]{};
319 for(
integer jc = 0; jc < CP_Deriv::nDer; ++jc )
323 for(
integer jp = 0; jp < NP; ++jp )
325 real64 const dResRelPerm_dS = m_dResPhaseRelPerm_dPhaseVolFrac[er][esr][ei][0][ip][jp];
326 dRelPerm[CP_Deriv::dP] += dResRelPerm_dS * m_dResPhaseVolFrac[er][esr][ei][jp][Deriv::dP];
327 if constexpr ( IS_THERMAL )
329 dRelPerm[CP_Deriv::dT] += dResRelPerm_dS * m_dResPhaseVolFrac[er][esr][ei][jp][Deriv::dT];
331 for(
integer jc = 0; jc < NC; ++jc )
333 dRelPerm[CP_Deriv::dC+jc] += dResRelPerm_dS * m_dResPhaseVolFrac[er][esr][ei][jp][Deriv::dC+jc];
337 mob = resDens * resRelPerm / resVisc;
338 for(
integer jc = 0; jc < CP_Deriv::nDer; ++jc )
340 dMob[jc] = dRelPerm[jc] * resDens / resVisc
341 + mob * (dDens[jc] / resDens - dVisc[jc] / resVisc);
345 template<
typename FUNC = NoOpFunc >
353 if( !m_perfStatus[iperf] )
358 using Deriv = constitutive::multifluid::DerivativeOffset;
359 using CP_Deriv = constitutive::multifluid::DerivativeOffsetC< NC, IS_THERMAL >;
366 real64 dMob[CP_Deriv::nDer]{};
370 real64 dFlux[2][CP_Deriv::nDer]{};
371 real64 dCompFrac[CP_Deriv::nDer]{};
373 if( stack.m_potDiff >= 0 )
378 for(
integer ip = 0; ip < NP; ++ip )
382 real64 const resPhaseVolFrac = m_resPhaseVolFrac[er][esr][ei][ip];
383 bool const phaseExists = (resPhaseVolFrac > 0);
384 if( !phaseExists || (m_isInjector && !m_isCrossflowEnabled) )
389 computeDensityMobilityandDeriv( ip, er, esr, ei, mob, dMob );
390 fluxKernelOp( ip, resPhaseVolFrac, mob, dMob );
392 flux = mob * stack.m_potDiff;
394 for(
integer jc = 0; jc < CP_Deriv::nDer; ++jc )
396 dFlux[TAG::RES][jc] = dMob[jc] * stack.m_potDiff + mob * stack.m_dPotDiff[TAG::RES][jc];
397 dFlux[TAG::WELL][jc] = mob * stack.m_dPotDiff[TAG::WELL][jc];
401 for(
integer ic = 0; ic < NC; ++ic )
403 m_compPerfRate[iperf][ic] += flux * m_resPhaseCompFrac[er][esr][ei][0][ip][ic];
404 dCompFrac[CP_Deriv::dP] = m_dResPhaseCompFrac[er][esr][ei][0][ip][ic][Deriv::dP];
405 if constexpr (IS_THERMAL)
407 dCompFrac[CP_Deriv::dT] = m_dResPhaseCompFrac[er][esr][ei][0][ip][ic][Deriv::dT];
411 m_dResCompFrac_dCompDens[er][esr][ei],
412 m_dResPhaseCompFrac[er][esr][ei][0][ip][ic],
413 &dCompFrac[CP_Deriv::dC],
416 for(
integer jc = 0; jc < CP_Deriv::nDer; ++jc )
418 m_dCompPerfRate[iperf][TAG::RES][ic][jc] += dFlux[TAG::RES][jc] * m_resPhaseCompFrac[er][esr][ei][0][ip][ic];
419 m_dCompPerfRate[iperf][TAG::RES][ic][jc] += flux * dCompFrac[jc];
420 m_dCompPerfRate[iperf][TAG::WELL][ic][jc] += dFlux[TAG::WELL][jc] * m_resPhaseCompFrac[er][esr][ei][0][ip][ic];
428 real64 dResTotalMob[CP_Deriv::nDer]{};
430 real64 wellElemTotalDens = 0;
431 for(
integer ic = 0; ic < NC; ++ic )
433 wellElemTotalDens += m_wellElemCompDens[iwelem][ic];
437 for(
integer ip = 0; ip < NP; ++ip )
441 bool const phaseExists = (m_resPhaseVolFrac[er][esr][ei][ip] > 0);
442 if( !phaseExists || (!m_isInjector && !m_isCrossflowEnabled) )
446 computeMobilityandDeriv( ip, er, esr, ei, resTotalMob, dResTotalMob );
451 real64 const mult = wellElemTotalDens * resTotalMob;
453 real64 dMult[2][CP_Deriv::nDer]{};
454 dMult[TAG::WELL][CP_Deriv::dP] = 0.0;
455 if constexpr ( IS_THERMAL )
457 dMult[TAG::WELL][CP_Deriv::dT] = 0.0;
459 for(
integer ic = 0; ic < NC; ++ic )
461 dMult[TAG::WELL][CP_Deriv::dC+ic] = resTotalMob;
463 for(
integer jc = 0; jc < CP_Deriv::nDer; ++jc )
465 dMult[TAG::RES][jc] = wellElemTotalDens * dResTotalMob[jc];
469 flux = mult * stack.m_potDiff;
470 for(
integer ic = 0; ic < CP_Deriv::nDer; ++ic )
472 dFlux[TAG::RES][ic] = dMult[TAG::RES][ic] * stack.m_potDiff + mult * stack.m_dPotDiff[TAG::RES][ic];
473 dFlux[TAG::WELL][ic] = dMult[TAG::WELL][ic] * stack.m_potDiff + mult * stack.m_dPotDiff[TAG::WELL][ic];
477 for(
integer ic = 0; ic < NC; ++ic )
479 m_compPerfRate[iperf][ic] += m_wellElemCompFrac[iwelem][ic] * flux;
480 for(
integer jc = 0; jc < CP_Deriv::nDer; ++jc )
482 m_dCompPerfRate[iperf][TAG::RES][ic][jc] = m_wellElemCompFrac[iwelem][ic] * dFlux[TAG::RES][jc];
485 for(
integer ic = 0; ic < NC; ++ic )
487 m_dCompPerfRate[iperf][TAG::WELL][ic][CP_Deriv::dP] = m_wellElemCompFrac[iwelem][ic] * dFlux[TAG::WELL][CP_Deriv::dP];
488 if constexpr ( IS_THERMAL )
490 m_dCompPerfRate[iperf][TAG::WELL][ic][CP_Deriv::dT] = m_wellElemCompFrac[iwelem][ic] * dFlux[TAG::WELL][CP_Deriv::dT];
492 for(
integer jc = 0; jc < NC; ++jc )
494 m_dCompPerfRate[iperf][TAG::WELL][ic][CP_Deriv::dC+jc] += m_wellElemCompFrac[iwelem][ic] * dFlux[TAG::WELL][CP_Deriv::dC+jc];
495 m_dCompPerfRate[iperf][TAG::WELL][ic][CP_Deriv::dC+jc] += m_dWellElemCompFrac_dCompDens[iwelem][ic][jc] * flux;
498 if constexpr ( IS_THERMAL )
502 fluxKernelOp( -1, -1, resTotalMob, dResTotalMob );
513 template<
typename POLICY,
typename KERNEL_TYPE >
516 KERNEL_TYPE
const & kernelComponent )
521 typename KERNEL_TYPE::StackVariables stack;
523 localIndex const er = kernelComponent.m_resElementRegion[iperf];
524 localIndex const esr = kernelComponent.m_resElementSubRegion[iperf];
525 localIndex const ei = kernelComponent.m_resElementIndex[iperf];
527 localIndex const iwelem = kernelComponent.m_perfWellElemIndex[iperf];
529 kernelComponent.initialize( iperf, stack );
530 kernelComponent.computePotentialandDeriv( iperf, er, esr, ei, iwelem, stack );
531 kernelComponent.computeFlux( iperf, er, esr, ei, iwelem, stack );
537 ElementViewConst< arrayView1d< real64 const > >
const m_resPres;
538 ElementViewConst< arrayView2d< real64 const, compflow::USD_PHASE > >
const m_resPhaseVolFrac;
539 ElementViewConst< arrayView3d< real64 const, compflow::USD_PHASE_DC > >
const m_dResPhaseVolFrac;
540 ElementViewConst< arrayView3d< real64 const, compflow::USD_COMP_DC > >
const m_dResCompFrac_dCompDens;
541 ElementViewConst< arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > >
const m_resPhaseDens;
542 ElementViewConst< arrayView4d< real64 const, constitutive::multifluid::USD_PHASE_DC > >
const m_dResPhaseDens;
543 ElementViewConst< arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > >
const m_resPhaseVisc;
544 ElementViewConst< arrayView4d< real64 const, constitutive::multifluid::USD_PHASE_DC > >
const m_dResPhaseVisc;
545 ElementViewConst< arrayView4d< real64 const, constitutive::multifluid::USD_PHASE_COMP > >
const m_resPhaseCompFrac;
546 ElementViewConst< arrayView5d< real64 const, constitutive::multifluid::USD_PHASE_COMP_DC > >
const m_dResPhaseCompFrac;
547 ElementViewConst< arrayView3d< real64 const, constitutive::relperm::USD_RELPERM > >
const m_resPhaseRelPerm;
548 ElementViewConst< arrayView4d< real64 const, constitutive::relperm::USD_RELPERM_DS > >
const m_dResPhaseRelPerm_dPhaseVolFrac;
568 bool const m_isInjector;
569 bool const m_isCrossflowEnabled;
592 template<
typename POLICY >
596 string const flowSolverName,
600 bool const isInjector,
601 bool const isCrossflowEnabled )
603 geos::internal::kernelLaunchSelectorCompPhaseSwitch( numComp, numPhases, [&](
auto NC,
auto NP )
605 integer constexpr NUM_COMP = NC();
606 integer constexpr NUM_PHASE = NP();
607 integer constexpr IS_THERMAL = 0;
610 typename kernelType::CompFlowAccessors compFlowAccessors( elemManager, flowSolverName );
611 typename kernelType::MultiFluidAccessors multiFluidAccessors( elemManager, flowSolverName );
612 typename kernelType::RelPermAccessors relPermAccessors( elemManager, flowSolverName );
614 kernelType kernel( perforationData, subRegion,
615 compFlowAccessors, multiFluidAccessors, relPermAccessors,
616 isInjector, isCrossflowEnabled );
617 kernelType::template launch< POLICY >( perforationData->
size(), kernel );
624 namespace thermalPerforationFluxKernels
627 using namespace constitutive;
631 template<
integer NC,
integer NP,
integer IS_THERMAL >
637 using Base::m_dWellElemCompFrac_dCompDens;
638 using Base::m_resPres;
639 using Base::m_resPhaseVolFrac;
640 using Base::m_dResPhaseVolFrac;
641 using Base::m_dResCompFrac_dCompDens;
642 using Base::m_resPhaseDens;
643 using Base::m_dResPhaseDens;
644 using Base::m_resPhaseVisc;
645 using Base::m_dResPhaseVisc;
646 using Base::m_resPhaseCompFrac;
647 using Base::m_dResPhaseCompFrac;
648 using Base::m_resPhaseRelPerm;
649 using Base::m_dResPhaseRelPerm_dPhaseVolFrac;
650 using Base::m_isInjector;
651 using Base::m_isCrossflowEnabled;
652 using Base::m_resElementRegion;
653 using Base::m_resElementSubRegion;
654 using Base::m_resElementIndex;
655 using Base::m_perfWellElemIndex;
664 using Base::StackVariables::m_potDiff;
665 using Base::StackVariables::m_dPotDiff;
674 static constexpr
integer isThermal = IS_THERMAL;
687 fields::multifluid::phaseFraction,
688 fields::multifluid::dPhaseFraction,
689 fields::multifluid::phaseEnthalpy,
690 fields::multifluid::dPhaseEnthalpy >;
699 template<
typename VIEWTYPE >
704 MultiFluidBase
const & wellFluid,
710 bool const isInjector,
711 bool const isCrossflowEnabled )
712 :
Base( perforationData,
718 isCrossflowEnabled ),
719 m_wellElemPhaseVolFrac( subRegion.getField< fields::well::phaseVolumeFraction >() ),
720 m_dWellElemPhaseVolFrac( subRegion.getField< fields::well::dPhaseVolumeFraction >() ),
721 m_wellElemPhaseDensity( wellFluid.phaseDensity() ),
722 m_dWellElemPhaseDensity( wellFluid.dPhaseDensity()),
723 m_wellElemPhaseEnthalpy( wellFluid.phaseEnthalpy()),
724 m_dWellElemPhaseEnthalpy( wellFluid.dPhaseEnthalpy()),
725 m_energyPerfFlux( perforationData->getField< fields::well::energyPerforationFlux >() ),
726 m_dEnergyPerfFlux( perforationData->getField< fields::well::dEnergyPerforationFlux >() ),
727 m_temp( thermalCompFlowAccessors.get( fields::flow::temperature {} ) ),
728 m_resPhaseFraction( thermalMultiFluidAccessors.get( fields::multifluid::phaseFraction {} ) ),
729 m_dResPhaseFraction( thermalMultiFluidAccessors.get( fields::multifluid::dPhaseFraction {} )),
730 m_resPhaseEnthalpy( thermalMultiFluidAccessors.get( fields::multifluid::phaseEnthalpy {} ) ),
731 m_dResPhaseEnthalpy( thermalMultiFluidAccessors.get( fields::multifluid::dPhaseEnthalpy {} ) )
734 template<
typename FUNC = NoOpFunc >
740 using Deriv = constitutive::multifluid::DerivativeOffset;
741 using CP_Deriv =constitutive::multifluid::DerivativeOffsetC< NC, IS_THERMAL >;
743 m_energyPerfFlux[iperf]=0;
744 for(
integer ke = 0; ke < 2; ++ke )
746 for(
integer i = 0; i < CP_Deriv::nDer; ++i )
748 m_dEnergyPerfFlux[iperf][ke][i]=0;
751 if( stack.m_potDiff >= 0 )
753 real64 dEmob[CP_Deriv::nDer]{};
754 Base::computeFlux ( iperf, er, esr, ei, iwelem, stack, [&](
localIndex const ip,
real64 const resPhaseVolFrac,
real64 const mob,
real64 const (&dMob)[CP_Deriv::nDer] )
757 real64 const resEnthalpy = m_resPhaseEnthalpy[er][esr][ei][0][ip];
758 real64 dResEnthalpy[CP_Deriv::nDer]{};
759 dResEnthalpy[CP_Deriv::dP] = m_dResPhaseEnthalpy[er][esr][ei][0][ip][Deriv::dP];
760 dResEnthalpy[CP_Deriv::dT] = m_dResPhaseEnthalpy[er][esr][ei][0][ip][Deriv::dT];
762 applyChainRule( NC, m_dResCompFrac_dCompDens[er][esr][ei],
763 m_dResPhaseEnthalpy[er][esr][ei][0][ip],
764 &dResEnthalpy[CP_Deriv::dC],
766 for(
integer jc = 0; jc < CP_Deriv::nDer; ++jc )
768 dEmob[jc] = dMob[jc] * m_resPhaseEnthalpy[er][esr][ei][0][ip] + mob * dResEnthalpy[jc];
770 real64 resPhaseMobE = mob * resEnthalpy;
771 real64 eflux = resPhaseMobE * stack.m_potDiff;
772 real64 dEFlux[2][CP_Deriv::nDer]{};
773 dEFlux[TAG::WELL][CP_Deriv::dP] = resPhaseMobE * stack.m_dPotDiff[TAG::WELL][CP_Deriv::dP];
774 dEFlux[TAG::WELL][CP_Deriv::dT] = resPhaseMobE * stack.m_dPotDiff[TAG::WELL][CP_Deriv::dT];
776 for(
integer jc = 0; jc < CP_Deriv::nDer; ++jc )
778 dEFlux[TAG::RES][jc] = dEmob[jc] * stack.m_potDiff + resPhaseMobE * stack.m_dPotDiff[TAG::RES][jc];
779 m_dEnergyPerfFlux[iperf][TAG::WELL][jc] = resPhaseMobE * stack.m_dPotDiff[TAG::WELL][jc];
781 m_energyPerfFlux[iperf] += eflux;
783 m_dEnergyPerfFlux[iperf][TAG::RES][CP_Deriv::dP] += dEFlux[TAG::RES][CP_Deriv::dP] * resPhaseVolFrac +
784 eflux * m_dResPhaseFraction[er][esr][ei][0][ip][Deriv::dP];
785 m_dEnergyPerfFlux[iperf][TAG::RES][CP_Deriv::dT] += dEFlux[TAG::RES][CP_Deriv::dT] * resPhaseVolFrac +
786 eflux *m_dResPhaseFraction[er][esr][ei][0][ip][Deriv::dT];
787 real64 dProp_dC[numComp]{};
789 m_dResCompFrac_dCompDens[er][esr][ei],
790 m_dResPhaseFraction[er][esr][ei][0][ip],
793 for(
integer jc = 0; jc < NC; ++jc )
795 m_dEnergyPerfFlux[iperf][TAG::RES][CP_Deriv::dC+jc] += dEFlux[TAG::RES][CP_Deriv::dC+jc];
801 Base::computeFlux ( iperf, er, esr, ei, iwelem, stack, [&](
localIndex const null1,
real64 const null2,
real64 const mob,
real64 const (&dMob)[CP_Deriv::nDer] )
805 real64 dMult[CP_Deriv::nDer]{};
809 arraySlice1d<
real64 const, compflow::USD_PHASE - 1 > phaseVolFrac = m_wellElemPhaseVolFrac[iwelem];
810 arraySlice2d<
real64 const, compflow::USD_PHASE_DC - 1 > dPhaseVolFrac = m_dWellElemPhaseVolFrac[iwelem];
811 arraySlice1d<
real64 const, constitutive::multifluid::USD_PHASE - 2 > phaseDens = m_wellElemPhaseDensity[iwelem][0];
812 arraySlice2d<
real64 const, constitutive::multifluid::USD_PHASE_DC - 2 > dPhaseDens = m_dWellElemPhaseDensity[iwelem][0];
813 arraySlice1d<
real64 const, constitutive::multifluid::USD_PHASE - 2 > phaseEnthalpy = m_wellElemPhaseEnthalpy[iwelem][0];
814 arraySlice2d<
real64 const, constitutive::multifluid::USD_PHASE_DC - 2 > dPhaseEnthalpy = m_dWellElemPhaseEnthalpy[iwelem][0];
816 for(
integer iphase = 0; iphase < NP; ++iphase )
818 bool const phaseExists = (phaseVolFrac[iphase] > 0);
819 if( !phaseExists || (!m_isInjector && !m_isCrossflowEnabled) )
823 totalEnthalpy += phaseEnthalpy[iphase] * phaseVolFrac[iphase] * phaseDens[iphase];
824 dMult[CP_Deriv::dP] += phaseEnthalpy[iphase] * dPhaseVolFrac[iphase][Deriv::dP] * phaseDens[iphase] +
825 dPhaseEnthalpy[iphase][Deriv::dP] * phaseVolFrac[iphase] * phaseDens[iphase] +
826 phaseEnthalpy[iphase] * phaseVolFrac[iphase] * dPhaseDens[iphase][Deriv::dP];
827 dMult[CP_Deriv::dT ] += phaseEnthalpy[iphase] * dPhaseVolFrac[iphase][Deriv::dT] * phaseDens[iphase] +
828 dPhaseEnthalpy[iphase][Deriv::dT] *phaseVolFrac[iphase] * phaseDens[iphase]+
829 phaseEnthalpy[iphase] * phaseVolFrac[iphase] * dPhaseDens[iphase][Deriv::dT];
831 for(
integer jc = 0; jc < NC; ++jc )
833 dProp_dC[jc] += phaseVolFrac[iphase] * phaseDens[iphase] * dPhaseEnthalpy[iphase][Deriv::dC+jc]
834 + phaseVolFrac[iphase] * dPhaseDens[iphase][Deriv::dC+jc] * phaseEnthalpy[iphase];
835 dMult[CP_Deriv::dC+jc] += phaseEnthalpy[iphase] * phaseDens[iphase] * dPhaseVolFrac[iphase][Deriv::dC+jc];
839 real64 dProp_dD[numComp]{};
841 m_dWellElemCompFrac_dCompDens[iwelem],
845 for(
integer iphase=0; iphase < NP; ++iphase )
847 for(
integer jc = 0; jc < NC; ++jc )
849 dMult[CP_Deriv::dC+jc] += phaseVolFrac[iphase] * phaseDens[iphase] * dProp_dD[jc]
850 + phaseEnthalpy[iphase] * phaseVolFrac[iphase] * dProp_dD[jc];
854 real64 eflux = mob * totalEnthalpy*stack.m_potDiff;
855 m_energyPerfFlux[iperf] = eflux;
856 for(
integer jc = 0; jc < CP_Deriv::nDer; ++jc )
858 m_dEnergyPerfFlux[iperf][TAG::WELL][jc] = mob* dMult[jc]*stack.m_potDiff
859 + mob* totalEnthalpy * stack.m_dPotDiff[TAG::WELL][jc];
860 m_dEnergyPerfFlux[iperf][TAG::RES][jc] = dMob[jc]*totalEnthalpy*stack.m_potDiff
861 + mob* totalEnthalpy * stack.m_dPotDiff[TAG::RES][jc];
875 template<
typename POLICY,
typename KERNEL_TYPE >
878 KERNEL_TYPE
const & kernelComponent )
883 typename KERNEL_TYPE::StackVariables stack;
885 localIndex const er = kernelComponent.m_resElementRegion[iperf];
886 localIndex const esr = kernelComponent.m_resElementSubRegion[iperf];
887 localIndex const ei = kernelComponent.m_resElementIndex[iperf];
889 localIndex const iwelem = kernelComponent.m_perfWellElemIndex[iperf];
890 kernelComponent.initialize( iperf, stack );
891 kernelComponent.computePotentialandDeriv( iperf, er, esr, ei, iwelem, stack );
892 kernelComponent.computeFlux( iperf, er, esr, ei, iwelem, stack );
944 template<
typename POLICY >
948 string const flowSolverName,
951 MultiFluidBase
const & fluid,
953 bool const isInjector,
954 bool const isCrossflowEnabled )
956 geos::internal::kernelLaunchSelectorCompPhaseSwitch( numComp, numPhases, [&](
auto NC,
auto NP )
958 integer constexpr NUM_COMP = NC();
959 integer constexpr NUM_PHASE = NP();
960 integer constexpr IS_THERMAL = 1;
963 typename kernelType::CompFlowAccessors compFlowAccessors( elemManager, flowSolverName );
964 typename kernelType::MultiFluidAccessors multiFluidAccessors( elemManager, flowSolverName );
965 typename kernelType::RelPermAccessors relPermAccessors( elemManager, flowSolverName );
966 typename kernelType::ThermalCompFlowAccessors thermalCompFlowAccessors( elemManager, flowSolverName );
967 typename kernelType::ThermalMultiFluidAccessors thermalMultiFluidAccessors( elemManager, flowSolverName );
969 kernelType kernel( perforationData, subRegion, fluid, compFlowAccessors, multiFluidAccessors,
970 relPermAccessors, thermalCompFlowAccessors, thermalMultiFluidAccessors,
971 isInjector, isCrossflowEnabled );
972 kernelType::template launch< POLICY >( perforationData->
size(), kernel );
#define GEOS_HOST_DEVICE
Marks a host-device function.
#define GEOS_UNUSED_VAR(...)
Mark an unused variable and silence compiler warnings.
#define GEOS_MARK_FUNCTION
Mark function with both Caliper and NVTX if enabled.
The ElementRegionManager class provides an interface to ObjectManagerBase in order to manage ElementR...
typename ElementViewAccessor< VIEWTYPE >::NestedViewTypeConst ElementViewConst
The ElementViewAccessor at the ElementRegionManager level is the type resulting from ElementViewAcces...
A struct to automatically construct and store element view accessors.
A struct to automatically construct and store element view accessors.
localIndex size() const
Get the "size" of the group, which determines the number of elements in resizable wrappers.
static void createAndLaunch(integer const numComp, integer const numPhases, string const flowSolverName, PerforationData *const perforationData, ElementSubRegionBase const &subRegion, ElementRegionManager const &elemManager, bool const isInjector, bool const isCrossflowEnabled)
Create a new kernel and launch.
static constexpr integer numComp
Compile time value for the number of components.
static constexpr integer numPhase
Compile time value for the number of phases.
static constexpr integer isThermal
Compile time value for thermal option.
static void launch(localIndex const numElements, KERNEL_TYPE const &kernelComponent)
Performs the kernel launch.
ElementRegionManager::ElementViewConst< VIEWTYPE > ElementViewConst
The type for element-based non-constitutive data parameters. Consists entirely of ArrayView's.
static void createAndLaunch(integer const numComp, integer const numPhases, string const flowSolverName, PerforationData *const perforationData, ElementSubRegionBase &subRegion, MultiFluidBase const &fluid, ElementRegionManager const &elemManager, bool const isInjector, bool const isCrossflowEnabled)
Create a new kernel and launch.
arrayView1d< real64 > const m_energyPerfFlux
Views on energy flux.
arrayView2d< real64 const, compflow::USD_PHASE > const m_wellElemPhaseVolFrac
Views on well element properties.
ElementRegionManager::ElementViewConst< VIEWTYPE > ElementViewConst
The type for element-based non-constitutive data parameters. Consists entirely of ArrayView's.
ElementViewConst< arrayView3d< real64 const, multifluid::USD_PHASE > > const m_resPhaseFraction
Views on phase enthalpies.
ElementViewConst< arrayView1d< real64 const > > const m_temp
Views on temperature.
static void launch(localIndex const numElements, KERNEL_TYPE const &kernelComponent)
Performs the kernel launch.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
ArraySlice< T, 2, USD > arraySlice2d
Alias for 2D array slice.
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.
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 variables (dof numbers, jacobian and residual) located on the stack.
Kernel variables ) located on the stack.