19 #ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_WELLS_THERMALCOMPOSITIONALMULTIPHASEWELLKERNELS_HPP
20 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_WELLS_THERMALCOMPOSITIONALMULTIPHASEWELLKERNELS_HPP
28 namespace thermalCompositionalMultiphaseWellKernels
31 using namespace constitutive;
41 template<
integer NUM_COMP,
integer NUM_PHASE >
46 using Base::m_dCompFrac_dCompDens;
47 using Base::m_dPhaseMassDens;
48 using Base::m_dPhaseVolFrac;
49 using Base::m_dTotalMassDens;
50 using Base::m_phaseMassDens;
51 using Base::m_phaseVolFrac;
52 using Base::m_totalMassDens;
62 MultiFluidBase
const & fluid )
63 :
Base( subRegion, fluid )
74 using Deriv = multifluid::DerivativeOffset;
76 arraySlice1d<
real64 const, compflow::USD_PHASE - 1 > phaseVolFrac = m_phaseVolFrac[ei];
77 arraySlice2d<
real64 const, compflow::USD_PHASE_DC - 1 > dPhaseVolFrac = m_dPhaseVolFrac[ei];
78 arraySlice1d<
real64 const, multifluid::USD_PHASE - 2 > phaseMassDens = m_phaseMassDens[ei][0];
79 arraySlice2d<
real64 const, multifluid::USD_PHASE_DC - 2 > dPhaseMassDens = m_dPhaseMassDens[ei][0];
81 real64 & dTotalMassDens_dT = m_dTotalMassDens[ei][Deriv::dT];
84 return Base::compute( ei, [&](
localIndex const ip )
86 dTotalMassDens_dT += dPhaseVolFrac[ip][Deriv::dT] * phaseMassDens[ip] + phaseVolFrac[ip] * dPhaseMassDens[ip][Deriv::dT];
109 template<
typename POLICY >
114 MultiFluidBase
const & fluid )
118 isothermalCompositionalMultiphaseBaseKernels::internal::kernelLaunchSelectorCompSwitch( numComp, [&](
auto NC )
120 integer constexpr NUM_COMP = NC();
125 else if( numPhase == 3 )
127 isothermalCompositionalMultiphaseBaseKernels::internal::kernelLaunchSelectorCompSwitch( numComp, [&](
auto NC )
129 integer constexpr NUM_COMP = NC();
142 template< localIndex NUM_COMP >
154 using Base::m_minNormalizer;
155 using Base::m_rankOffset;
156 using Base::m_localResidual;
157 using Base::m_dofNumber;
163 integer const targetPhaseIndex,
165 MultiFluidBase
const & fluid,
167 real64 const timeAtEndOfStep,
169 real64 const minNormalizer )
175 m_numPhases( fluid.numFluidPhases()),
176 m_targetPhaseIndex( targetPhaseIndex ),
178 m_isLocallyOwned( subRegion.isLocallyOwned() ),
179 m_iwelemControl( subRegion.getTopWellElementIndex() ),
180 m_isProducer( wellControls.isProducer() ),
181 m_currentControl( wellControls.getControl() ),
182 m_targetBHP( wellControls.getTargetBHP( timeAtEndOfStep ) ),
183 m_targetTotalRate( wellControls.getTargetTotalRate( timeAtEndOfStep ) ),
184 m_targetPhaseRate( wellControls.getTargetPhaseRate( timeAtEndOfStep ) ),
185 m_targetMassRate( wellControls.getTargetMassRate( timeAtEndOfStep ) ),
186 m_volume( subRegion.getElementVolume() ),
187 m_phaseDens_n( fluid.phaseDensity_n() ),
188 m_totalDens_n( fluid.totalDensity_n() ),
189 m_phaseVolFraction_n( subRegion.getField< fields::well::phaseVolumeFraction_n >()),
190 m_phaseInternalEnergy_n( fluid.phaseInternalEnergy_n() )
195 void computeMassEnergyNormalizers(
localIndex const iwelem,
197 real64 & energyNormalizer )
const
199 massNormalizer = LvArray::math::max( m_minNormalizer, m_totalDens_n[iwelem][0] * m_volume[iwelem] );
201 for(
integer ip = 0; ip < m_numPhases; ++ip )
203 energyNormalizer += m_phaseInternalEnergy_n[iwelem][0][ip] * m_phaseDens_n[iwelem][0][ip] * m_phaseVolFraction_n[iwelem][ip] * m_volume[iwelem];
206 energyNormalizer = LvArray::math::max( m_minNormalizer, LvArray::math::abs( energyNormalizer ) );
211 LinfStackVariables & stack )
const override
214 for(
integer idof = 0; idof < WJ_ROFFSET::nEqn; ++idof )
220 if( idof == WJ_ROFFSET::CONTROL )
224 if( m_isLocallyOwned && iwelem == m_iwelemControl )
229 normalizer = m_targetBHP;
234 normalizer = LvArray::math::max( LvArray::math::abs( m_targetTotalRate ), m_minNormalizer );
239 normalizer = LvArray::math::max( LvArray::math::abs( m_targetPhaseRate ), m_minNormalizer );
244 normalizer = LvArray::math::max( LvArray::math::abs( m_targetMassRate ), m_minNormalizer );
250 normalizer = m_targetBHP;
254 else if( idof >= WJ_ROFFSET::MASSBAL && idof < WJ_ROFFSET::MASSBAL + numComp )
259 normalizer = m_dt * LvArray::math::abs( m_targetPhaseRate ) * m_phaseDens_n[iwelem][0][m_targetPhaseIndex];
265 normalizer = m_dt * LvArray::math::abs( m_targetMassRate );
270 normalizer = m_dt * LvArray::math::abs( m_targetTotalRate ) * m_totalDens_n[iwelem][0];
276 normalizer = LvArray::math::max( normalizer, m_volume[iwelem] * m_totalDens_n[iwelem][0] );
279 else if( idof == WJ_ROFFSET::VOLBAL )
284 normalizer = m_dt * LvArray::math::abs( m_targetPhaseRate );
290 normalizer = m_dt * LvArray::math::abs( m_targetMassRate/ m_totalDens_n[iwelem][0] );
294 normalizer = m_dt * LvArray::math::abs( m_targetTotalRate );
299 normalizer = LvArray::math::max( normalizer, m_volume[iwelem] );
302 if( idof == WJ_ROFFSET::ENERGYBAL )
304 real64 massNormalizer = 0.0, energyNormalizer = 0.0;
305 computeMassEnergyNormalizers( iwelem, massNormalizer, energyNormalizer );
306 real64 const valEnergy = LvArray::math::abs( m_localResidual[stack.localRow + WJ_ROFFSET::ENERGYBAL] ) / energyNormalizer;
307 if( valEnergy > stack.localValue[1] )
309 stack.localValue[1] = valEnergy;
315 normalizer = LvArray::math::max( m_minNormalizer, normalizer );
317 real64 const val = LvArray::math::abs( m_localResidual[stack.localRow + idof] ) / normalizer;
318 if( val > stack.localValue[0] )
320 stack.localValue[0] = val;
328 L2StackVariables & stack )
const override
331 GEOS_ERROR(
"The L2 norm is not implemented for CompositionalMultiphaseWell" );
358 real64 const m_targetTotalRate;
359 real64 const m_targetPhaseRate;
360 real64 const m_targetMassRate;
396 template<
typename POLICY >
399 integer const targetPhaseIndex,
401 string const & dofKey,
404 MultiFluidBase
const & fluid,
406 real64 const timeAtEndOfStep,
408 real64 const minNormalizer,
409 real64 (& residualNorm)[2] )
411 isothermalCompositionalMultiphaseBaseKernels::internal::kernelLaunchSelectorCompSwitch ( numComp, [&](
auto NC )
414 integer constexpr NUM_COMP = NC();
419 kernelType kernel( rankOffset, localResidual, dofNumber, ghostRank,
420 targetPhaseIndex, subRegion, fluid, wellControls, timeAtEndOfStep, dt, minNormalizer );
421 kernelType::template launchLinf< POLICY >( subRegion.
size(), kernel, residualNorm );
435 template< localIndex NUM_COMP >
440 using Base::m_dCompFrac_dCompDens;
441 using Base::m_dofNumber;
442 using Base::m_dPhaseCompFrac;
443 using Base::m_dPhaseDens;
444 using Base::m_dPhaseVolFrac;
445 using Base::m_dPoro_dPres;
446 using Base::m_elemGhostRank;
447 using Base::m_localMatrix;
448 using Base::m_localRhs;
449 using Base::m_numPhases;
450 using Base::m_phaseCompFrac;
451 using Base::m_phaseCompFrac_n;
452 using Base::m_phaseDens;
453 using Base::m_phaseDens_n;
454 using Base::m_phaseVolFrac;
455 using Base::m_phaseVolFrac_n;
456 using Base::m_porosity;
457 using Base::m_porosity_n;
458 using Base::m_rankOffset;
459 using Base::m_volume;
464 using FLUID_PROP_COFFSET = multifluid::DerivativeOffsetC< NUM_COMP, 1 >;
482 MultiFluidBase
const & fluid,
485 BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags >
const kernelFlags )
486 :
Base( numPhases, isProducer, rankOffset, dofKey, subRegion, fluid, localMatrix, localRhs, kernelFlags ),
487 m_phaseInternalEnergy_n( fluid.phaseInternalEnergy_n()),
488 m_phaseInternalEnergy( fluid.phaseInternalEnergy()),
489 m_dPhaseInternalEnergy( fluid.dPhaseInternalEnergy())
497 : Base::StackVariables()
499 using Base::StackVariables::eqnRowIndices;
500 using Base::StackVariables::dofColIndices;
501 using Base::StackVariables::localJacobian;
502 using Base::StackVariables::localResidual;
503 using Base::StackVariables::localRow;
504 using Base::StackVariables::volume;
518 Base::setup( ei, stack );
534 using Deriv = multifluid::DerivativeOffset;
536 Base::computeAccumulation( ei, stack, [&](
integer const ip
537 ,
real64 const & phaseAmount
538 ,
real64 const & phaseAmount_n
539 ,
real64 const (&dPhaseAmount)[FLUID_PROP_COFFSET::nDer] )
546 real64 dPhaseInternalEnergy_dC[numComp]{};
549 arraySlice2d<
real64 const, compflow::USD_COMP_DC - 1 > dCompFrac_dCompDens = m_dCompFrac_dCompDens[ei];
550 arraySlice1d<
real64 const, multifluid::USD_PHASE - 2 > phaseInternalEnergy_n = m_phaseInternalEnergy_n[ei][0];
551 arraySlice1d<
real64 const, multifluid::USD_PHASE - 2 > phaseInternalEnergy = m_phaseInternalEnergy[ei][0];
552 arraySlice2d<
real64 const, multifluid::USD_PHASE_DC - 2 > dPhaseInternalEnergy = m_dPhaseInternalEnergy[ei][0];
556 real64 const phaseEnergy = phaseAmount * phaseInternalEnergy[ip];
557 real64 const phaseEnergy_n = phaseAmount_n * phaseInternalEnergy_n[ip];
558 real64 const dPhaseEnergy_dP = dPhaseAmount[FLUID_PROP_COFFSET::dP] * phaseInternalEnergy[ip]
559 + phaseAmount * dPhaseInternalEnergy[ip][Deriv::dP];
560 real64 const dPhaseEnergy_dT = dPhaseAmount[FLUID_PROP_COFFSET::dT] * phaseInternalEnergy[ip]
561 + phaseAmount * dPhaseInternalEnergy[ip][Deriv::dT];
563 stack.localResidual[numEqn-1] += phaseEnergy - phaseEnergy_n;
566 stack.localJacobian[numEqn-1][0] += dPhaseEnergy_dP;
567 stack.localJacobian[numEqn-1][numDof-1] += dPhaseEnergy_dT;
570 applyChainRule( numComp, dCompFrac_dCompDens, dPhaseInternalEnergy[ip], dPhaseInternalEnergy_dC, Deriv::dC );
571 for(
integer jc = 0; jc < numComp; ++jc )
573 stack.localJacobian[numEqn-1][jc + 1] += phaseInternalEnergy[ip] * dPhaseAmount[FLUID_PROP_COFFSET::dC+jc]
574 + dPhaseInternalEnergy_dC[jc] * phaseAmount;
591 Base::computeVolumeBalance( ei, stack );
597 StackVariables & stack )
const
601 Base::complete( ei, stack );
634 template<
typename POLICY >
640 integer const useTotalMassEquation,
643 MultiFluidBase
const & fluid,
647 isothermalCompositionalMultiphaseBaseKernels::
648 internal::kernelLaunchSelectorCompSwitch( numComps, [&](
auto NC )
653 BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > kernelFlags;
654 if( useTotalMassEquation )
655 kernelFlags.set( isothermalCompositionalMultiphaseBaseKernels::KernelFlags::TotalMassEquation );
658 kernel( numPhases, isProducer, rankOffset, dofKey, subRegion, fluid, localMatrix, localRhs, kernelFlags );
660 launch< POLICY, ElementBasedAssemblyKernel< NUM_COMP > >( subRegion.
size(), kernel );
669 template<
integer NC >
673 static constexpr
integer IS_THERMAL = 1;
680 using CP_Deriv = multifluid::DerivativeOffsetC< NC, IS_THERMAL >;
685 using Base::m_isProducer;
687 using Base::m_localRhs;
688 using Base::m_localMatrix;
689 using Base::m_rankOffset;
690 using Base::maxNumElems;
691 using Base::maxStencilSize;
692 using Base::m_useTotalMassEquation;
698 static constexpr
integer numDof = WJ_COFFSET::nDer;
701 static constexpr
integer numEqn = WJ_ROFFSET::nEqn - 2;
719 string const wellDofKey,
722 MultiFluidBase
const & fluid,
725 BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > kernelFlags )
734 m_numPhases ( fluid.numFluidPhases()),
735 m_globalWellElementIndex( subRegion.getGlobalWellElementIndex() ),
736 m_phaseFraction( fluid.phaseFraction()),
737 m_dPhaseFraction( fluid.dPhaseFraction()),
738 m_phaseEnthalpy( fluid.phaseEnthalpy()),
739 m_dPhaseEnthalpy( fluid.dPhaseEnthalpy())
763 Base::setup ( iwelem, stack );
771 for(
integer j=0; j< stack.stencilSize * numDof; j++ )
778 void complete(
localIndex const iwelem, StackVariables & stack )
const
780 Base::complete ( iwelem, stack );
782 using namespace compositionalMultiphaseUtilities;
783 if( stack.numConnectedElems ==1 )
786 globalIndex oneSidedEqnRowIndices = stack.offsetUp + WJ_ROFFSET::ENERGYBAL - m_rankOffset;
788 if( oneSidedEqnRowIndices >= 0 && oneSidedEqnRowIndices < m_localMatrix.numRows() )
791 if( !m_isProducer && m_globalWellElementIndex[iwelem] == 0 )
796 for(
integer i=0; i< CP_Deriv::nDer; i++ )
798 stack.localEnergyFluxJacobian[0][i] = 0.0;
800 stack.localEnergyFluxJacobian_dQ[0][0]=0;
801 stack.localEnergyFlux[0]=0;
806 globalIndex oneSidedDofColIndices_dRate = stack.offsetCurrent + WJ_COFFSET::dQ;
807 globalIndex oneSidedDofColIndices_dPresCompTempUp[CP_Deriv::nDer]{};
810 oneSidedDofColIndices_dPresCompTempUp[ioff++] = stack.offsetUp + WJ_COFFSET::dP;
811 oneSidedDofColIndices_dPresCompTempUp[ioff++] = stack.offsetUp + WJ_COFFSET::dT;
812 for(
integer jdof = 0; jdof < NC; ++jdof )
814 oneSidedDofColIndices_dPresCompTempUp[ioff++] = stack.offsetUp + WJ_COFFSET::dC+ jdof;
817 m_localMatrix.template addToRow< parallelDeviceAtomic >( oneSidedEqnRowIndices,
818 &oneSidedDofColIndices_dRate,
819 stack.localEnergyFluxJacobian_dQ[0],
821 m_localMatrix.template addToRowBinarySearchUnsorted< parallelDeviceAtomic >( oneSidedEqnRowIndices,
822 oneSidedDofColIndices_dPresCompTempUp,
823 stack.localEnergyFluxJacobian[0],
825 RAJA::atomicAdd( parallelDeviceAtomic{}, &m_localRhs[oneSidedEqnRowIndices], stack.localEnergyFlux[0] );
830 globalIndex row_current = stack.offsetCurrent + WJ_ROFFSET::ENERGYBAL - m_rankOffset;
831 globalIndex row_next = stack.offsetNext + WJ_ROFFSET::ENERGYBAL - m_rankOffset;
835 if( row_next >= 0 && row_next < m_localMatrix.numRows() )
837 if( m_globalWellElementIndex[stack.iwelemNext] == 0 )
839 for(
integer i=0; i<CP_Deriv::nDer; i++ )
840 stack.localEnergyFluxJacobian[TAG::NEXT][i] = 0.0;
841 stack.localEnergyFluxJacobian_dQ[TAG::NEXT][0] =0;
842 stack.localEnergyFlux[TAG::NEXT] =0;
852 eqnRowIndices[TAG::CURRENT ] = row_current;
853 eqnRowIndices[TAG::NEXT ] = row_next;
858 globalIndex dofColIndices_dRate = stack.offsetCurrent + WJ_COFFSET::dQ;
863 dofColIndices[ioff++] = stack.offsetUp + WJ_COFFSET::dP;
865 if constexpr ( IS_THERMAL )
867 dofColIndices[ioff++] = stack.offsetUp + WJ_COFFSET::dT;
869 for(
integer jdof = 0; jdof < NC; ++jdof )
871 dofColIndices[ioff++] = stack.offsetUp + WJ_COFFSET::dC+ jdof;
874 for(
integer i = 0; i < 2; ++i )
876 if( eqnRowIndices[i] >= 0 && eqnRowIndices[i] < m_localMatrix.numRows() )
878 m_localMatrix.template addToRow< parallelDeviceAtomic >( eqnRowIndices[i],
879 &dofColIndices_dRate,
880 stack.localEnergyFluxJacobian_dQ[i],
882 m_localMatrix.template addToRowBinarySearchUnsorted< parallelDeviceAtomic >( eqnRowIndices[i],
884 stack.localEnergyFluxJacobian[i],
886 RAJA::atomicAdd( parallelDeviceAtomic{}, &m_localRhs[eqnRowIndices[i]], stack.localEnergyFlux[i] );
905 Base::computeFlux ( iwelem, stack, [&] (
localIndex const & iwelemNext
907 ,
real64 const & currentConnRate
908 ,
real64 const (&dCompFrac_dCompDens)[NC][NC] )
911 if( iwelemNext < 0 && !m_isProducer )
915 for(
integer ip = 0; ip < m_numPhases; ++ip )
917 eflux += m_phaseEnthalpy[iwelemUp][0][ip]* m_phaseFraction[iwelemUp][0][ip];
918 eflux_dq += m_phaseEnthalpy[iwelemUp][0][ip] * m_phaseFraction[iwelemUp][0][ip];
920 stack.
localEnergyFluxJacobian[0] [CP_Deriv::dP] += m_phaseEnthalpy[iwelemUp][0][ip]*m_dPhaseFraction[iwelemUp][0][ip][CP_Deriv::dP]
921 + m_dPhaseEnthalpy[iwelemUp][0][ip][CP_Deriv::dP]*m_phaseFraction[iwelemUp][0][ip];
922 stack.
localEnergyFluxJacobian[0] [CP_Deriv::dT] += m_phaseEnthalpy[iwelemUp][0][ip]*m_dPhaseFraction[iwelemUp][0][ip][CP_Deriv::dT]
923 + m_dPhaseEnthalpy[iwelemUp][0][ip][CP_Deriv::dT]*m_phaseFraction[iwelemUp][0][ip];
925 real64 dProp1_dC[numComp]{};
926 applyChainRule( numComp, dCompFrac_dCompDens, m_dPhaseEnthalpy[iwelemUp][0][ip], dProp1_dC, CP_Deriv::dC );
927 real64 dProp2_dC[numComp]{};
928 applyChainRule( numComp, dCompFrac_dCompDens, m_dPhaseFraction[iwelemUp][0][ip], dProp2_dC, CP_Deriv::dC );
929 for(
integer dof=0; dof < numComp; dof++ )
932 + dProp1_dC[dof]*m_phaseFraction[iwelemUp][0][ip];
935 for(
integer dof=0; dof < CP_Deriv::nDer; dof++ )
943 else if( ( iwelemNext < 0 && m_isProducer ) || currentConnRate < 0 )
947 for(
integer ip = 0; ip < m_numPhases; ++ip )
949 eflux += m_phaseEnthalpy[iwelemUp][0][ip]* m_phaseFraction[iwelemUp][0][ip];
950 eflux_dq += m_phaseEnthalpy[iwelemUp][0][ip] * m_phaseFraction[iwelemUp][0][ip];
951 stack.
localEnergyFluxJacobian[0] [CP_Deriv::dP] += m_phaseEnthalpy[iwelemUp][0][ip]*m_dPhaseFraction[iwelemUp][0][ip][CP_Deriv::dP]
952 + m_dPhaseEnthalpy[iwelemUp][0][ip][CP_Deriv::dP]*m_phaseFraction[iwelemUp][0][ip];
953 stack.
localEnergyFluxJacobian[0] [CP_Deriv::dT] += m_phaseEnthalpy[iwelemUp][0][ip]*m_dPhaseFraction[iwelemUp][0][ip][CP_Deriv::dT]
954 + m_dPhaseEnthalpy[iwelemUp][0][ip][CP_Deriv::dT]*m_phaseFraction[iwelemUp][0][ip];
956 real64 dProp1_dC[numComp]{};
957 applyChainRule( numComp, dCompFrac_dCompDens, m_dPhaseEnthalpy[iwelemUp][0][ip], dProp1_dC, CP_Deriv::dC );
958 real64 dProp2_dC[numComp]{};
959 applyChainRule( numComp, dCompFrac_dCompDens, m_dPhaseFraction[iwelemUp][0][ip], dProp2_dC, CP_Deriv::dC );
960 for(
integer dof=0; dof < numComp; dof++ )
963 + dProp1_dC[dof]*m_phaseFraction[iwelemUp][0][ip];
968 for(
integer dof=0; dof < CP_Deriv::nDer; dof++ )
979 for(
integer ip = 0; ip < m_numPhases; ++ip )
981 eflux += m_phaseEnthalpy[iwelemUp][0][ip]* m_phaseFraction[iwelemUp][0][ip];
982 eflux_dq += m_phaseEnthalpy[iwelemUp][0][ip] * m_phaseFraction[iwelemUp][0][ip];
984 real64 dprop_dp = m_phaseEnthalpy[iwelemUp][0][ip]*m_dPhaseFraction[iwelemUp][0][ip][CP_Deriv::dP]
985 + m_dPhaseEnthalpy[iwelemUp][0][ip][CP_Deriv::dP]*m_phaseFraction[iwelemUp][0][ip];
986 real64 dprop_dt = m_phaseEnthalpy[iwelemUp][0][ip]*m_dPhaseFraction[iwelemUp][0][ip][CP_Deriv::dT]
987 + m_dPhaseEnthalpy[iwelemUp][0][ip][CP_Deriv::dT]*m_phaseFraction[iwelemUp][0][ip];
996 applyChainRule( numComp, dCompFrac_dCompDens, m_dPhaseEnthalpy[iwelemUp][0][ip], dPE_dC, CP_Deriv::dC );
998 applyChainRule( numComp, dCompFrac_dCompDens, m_dPhaseFraction[iwelemUp][0][ip], dPF_dC, CP_Deriv::dC );
1000 for(
integer dof=0; dof < numComp; dof++ )
1003 +dPE_dC[dof]*m_phaseFraction[iwelemUp][0][ip];
1004 stack.
localEnergyFluxJacobian[TAG::CURRENT ][CP_Deriv::dC+dof] += m_phaseEnthalpy[iwelemUp][0][ip]*dPF_dC[dof]
1005 +dPE_dC[dof]*m_phaseFraction[iwelemUp][0][ip];
1009 stack.
localEnergyFlux[TAG::CURRENT ] = -m_dt * eflux * currentConnRate;
1012 for(
integer dof=0; dof < CP_Deriv::nDer; dof++ )
1032 template<
typename POLICY,
typename KERNEL_TYPE >
1035 KERNEL_TYPE
const & kernelComponent )
1040 typename KERNEL_TYPE::StackVariables stack( 1 );
1042 kernelComponent.setup( ie, stack );
1043 kernelComponent.computeFlux( ie, stack );
1044 kernelComponent.complete( ie, stack );
1086 template<
typename POLICY >
1091 integer const useTotalMassEquation,
1092 string const dofKey,
1095 MultiFluidBase
const & fluid,
1099 isothermalCompositionalMultiphaseBaseKernels::internal::kernelLaunchSelectorCompSwitch( numComps, [&](
auto NC )
1101 integer constexpr NUM_COMP = NC();
1104 BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > kernelFlags;
1105 if( useTotalMassEquation )
1106 kernelFlags.set( isothermalCompositionalMultiphaseBaseKernels::KernelFlags::TotalMassEquation );
1112 kernelType kernel( dt, rankOffset, dofKey, wellControls, subRegion, fluid, localMatrix, localRhs, kernelFlags );
1113 kernelType::template launch< POLICY >( subRegion.
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_ERROR(msg)
Raise a hard error and terminate the program.
#define GEOS_MARK_FUNCTION
Mark function with both Caliper and NVTX if enabled.
The ObjectManagerBase is the base object of all object managers in the mesh data hierachy.
array1d< integer > const & ghostRank()
Get the ghost information of each object.
This class describes the controls used to operate a well.
This class describes a collection of local well elements and perforations.
Define the interface for the assembly kernel in charge of accumulation and volume balance.
Define the interface for the assembly kernel in charge of flux terms.
Define the interface for the property kernel in charge of computing the total mass density.
GEOS_DECLTYPE_AUTO_RETURN getReference(LOOKUP_TYPE const &lookup) const
Look up a wrapper and get reference to wrapped object.
localIndex size() const
Get the "size" of the group, which determines the number of elements in resizable wrappers.
Define the base interface for the property update kernels.
Define the base interface for the residual calculations.
static void createAndLaunch(localIndex const numComps, localIndex const numPhases, integer const isProducer, globalIndex const rankOffset, integer const useTotalMassEquation, string const dofKey, WellElementSubRegion const &subRegion, MultiFluidBase const &fluid, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs)
Create a new kernel and launch.
Define the interface for the assembly kernel in charge of thermal accumulation and volume balance.
arrayView2d< real64 const > const m_dPoro_dTemp
View on derivative of porosity w.r.t temperature.
GEOS_HOST_DEVICE void computeVolumeBalance(localIndex const ei, StackVariables &stack) const
Compute the local volume balance contributions to the residual and Jacobian.
arrayView3d< real64 const, multifluid::USD_PHASE > m_phaseInternalEnergy_n
Views on phase internal energy.
GEOS_HOST_DEVICE void computeAccumulation(localIndex const ei, StackVariables &stack) const
Compute the local accumulation contributions to the residual and Jacobian.
ElementBasedAssemblyKernel(localIndex const numPhases, integer const isProducer, globalIndex const rankOffset, string const dofKey, WellElementSubRegion const &subRegion, MultiFluidBase const &fluid, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs, BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > const kernelFlags)
Constructor.
GEOS_HOST_DEVICE void setup(localIndex const ei, StackVariables &stack) const
Performs the setup phase for the kernel.
static void createAndLaunch(integer const numComps, real64 const dt, globalIndex const rankOffset, integer const useTotalMassEquation, string const dofKey, WellControls const &wellControls, WellElementSubRegion const &subRegion, MultiFluidBase const &fluid, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs)
Create a new kernel and launch.
Define the interface for the assembly kernel in charge of flux terms.
integer const m_numPhases
Number of phases.
FaceBasedAssemblyKernel(real64 const dt, globalIndex const rankOffset, string const wellDofKey, WellControls const &wellControls, WellElementSubRegion const &subRegion, MultiFluidBase const &fluid, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs, BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > kernelFlags)
Constructor for the kernel interface.
arrayView3d< real64 const, multifluid::USD_PHASE > m_phaseEnthalpy
Views on phase enthalpy.
GEOS_HOST_DEVICE void computeFlux(localIndex const iwelem, StackVariables &stack) const
Compute the local flux contributions to the residual and Jacobian.
arrayView1d< globalIndex const > m_globalWellElementIndex
Global index of local element.
arrayView3d< real64 const, multifluid::USD_PHASE > const m_phaseFraction
Element phase fraction.
static void launch(localIndex const numElements, KERNEL_TYPE const &kernelComponent)
Performs the kernel launch.
static void createAndLaunch(integer const numComp, integer const targetPhaseIndex, globalIndex const rankOffset, string const &dofKey, arrayView1d< real64 const > const &localResidual, WellElementSubRegion const &subRegion, MultiFluidBase const &fluid, WellControls const &wellControls, real64 const timeAtEndOfStep, real64 const dt, real64 const minNormalizer, real64(&residualNorm)[2])
Create a new kernel and launch.
integer const m_numPhases
Number of fluid phases.
WellControls::Control const m_currentControl
Controls.
real64 const m_dt
Time step size.
arrayView3d< real64 const, multifluid::USD_PHASE > const m_phaseDens_n
View on phase/total density at the previous converged time step.
localIndex const m_iwelemControl
Index of the element where the control is enforced.
virtual GEOS_HOST_DEVICE void computeLinf(localIndex const iwelem, LinfStackVariables &stack) const override
Compute the local values for the Linf norm.
arrayView1d< real64 const > const m_volume
View on the volume.
virtual GEOS_HOST_DEVICE void computeL2(localIndex const iwelem, L2StackVariables &stack) const override
Compute the local values and normalizer for the L2 norm.
bool const m_isProducer
Flag indicating whether the well is a producer or an injector.
bool const m_isLocallyOwned
Flag indicating whether the well is locally owned or not.
integer const m_targetPhaseIndex
Index of the target phase.
static void createAndLaunch(integer const numComp, integer const numPhase, ObjectManagerBase &subRegion, MultiFluidBase const &fluid)
Create a new kernel and launch.
Define the interface for the property kernel in charge of computing the total mass density.
GEOS_HOST_DEVICE void compute(localIndex const ei) const
Compute the total mass density in an element.
TotalMassDensityKernel(ObjectManagerBase &subRegion, MultiFluidBase const &fluid)
Constructor.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
StackArray< T, 2, MAXSIZE > stackArray2d
Alias for 2D stack array.
LvArray::CRSMatrixView< T, COL_INDEX, localIndex const, LvArray::ChaiBuffer > CRSMatrixView
Alias for CRS Matrix View.
GEOS_GLOBALINDEX_TYPE globalIndex
Global index type (for indexing objects across MPI partitions).
StackArray< T, 1, MAXSIZE > stackArray1d
Alias for 1D stack array.
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.
std::int32_t integer
Signed integer type.
ArrayView< T, 4, USD > arrayView4d
Alias for 4D array view.
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.
Array< T, 1 > array1d
Alias for 1D array.
ArrayView< T, 3, USD > arrayView3d
Alias for 3D array view.
localIndex numConnectedElems
Number of elements connected at a given connection.
stackArray1d< real64, maxNumElems > localEnergyFlux
Storage for the face local residual vector (energy equation)
stackArray2d< real64, maxNumElems *maxStencilSize > localEnergyFluxJacobian_dQ
Storage for the face local Jacobian matrix dQ only.
stackArray2d< real64, maxNumElems *maxStencilSize *CP_Deriv::nDer > localEnergyFluxJacobian
Storage for the face local energy Jacobian matrix dC dP dT.