20 #ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_WELLS_COMPOSITIONALMULTIPHASEWELLKERNELS_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_WELLS_COMPOSITIONALMULTIPHASEWELLKERNELS_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"
40 #include "physicsSolvers/fluidFlow/wells/WellControls.hpp"
47 namespace compositionalMultiphaseWellKernels
50 static constexpr
real64 minDensForDivision = 1e-10;
55 static constexpr
integer RES = 0;
56 static constexpr
integer WELL = 1;
62 static constexpr
integer CURRENT = 0;
63 static constexpr
integer NEXT = 1;
69 static constexpr
integer DPRES = 0;
70 static constexpr
integer DCOMP = 1;
73 template<
integer NC,
integer IS_THERMAL >
76 template<
integer NC >
79 static constexpr
integer dP = 0;
80 static constexpr
integer dC = 1;
81 static constexpr
integer dQ = dC + NC;
82 static integer constexpr nDer = dQ + 1;
86 template<
integer NC >
89 static constexpr
integer dP = 0;
90 static constexpr
integer dC = 1;
91 static constexpr
integer dQ = dC + NC;
92 static constexpr
integer dT = dQ+1;
100 static constexpr
integer CONTROL = 0;
101 static constexpr
integer MASSBAL = 1;
104 template<
integer NC,
integer IS_THERMAL >
107 template<
integer NC >
110 static constexpr
integer CONTROL = 0;
111 static constexpr
integer MASSBAL = 1;
112 static constexpr
integer VOLBAL = MASSBAL + NC;
113 static constexpr
integer nEqn = VOLBAL+1;
116 template<
integer NC >
119 static constexpr
integer CONTROL = 0;
120 static constexpr
integer MASSBAL = 1;
121 static constexpr
integer VOLBAL = MASSBAL + NC;
122 static constexpr
integer ENERGYBAL = VOLBAL+1;
123 static constexpr
integer nEqn = ENERGYBAL+1;
136 switchControl(
bool const isProducer,
141 real64 const & targetPhaseRate,
142 real64 const & targetTotalRate,
143 real64 const & targetMassRate,
144 real64 const & currentBHP,
146 real64 const & currentTotalVolRate,
147 real64 const & currentMassRate,
150 template<
integer NC,
integer IS_THERMAL >
156 integer const targetPhaseIndex,
158 real64 const & targetPhaseRate,
159 real64 const & targetTotalRate,
160 real64 const & targetMassRate,
161 real64 const & currentBHP,
165 real64 const & currentTotalVolRate,
167 real64 const & massDensity,
178 using Deriv = constitutive::multifluid::DerivativeOffset;
183 template<
integer NC,
integer IS_THERMAL >
187 compute(
real64 const & gravCoef,
188 real64 const & gravCoefNext,
191 real64 const & totalMassDens,
192 real64 const & totalMassDensNext,
196 real64 ( &localPresRelJacobian )[2*(NC+1+IS_THERMAL)] );
198 template<
integer NC,
integer IS_THERMAL >
202 bool const isLocallyOwned,
204 integer const targetPhaseIndex,
206 real64 const & timeAtEndOfStep,
213 bool & controlHasSwitched,
227 template<
integer NC >
231 compute(
integer const numPhases,
236 real64 ( &localVolBalanceJacobian )[NC+1] );
238 template<
integer NC >
260 fields::flow::temperature,
261 fields::flow::globalCompDensity,
262 fields::flow::phaseVolumeFraction >;
266 fields::multifluid::phaseMassDensity >;
276 template<
typename VIEWTYPE >
286 real64 const & currentTime,
324 integer const targetPhaseIndex,
326 real64 const & currentTime,
342 template<
integer NUM_COMP,
integer NUM_PHASE >
359 constitutive::MultiFluidBase
const & fluid )
361 m_phaseVolFrac( subRegion.getField< fields::well::phaseVolumeFraction >() ),
362 m_dPhaseVolFrac( subRegion.getField< fields::well::dPhaseVolumeFraction >() ),
363 m_dCompFrac_dCompDens( subRegion.getField< fields::well::dGlobalCompFraction_dGlobalCompDensity >() ),
365 m_dPhaseMassDens( fluid.dPhaseMassDensity() ),
366 m_totalMassDens( subRegion.getField< fields::well::totalMassDensity >() ),
367 m_dTotalMassDens( subRegion.getField< fields::well::dTotalMassDensity >() )
376 template<
typename FUNC = NoOpFunc >
380 FUNC && totalMassDensityKernelOp = NoOpFunc{} )
const
382 using Deriv = constitutive::multifluid::DerivativeOffset;
385 arraySlice2d<
real64 const, compflow::USD_PHASE_DC - 1 > dPhaseVolFrac = m_dPhaseVolFrac[ei];
386 arraySlice2d<
real64 const, compflow::USD_COMP_DC - 1 > dCompFrac_dCompDens = m_dCompFrac_dCompDens[ei];
388 arraySlice2d<
real64 const, constitutive::multifluid::USD_PHASE_DC - 2 > dPhaseMassDens = m_dPhaseMassDens[ei][0];
390 arraySlice1d<
real64, compflow::USD_FLUID_DC - 1 > dTotalMassDens = m_dTotalMassDens[ei];
396 dTotalMassDens[Deriv::dP]=0.0;
399 dTotalMassDens[Deriv::dC+ic]=0.0;
404 totalMassDens += phaseVolFrac[ip] * phaseMassDens[ip];
405 dTotalMassDens[Deriv::dP] += dPhaseVolFrac[ip][Deriv::dP] * phaseMassDens[ip] + phaseVolFrac[ip] * dPhaseMassDens[ip][Deriv::dP];
407 applyChainRule(
numComp, dCompFrac_dCompDens, dPhaseMassDens[ip], dMassDens_dC, Deriv::dC );
410 dTotalMassDens[Deriv::dC+ic] += dPhaseVolFrac[ip][Deriv::dC+ic] * phaseMassDens[ip]
411 + phaseVolFrac[ip] * dMassDens_dC[ic];
414 totalMassDensityKernelOp( ip );
456 template<
typename POLICY >
461 constitutive::MultiFluidBase
const & fluid )
465 isothermalCompositionalMultiphaseBaseKernels::internal::kernelLaunchSelectorCompSwitch( numComp, [&] (
auto NC )
467 integer constexpr NUM_COMP = NC();
472 else if( numPhase == 3 )
474 isothermalCompositionalMultiphaseBaseKernels::internal::kernelLaunchSelectorCompSwitch( numComp, [&] (
auto NC )
476 integer constexpr NUM_COMP = NC();
506 integer const targetPhaseIndex,
508 constitutive::MultiFluidBase
const & fluid,
510 real64 const timeAtEndOfStep,
512 real64 const minNormalizer )
526 m_targetBHP( wellControls.
getTargetBHP( timeAtEndOfStep ) ),
532 m_totalDens_n( fluid.totalDensity_n() )
537 LinfStackVariables & stack )
const override
548 if( idof == ROFFSET::CONTROL )
557 normalizer = m_targetBHP;
562 normalizer = LvArray::math::max( LvArray::math::abs( m_targetTotalRate ),
m_minNormalizer );
567 normalizer = LvArray::math::max( LvArray::math::abs( m_targetPhaseRate ),
m_minNormalizer );
572 normalizer = LvArray::math::max( LvArray::math::abs( m_targetMassRate ),
m_minNormalizer );
578 normalizer = m_targetBHP;
582 else if( idof >= ROFFSET::MASSBAL && idof < ROFFSET::MASSBAL +
m_numComp )
593 normalizer =
m_dt * LvArray::math::abs( m_targetMassRate );
598 normalizer =
m_dt * LvArray::math::abs( m_targetTotalRate ) * m_totalDens_n[iwelem][0];
604 normalizer = LvArray::math::max( normalizer,
m_volume[iwelem] * m_totalDens_n[iwelem][0] );
607 else if( idof == ROFFSET::MASSBAL +
m_numComp )
612 normalizer =
m_dt * LvArray::math::abs( m_targetPhaseRate );
618 normalizer =
m_dt * LvArray::math::abs( m_targetMassRate/ m_totalDens_n[iwelem][0] );
622 normalizer =
m_dt * LvArray::math::abs( m_targetTotalRate );
630 normalizer = LvArray::math::max( normalizer,
m_volume[iwelem] );
634 if( val > stack.localValue[0] )
636 stack.localValue[0] = val;
643 L2StackVariables & stack )
const override
646 GEOS_ERROR(
"The L2 norm is not implemented for CompositionalMultiphaseWell" );
676 real64 const m_targetTotalRate;
677 real64 const m_targetPhaseRate;
678 real64 const m_targetMassRate;
712 template<
typename POLICY >
716 integer const targetPhaseIndex,
718 string const & dofKey,
721 constitutive::MultiFluidBase
const & fluid,
723 real64 const timeAtEndOfStep,
725 real64 const minNormalizer,
726 real64 (& residualNorm)[1] )
732 numComp, numDof, targetPhaseIndex, subRegion, fluid, wellControls, timeAtEndOfStep, dt, minNormalizer );
733 ResidualNormKernel::launchLinf< POLICY >( subRegion.
size(), kernel, residualNorm );
760 template<
typename POLICY >
763 real64 const maxAbsolutePresChange,
764 real64 const maxCompFracChange,
765 real64 const maxRelativeCompDensChange,
773 subRegion.
getField< fields::well::pressure >();
775 subRegion.
getField< fields::well::globalCompDensity >();
777 subRegion.
getField< fields::well::pressureScalingFactor >();
779 subRegion.
getField< fields::well::globalCompDensityScalingFactor >();
780 isothermalCompositionalMultiphaseBaseKernels::
781 SolutionScalingKernel kernel( maxRelativePresChange, maxAbsolutePresChange, maxCompFracChange, maxRelativeCompDensChange, rankOffset,
782 numComp, dofKey, subRegion, localSolution, pressure, compDens, pressureScalingFactor, compDensScalingFactor );
783 return isothermalCompositionalMultiphaseBaseKernels::
784 SolutionScalingKernel::
785 launch< POLICY >( subRegion.
size(), kernel );
810 template<
typename POLICY >
814 real64 const scalingFactor,
826 isothermalCompositionalMultiphaseBaseKernels::
827 SolutionCheckKernel kernel( allowCompDensChopping, 0, scalingType, scalingFactor,
828 pressure, compDens, pressureScalingFactor, compDensScalingFactor, rankOffset,
829 numComp, dofKey, subRegion, localSolution );
830 return isothermalCompositionalMultiphaseBaseKernels::
831 SolutionCheckKernel::
832 launch< POLICY >( subRegion.
size(), kernel );
845 template<
integer NUM_COMP,
integer IS_THERMAL >
854 using FLUID_PROP_COFFSET = constitutive::multifluid::DerivativeOffsetC< NUM_COMP, IS_THERMAL >;
883 constitutive::MultiFluidBase
const & fluid,
886 BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags >
const kernelFlags )
893 m_volume( subRegion.getElementVolume() ),
894 m_dCompFrac_dCompDens( subRegion.getField< fields::flow::dGlobalCompFraction_dGlobalCompDensity >() ),
895 m_phaseVolFrac_n( subRegion.getField< fields::flow::phaseVolumeFraction_n >() ),
896 m_phaseVolFrac( subRegion.getField< fields::flow::phaseVolumeFraction >() ),
897 m_dPhaseVolFrac( subRegion.getField< fields::flow::dPhaseVolumeFraction >() ),
899 m_phaseDens( fluid.phaseDensity() ),
900 m_dPhaseDens( fluid.dPhaseDensity() ),
902 m_phaseCompFrac( fluid.phaseCompFraction() ),
903 m_dPhaseCompFrac( fluid.dPhaseCompFraction() ),
904 m_compDens( subRegion.getField< fields::flow::globalCompDensity >() ),
905 m_compDens_n( subRegion.getField< fields::flow::globalCompDensity_n >() ),
908 m_kernelFlags( kernelFlags )
973 if constexpr ( IS_THERMAL )
978 stack.dofColIndices[0] =
m_dofNumber[ei] + WJ_COFFSET::dP;
981 stack.dofColIndices[ic+1] =
m_dofNumber[ei] + WJ_COFFSET::dC+ic;
983 if constexpr ( IS_THERMAL )
1007 template<
typename FUNC = NoOpFunc >
1011 FUNC && phaseAmountKernelOp = NoOpFunc{} )
const
1014 using Deriv = constitutive::multifluid::DerivativeOffset;
1020 arraySlice1d<
real64 const, compflow::USD_PHASE - 1 > phaseVolFrac = m_phaseVolFrac[ei];
1021 arraySlice2d<
real64 const, compflow::USD_PHASE_DC - 1 > dPhaseVolFrac = m_dPhaseVolFrac[ei];
1024 arraySlice1d<
real64 const, constitutive::multifluid::USD_PHASE - 2 > phaseDens = m_phaseDens[ei][0];
1025 arraySlice2d<
real64 const, constitutive::multifluid::USD_PHASE_DC - 2 > dPhaseDens = m_dPhaseDens[ei][0];
1028 arraySlice2d<
real64 const, constitutive::multifluid::USD_PHASE_COMP - 2 > phaseCompFrac = m_phaseCompFrac[ei][0];
1029 arraySlice3d<
real64 const, constitutive::multifluid::USD_PHASE_COMP_DC - 2 > dPhaseCompFrac = m_dPhaseCompFrac[ei][0];
1032 real64 dPhaseAmount[FLUID_PROP_COFFSET::nDer]{};
1039 real64 const phaseAmount = stack.volume * phaseVolFrac[ip] * phaseDens[ip];
1040 real64 const phaseAmount_n = stack.volume * phaseVolFrac_n[ip] * phaseDens_n[ip];
1042 real64 const dPhaseAmount_dP = stack.volume * ( dPhaseVolFrac[ip][Deriv::dP] * phaseDens[ip]
1043 + phaseVolFrac[ip] * dPhaseDens[ip][Deriv::dP] );
1044 dPhaseAmount[FLUID_PROP_COFFSET::dP]=stack.volume * ( dPhaseVolFrac[ip][Deriv::dP] * phaseDens[ip]
1045 + phaseVolFrac[ip] * dPhaseDens[ip][Deriv::dP] );
1048 applyChainRule(
numComp, dCompFrac_dCompDens, dPhaseDens[ip], dPhaseAmount_dC, Deriv::dC );
1049 applyChainRule(
numComp, dCompFrac_dCompDens, dPhaseDens[ip], &dPhaseAmount[FLUID_PROP_COFFSET::dC], Deriv::dC );
1052 dPhaseAmount_dC[jc] = dPhaseAmount_dC[jc] * phaseVolFrac[ip]
1053 + phaseDens[ip] * dPhaseVolFrac[ip][Deriv::dC+jc];
1054 dPhaseAmount_dC[jc] *= stack.volume;
1055 dPhaseAmount[FLUID_PROP_COFFSET::dC+jc] = dPhaseAmount[FLUID_PROP_COFFSET::dC+jc] * phaseVolFrac[ip]
1056 + phaseDens[ip] * dPhaseVolFrac[ip][Deriv::dC+jc];
1057 dPhaseAmount[FLUID_PROP_COFFSET::dC+jc] *= stack.volume;
1062 assert( fabs( dPhaseAmount[FLUID_PROP_COFFSET::dC+ic] -dPhaseAmount_dC[ic] ) < FLT_EPSILON );
1069 real64 const phaseCompAmount = phaseAmount * phaseCompFrac[ip][ic];
1070 real64 const phaseCompAmount_n = phaseAmount_n * phaseCompFrac_n[ip][ic];
1072 real64 const dPhaseCompAmount_dP = dPhaseAmount_dP * phaseCompFrac[ip][ic]
1073 + phaseAmount * dPhaseCompFrac[ip][ic][Deriv::dP];
1075 stack.
localResidual[ic] += phaseCompAmount - phaseCompAmount_n;
1082 applyChainRule(
numComp, dCompFrac_dCompDens, dPhaseCompFrac[ip][ic], dPhaseCompFrac_dC, Deriv::dC );
1085 real64 const dPhaseCompAmount_dC = dPhaseCompFrac_dC[jc] * phaseAmount
1086 + phaseCompFrac[ip][ic] * dPhaseAmount[FLUID_PROP_COFFSET::dC+jc];
1091 if constexpr ( IS_THERMAL )
1093 dPhaseAmount[FLUID_PROP_COFFSET::dT] = stack.volume * (dPhaseVolFrac[ip][Deriv::dT] * phaseDens[ip] + phaseVolFrac[ip] * dPhaseDens[ip][Deriv::dT] );
1097 stack.
localJacobian[ic][
numComp+1] += dPhaseAmount[FLUID_PROP_COFFSET::dT] * phaseCompFrac[ip][ic]
1098 + phaseAmount * dPhaseCompFrac[ip][ic][Deriv::dT];
1103 phaseAmountKernelOp( ip, phaseAmount, phaseAmount_n, dPhaseAmount );
1130 using Deriv = constitutive::multifluid::DerivativeOffset;
1132 arraySlice1d<
real64 const, compflow::USD_PHASE - 1 > phaseVolFrac = m_phaseVolFrac[ei];
1133 arraySlice2d<
real64 const, compflow::USD_PHASE_DC - 1 > dPhaseVolFrac = m_dPhaseVolFrac[ei];
1135 real64 oneMinusPhaseVolFracSum = 1.0;
1142 oneMinusPhaseVolFracSum -= phaseVolFrac[ip];
1150 if constexpr ( IS_THERMAL)
1174 using namespace compositionalMultiphaseUtilities;
1178 if constexpr ( IS_THERMAL)
1199 if( m_kernelFlags.isSet( isothermalCompositionalMultiphaseBaseKernels::KernelFlags::TotalMassEquation ) )
1212 for(
integer i = 0; i < numRows; ++i )
1215 m_localMatrix.addToRow< serialAtomic >( stack.eqnRowIndices[i],
1216 stack.dofColIndices,
1230 template<
typename POLICY,
typename KERNEL_TYPE >
1233 KERNEL_TYPE
const & kernelComponent )
1239 if( kernelComponent.elemGhostRank( ei ) >= 0 )
1244 typename KERNEL_TYPE::StackVariables stack;
1246 kernelComponent.setup( ei, stack );
1247 kernelComponent.computeAccumulation( ei, stack );
1248 kernelComponent.computeVolumeBalance( ei, stack );
1249 kernelComponent.complete( ei, stack );
1308 BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags >
const m_kernelFlags;
1330 template<
typename POLICY >
1336 BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > kernelFlags,
1337 string const dofKey,
1339 constitutive::MultiFluidBase
const & fluid,
1343 geos::internal::kernelLaunchSelectorCompThermSwitch( numComps, 0, [&](
auto NC,
auto IS_THERMAL )
1347 integer constexpr istherm = IS_THERMAL();
1350 kernel( numPhases, isProducer, rankOffset, dofKey, subRegion, fluid, localMatrix, localRhs, kernelFlags );
1352 launch< POLICY, ElementBasedAssemblyKernel< NUM_COMP, istherm > >( subRegion.
size(), kernel );
1364 template<
integer NC,
integer IS_THERMAL >
1373 using FLUID_PROP_COFFSET = constitutive::multifluid::DerivativeOffsetC< NC, IS_THERMAL >;
1377 using CP_Deriv = constitutive::multifluid::DerivativeOffsetC< NC, IS_THERMAL >;
1387 static constexpr
integer maxNumElems = 2;
1388 static constexpr
integer maxStencilSize = 2;
1405 string const wellDofKey,
1410 BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > kernelFlags )
1414 m_wellElemDofNumber ( subRegion.getReference<
array1d<
globalIndex > >( wellDofKey ) ),
1416 m_connRate ( subRegion.getField< fields::well::mixtureConnectionRate >() ),
1417 m_wellElemCompFrac ( subRegion.getField< fields::well::globalCompFraction >() ),
1418 m_dWellElemCompFrac_dCompDens ( subRegion.getField< fields::well::dGlobalCompFraction_dGlobalCompDensity >() ),
1421 m_useTotalMassEquation ( kernelFlags.isSet( isothermalCompositionalMultiphaseBaseKernels::KernelFlags::TotalMassEquation ) ),
1423 m_injection ( wellControls.getInjectionStream() )
1437 : stencilSize( size ),
1438 numConnectedElems( 2 ),
1439 dofColIndices( size *
numDof )
1479 if( m_nextWellElemIndex[iconn] <0 )
1500 using namespace compositionalMultiphaseUtilities;
1506 for(
integer ic = 0; ic < NC; ++ic )
1508 oneSidedEqnRowIndices[ic] = stack.offsetUp + WJ_ROFFSET::MASSBAL + ic -
m_rankOffset;
1512 globalIndex oneSidedDofColIndices_dPresCompTempUp[CP_Deriv::nDer]{};
1513 globalIndex oneSidedDofColIndices_dRate = stack.offsetCurrent + WJ_COFFSET::dQ;
1516 oneSidedDofColIndices_dPresCompTempUp[ioff++] = stack.offsetUp + WJ_COFFSET::dP;
1518 if constexpr ( IS_THERMAL )
1520 oneSidedDofColIndices_dPresCompTempUp[ioff++] = stack.offsetUp + WJ_COFFSET::dT;
1522 for(
integer jdof = 0; jdof < NC; ++jdof )
1524 oneSidedDofColIndices_dPresCompTempUp[ioff++] = stack.offsetUp + WJ_COFFSET::dC+ jdof;
1526 if( m_useTotalMassEquation > 0 )
1529 real64 work[CP_Deriv::nDer]{};
1532 shiftElementsAheadByOneAndReplaceFirstElementWithSum(
numEqn, stack.
localFlux );
1536 if( oneSidedEqnRowIndices[i] >= 0 && oneSidedEqnRowIndices[i] <
m_localMatrix.numRows() )
1538 m_localMatrix.addToRow< parallelDeviceAtomic >( oneSidedEqnRowIndices[i],
1539 &oneSidedDofColIndices_dRate,
1542 m_localMatrix.addToRowBinarySearchUnsorted< parallelDeviceAtomic >( oneSidedEqnRowIndices[i],
1543 oneSidedDofColIndices_dPresCompTempUp,
1546 RAJA::atomicAdd( parallelDeviceAtomic{}, &
m_localRhs[oneSidedEqnRowIndices[i]], stack.
localFlux[i] );
1556 for(
integer ic = 0; ic < NC; ++ic )
1559 eqnRowIndices[TAG::NEXT *
numEqn+ic] = stack.offsetNext + WJ_ROFFSET::MASSBAL + ic -
m_rankOffset;
1560 eqnRowIndices[TAG::CURRENT *
numEqn+ic] = stack.offsetCurrent + WJ_ROFFSET::MASSBAL + ic -
m_rankOffset;
1564 globalIndex dofColIndices_dPresCompUp[CP_Deriv::nDer]{};
1565 globalIndex dofColIndices_dRate = stack.offsetCurrent + WJ_COFFSET::dQ;
1569 dofColIndices_dPresCompUp[ioff++] = stack.offsetUp + WJ_COFFSET::dP;
1571 if constexpr ( IS_THERMAL )
1573 dofColIndices_dPresCompUp[ioff++] = stack.offsetUp + WJ_COFFSET::dT;
1575 for(
integer jdof = 0; jdof < NC; ++jdof )
1577 dofColIndices_dPresCompUp[ioff++] = stack.offsetUp + WJ_COFFSET::dC+ jdof;
1581 if( m_useTotalMassEquation > 0 )
1584 real64 work[CP_Deriv::nDer]{};
1590 for(
integer i = 0; i < 2*NC; ++i )
1592 if( eqnRowIndices[i] >= 0 && eqnRowIndices[i] <
m_localMatrix.numRows() )
1594 m_localMatrix.addToRow< parallelDeviceAtomic >( eqnRowIndices[i],
1595 &dofColIndices_dRate,
1598 m_localMatrix.addToRowBinarySearchUnsorted< parallelDeviceAtomic >( eqnRowIndices[i],
1599 dofColIndices_dPresCompUp,
1602 RAJA::atomicAdd( parallelDeviceAtomic{}, &
m_localRhs[eqnRowIndices[i]], stack.
localFlux[i] );
1612 computeExit(
real64 const & dt,
1613 real64 const ( &compFlux )[NC ],
1614 StackVariables & stack,
1617 for(
integer ic = 0; ic < NC; ++ic )
1619 stack.localFlux[ic] = -dt * compFlux[ic];
1621 stack.localFluxJacobian_dQ[ic][0] = -dt * dCompFlux[ic][WJ_COFFSET::dQ];
1623 stack.localFluxJacobian[ic][CP_Deriv::dP] = -dt * dCompFlux[ic][WJ_COFFSET::dP];
1625 for(
integer jdof = 0; jdof < NC; ++jdof )
1627 stack.localFluxJacobian[ic][CP_Deriv::dC+jdof] = -dt * dCompFlux[ic][WJ_COFFSET::dC+jdof];
1629 if constexpr ( IS_THERMAL )
1631 stack.localFluxJacobian[ic][CP_Deriv::dT] = -dt * dCompFlux[ic][WJ_COFFSET::dT];
1639 compute(
real64 const & dt,
1640 real64 const ( &compFlux )[NC ],
1641 StackVariables & stack,
1645 for(
integer ic = 0; ic < NC; ++ic )
1647 stack.localFlux[TAG::NEXT * NC +ic] = dt * compFlux[ic];
1648 stack.localFlux[TAG::CURRENT * NC +ic] = -dt * compFlux[ic];
1650 stack.localFluxJacobian_dQ[TAG::NEXT * NC+ ic][0] = dt * dCompFlux[ic][WJ_COFFSET::dQ];
1651 stack.localFluxJacobian_dQ[TAG::CURRENT * NC + +ic][0] = -dt * dCompFlux[ic][WJ_COFFSET::dQ];
1654 stack.localFluxJacobian[TAG::NEXT * NC +ic][CP_Deriv::dP] = dt * dCompFlux[ic][WJ_COFFSET::dP];
1655 stack.localFluxJacobian[TAG::CURRENT * NC+ ic][CP_Deriv::dP] = -dt * dCompFlux[ic][WJ_COFFSET::dP];
1657 if constexpr ( IS_THERMAL )
1659 stack.localFluxJacobian[TAG::NEXT * NC +ic][CP_Deriv::dT] = dt * dCompFlux[ic][WJ_COFFSET::dT];
1660 stack.localFluxJacobian[TAG::CURRENT * NC +ic][CP_Deriv::dT] = -dt * dCompFlux[ic][WJ_COFFSET::dT];
1664 for(
integer jdof = 0; jdof < NC; ++jdof )
1666 stack.localFluxJacobian[TAG::NEXT * NC +ic][CP_Deriv::dC+jdof] = dt * dCompFlux[ic][WJ_COFFSET::dC+jdof];
1667 stack.localFluxJacobian[TAG::CURRENT * NC +ic][CP_Deriv::dC+jdof] = -dt * dCompFlux[ic][WJ_COFFSET::dC+jdof];
1679 template<
typename FUNC = NoOpFunc >
1684 FUNC && compFluxKernelOp = NoOpFunc{} )
const
1687 using namespace compositionalMultiphaseUtilities;
1694 for(
integer ic = 0; ic < NC; ++ic )
1696 for(
integer jc = 0; jc < NC; ++jc )
1709 localIndex const iwelemNext = m_nextWellElemIndex[iwelem];
1710 real64 const currentConnRate = m_connRate[iwelem];
1719 for(
integer ic = 0; ic < NC; ++ic )
1721 compFracUp[ic] = m_injection[ic];
1722 for(
integer jc = 0; jc < NC; ++jc )
1724 dComp[ic][jc] = m_dWellElemCompFrac_dCompDens[iwelemUp][ic][jc];
1726 for(
integer jc = 0; jc < NC; ++jc )
1728 dCompFlux[ic][WJ_COFFSET::dC+jc] = 0.0;
1736 || currentConnRate < 0 )
1742 iwelemUp = iwelemNext;
1746 for(
integer ic = 0; ic < NC; ++ic )
1748 compFracUp[ic] = m_wellElemCompFrac[iwelemUp][ic];
1749 for(
integer jc = 0; jc < NC; ++jc )
1751 dCompFlux[ic][WJ_COFFSET::dC+jc] = m_dWellElemCompFrac_dCompDens[iwelemUp][ic][jc];
1752 dComp[ic][jc] = m_dWellElemCompFrac_dCompDens[iwelemUp][ic][jc];
1759 for(
integer ic = 0; ic < NC; ++ic )
1761 compFlux[ic] = compFracUp[ic] * currentConnRate;
1762 dCompFlux[ic][WJ_COFFSET::dQ] = compFracUp[ic];
1764 dCompFlux[ic][WJ_COFFSET::dP] = 0.0;
1765 if constexpr ( IS_THERMAL )
1767 dCompFlux[ic][WJ_COFFSET::dT] = 0.0;
1769 for(
integer jc = 0; jc < NC; ++jc )
1771 dCompFlux[ic][WJ_COFFSET::dC+jc] = dCompFlux[ic][WJ_COFFSET::dC+jc] * currentConnRate;
1775 stack.offsetUp = m_wellElemDofNumber[iwelemUp];
1776 stack.iwelemUp = iwelemUp;
1777 stack.offsetCurrent = m_wellElemDofNumber[iwelem];
1778 stack.iwelemCurrent= iwelem;
1781 if( iwelemNext < 0 )
1797 stack.offsetNext = m_wellElemDofNumber[iwelemNext];
1799 stack.iwelemNext = iwelemNext;
1800 compFluxKernelOp( iwelemNext, iwelemUp, currentConnRate, dComp );
1811 template<
typename POLICY,
typename KERNEL_TYPE >
1814 KERNEL_TYPE
const & kernelComponent )
1819 typename KERNEL_TYPE::StackVariables stack( 1 );
1821 kernelComponent.setup( ie, stack );
1822 kernelComponent.computeFlux( ie, stack );
1823 kernelComponent.complete( ie, stack );
1884 template<
typename POLICY >
1889 BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > kernelFlags,
1890 string const dofKey,
1896 isothermalCompositionalMultiphaseBaseKernels::internal::kernelLaunchSelectorCompSwitch( numComps, [&](
auto NC )
1898 integer constexpr NUM_COMP = NC();
1901 kernelType kernel( dt, rankOffset, dofKey, wellControls, subRegion, localMatrix, localRhs, kernelFlags );
1902 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.
ScalingType
Solution scaling type.
typename ElementViewAccessor< VIEWTYPE >::NestedViewTypeConst ElementViewConst
The ElementViewAccessor at the ElementRegionManager level is the type resulting from ElementViewAcces...
arrayView1d< real64 const > getElementVolume() const
Get the volume of each element in this subregion.
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.
GEOS_DECLTYPE_AUTO_RETURN getField() const
Get a view to the field associated with a trait from this ObjectManagerBase.
A struct to automatically construct and store element view accessors.
A struct to automatically construct and store element view accessors.
This class describes the controls used to operate a well.
bool isProducer() const
Is the well a producer?
Control getControl() const
Get the control type for the well.
real64 getTargetPhaseRate(real64 const ¤tTime) const
Get the target phase rate.
real64 getTargetTotalRate(real64 const ¤tTime) const
Get the target total rate.
real64 getTargetMassRate(real64 const ¤tTime) const
Get the target mass rate.
real64 getTargetBHP(real64 const ¤tTime) const
Get the target bottom hole pressure value.
This class describes a collection of local well elements and perforations.
bool isLocallyOwned() const
Check if well is owned by current rank.
localIndex getTopWellElementIndex() const
Get for the top element index.
static void createAndLaunch(localIndex const numComps, localIndex const numPhases, integer const isProducer, globalIndex const rankOffset, BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > kernelFlags, string const dofKey, WellElementSubRegion const &subRegion, constitutive::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 accumulation and volume balance.
static constexpr integer numEqn
Compute time value for the number of equations mass bal + vol bal + energy bal.
ElementBasedAssemblyKernel(localIndex const numPhases, integer const isProducer, globalIndex const rankOffset, string const dofKey, WellElementSubRegion const &subRegion, constitutive::MultiFluidBase const &fluid, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs, BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > const kernelFlags)
Constructor.
arrayView1d< globalIndex const > const m_dofNumber
View on the dof numbers.
arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > const m_phaseDens_n
Views on the phase densities.
GEOS_HOST_DEVICE void computeAccumulation(localIndex const ei, StackVariables &stack, FUNC &&phaseAmountKernelOp=NoOpFunc{}) const
Compute the local accumulation contributions to the residual and Jacobian.
arrayView4d< real64 const, constitutive::multifluid::USD_PHASE_COMP > const m_phaseCompFrac_n
Views on the phase component fraction.
GEOS_HOST_DEVICE integer elemGhostRank(localIndex const ei) const
Getter for the ghost rank of an element.
arrayView3d< real64 const, compflow::USD_COMP_DC > const m_dCompFrac_dCompDens
Views on the derivatives of comp fractions wrt component density.
arrayView1d< real64 const > const m_volume
View on the element volumes.
GEOS_HOST_DEVICE void complete(localIndex const ei, StackVariables &stack) const
Performs the complete phase for the kernel.
static constexpr integer numComp
Compile time value for the number of components.
globalIndex const m_rankOffset
Offset for my MPI rank.
integer const m_isProducer
Well type.
static void launch(localIndex const numElems, KERNEL_TYPE const &kernelComponent)
Performs the kernel launch.
arrayView2d< real64 const, compflow::USD_PHASE > const m_phaseVolFrac_n
Views on the phase volume fractions.
static constexpr integer numDof
Number of Dof's set in this kernal - no dQ in accum.
GEOS_HOST_DEVICE void computeVolumeBalance(localIndex const ei, StackVariables &stack) const
Compute the local volume balance contributions to the residual and Jacobian.
CRSMatrixView< real64, globalIndex const > const m_localMatrix
View on the local CRS matrix.
integer const m_numPhases
Number of fluid phases.
arrayView1d< integer const > const m_elemGhostRank
View on the ghost ranks.
localIndex const m_iwelemControl
Index of the element where the control is enforced.
arrayView1d< real64 > const m_localRhs
View on the local RHS.
GEOS_HOST_DEVICE void setup(localIndex const ei, StackVariables &stack) const
Performs the setup phase for the kernel.
arrayView2d< real64 const > const m_porosity_n
Views on the porosity.
static void createAndLaunch(integer const numComps, real64 const dt, globalIndex const rankOffset, BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > kernelFlags, string const dofKey, WellControls const &wellControls, WellElementSubRegion const &subRegion, 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.
arrayView1d< globalIndex const > const m_wellElemDofNumber
Reference to the degree-of-freedom numbers.
arrayView1d< real64 const > const m_injection
Injection stream composition.
arrayView1d< real64 > const m_localRhs
View on the local RHS.
GEOS_HOST_DEVICE void setup(localIndex const iconn, StackVariables &stack) const
Performs the setup phase for the kernel.
GEOS_HOST_DEVICE void computeFlux(localIndex const iwelem, StackVariables &stack, FUNC &&compFluxKernelOp=NoOpFunc{}) const
Compute the local flux contributions to the residual and Jacobian.
integer const m_useTotalMassEquation
Kernel option flag.
GEOS_HOST_DEVICE void complete(localIndex const iconn, StackVariables &stack) const
Performs the setup phase for the kernel.
integer const m_rankOffset
Rank offset for calculating row/col Jacobian indices.
arrayView1d< localIndex const > const m_nextWellElemIndex
Next element index, needed since iterating over element nodes, not edges.
arrayView2d< real64 const, compflow::USD_COMP > const m_wellElemCompFrac
Element component fraction.
real64 const m_dt
Time step size.
static void launch(localIndex const numElements, KERNEL_TYPE const &kernelComponent)
Performs the kernel launch.
FaceBasedAssemblyKernel(real64 const dt, globalIndex const rankOffset, string const wellDofKey, WellControls const &wellControls, WellElementSubRegion const &subRegion, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs, BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > kernelFlags)
Constructor for the kernel interface.
arrayView1d< real64 const > const m_connRate
Connection rate.
CRSMatrixView< real64, globalIndex const > const m_localMatrix
View on the local CRS matrix.
arrayView3d< real64 const, compflow::USD_COMP_DC > const m_dWellElemCompFrac_dCompDens
Element component fraction derivatives.
bool const m_isProducer
Well type.
static void createAndLaunch(integer const numComp, integer const numDof, integer const targetPhaseIndex, globalIndex const rankOffset, string const &dofKey, arrayView1d< real64 const > const &localResidual, WellElementSubRegion const &subRegion, constitutive::MultiFluidBase const &fluid, WellControls const &wellControls, real64 const timeAtEndOfStep, real64 const dt, real64 const minNormalizer, real64(&residualNorm)[1])
Create a new kernel and launch.
virtual GEOS_HOST_DEVICE void computeLinf(localIndex const iwelem, LinfStackVariables &stack) const override
Compute the local values for the Linf norm.
bool const m_isLocallyOwned
Flag indicating whether the well is locally owned or not.
integer const m_numComp
Number of fluid components.
arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > const m_phaseDens_n
View on phase/total density at the previous converged time step.
arrayView1d< real64 const > const m_volume
View on the volume.
integer const m_targetPhaseIndex
Index of the target phase.
integer const m_numDof
Number of dof per well element.
WellControls::Control const m_currentControl
Controls.
real64 const m_dt
Time step size.
localIndex const m_iwelemControl
Index of the element where the control is enforced.
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.
static isothermalCompositionalMultiphaseBaseKernels::SolutionCheckKernel::StackVariables createAndLaunch(integer const allowCompDensChopping, CompositionalMultiphaseFVM::ScalingType const scalingType, real64 const scalingFactor, arrayView1d< real64 const > const pressure, arrayView2d< real64 const, compflow::USD_COMP > const compDens, arrayView1d< real64 > pressureScalingFactor, arrayView1d< real64 > compDensScalingFactor, globalIndex const rankOffset, integer const numComp, string const dofKey, ElementSubRegionBase &subRegion, arrayView1d< real64 const > const localSolution)
Create a new kernel and launch.
static isothermalCompositionalMultiphaseBaseKernels::SolutionScalingKernel::StackVariables createAndLaunch(real64 const maxRelativePresChange, real64 const maxAbsolutePresChange, real64 const maxCompFracChange, real64 const maxRelativeCompDensChange, globalIndex const rankOffset, integer const numComp, string const dofKey, ElementSubRegionBase &subRegion, arrayView1d< real64 const > const localSolution)
Create a new kernel and launch.
static void createAndLaunch(integer const numComp, integer const numPhase, ObjectManagerBase &subRegion, constitutive::MultiFluidBase const &fluid)
Create a new kernel and launch.
Define the interface for the property kernel in charge of computing the total mass density.
arrayView1d< real64 > m_totalMassDens
Views on total mass densities.
GEOS_HOST_DEVICE void compute(localIndex const ei, FUNC &&totalMassDensityKernelOp=NoOpFunc{}) const
Compute the total mass density in an element.
static constexpr integer numPhase
Compile time value for the number of phases.
arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > m_phaseMassDens
Views on phase mass densities.
arrayView2d< real64 const, compflow::USD_PHASE > m_phaseVolFrac
Views on phase volume fractions.
static constexpr integer numComp
Compile time value for the number of components.
TotalMassDensityKernel(ObjectManagerBase &subRegion, constitutive::MultiFluidBase const &fluid)
Constructor.
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.
static constexpr integer numComp
Compile time value for the number of components.
Define the base interface for the residual calculations.
real64 const m_minNormalizer
Value used to make sure that normalizers are never zero.
arrayView1d< globalIndex const > const m_dofNumber
View on the dof numbers.
GEOS_HOST_DEVICE integer ghostRank(localIndex const i) const
Getter for the ghost rank.
globalIndex const m_rankOffset
Offset for my MPI rank.
arrayView1d< real64 const > const m_localResidual
View on the local residual.
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.
ArraySlice< T, 3, USD > arraySlice3d
Alias for 3D array slice.
ArrayView< T, 5, USD > arrayView5d
Alias for 5D array view.
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.
Kernel variables (dof numbers, jacobian and residual) located on the stack.
real64 localJacobian[numEqn][numDof]
C-array storage for the element local Jacobian matrix (all equations except constraint and momentum)
globalIndex dofIndices[numDof]
Indices of the matrix rows/columns corresponding to the dofs in this element.
localIndex localRow
Index of the local row corresponding to this element.
real64 localResidual[numEqn]
C-array storage for the element local residual vector (all equations except constraint and momentum)
stackArray2d< real64, maxNumElems *numEqn *maxStencilSize *CP_Deriv::nDer > localFluxJacobian
Storage for the face local Jacobian matrix dC dP dT.
GEOS_HOST_DEVICE StackVariables(localIndex const size)
Constructor for the stack variables.
stackArray2d< real64, maxNumElems *numEqn *maxStencilSize > localFluxJacobian_dQ
Storage for the face local Jacobian matrix dQ only.
stackArray1d< globalIndex, maxNumElems *numDof > dofColIndices
Indices of the matrix rows/columns corresponding to the dofs in this face.
stackArray1d< real64, maxNumElems *numEqn > localFlux
Storage for the face local residual vector (all mass bal equations)
localIndex numConnectedElems
Number of elements connected at a given connection.
ElementRegionManager::ElementViewConst< VIEWTYPE > ElementViewConst
The type for element-based non-constitutive data parameters. Consists entirely of ArrayView's.
Kernel variables located on the stack.
Kernel variables located on the stack.