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"
32 #include "mesh/WellElementSubRegion.hpp"
41 #include "physicsSolvers/fluidFlow/wells/WellControls.hpp"
48 namespace compositionalMultiphaseWellKernels
51 static constexpr
real64 minDensForDivision = 1e-10;
56 static constexpr
integer RES = 0;
57 static constexpr
integer WELL = 1;
63 static constexpr
integer CURRENT = 0;
64 static constexpr
integer NEXT = 1;
70 static constexpr
integer DPRES = 0;
71 static constexpr
integer DCOMP = 1;
74 template<
integer NC,
integer IS_THERMAL >
77 template<
integer NC >
80 static constexpr
integer dP = 0;
81 static constexpr
integer dC = 1;
82 static constexpr
integer dQ = dC + NC;
83 static integer constexpr nDer = dQ + 1;
87 template<
integer NC >
90 static constexpr
integer dP = 0;
91 static constexpr
integer dC = 1;
92 static constexpr
integer dQ = dC + NC;
93 static constexpr
integer dT = dQ+1;
101 static constexpr
integer CONTROL = 0;
102 static constexpr
integer MASSBAL = 1;
105 template<
integer NC,
integer IS_THERMAL >
108 template<
integer NC >
111 static constexpr
integer CONTROL = 0;
112 static constexpr
integer MASSBAL = 1;
113 static constexpr
integer VOLBAL = MASSBAL + NC;
114 static constexpr
integer nEqn = VOLBAL+1;
117 template<
integer NC >
120 static constexpr
integer CONTROL = 0;
121 static constexpr
integer MASSBAL = 1;
122 static constexpr
integer VOLBAL = MASSBAL + NC;
123 static constexpr
integer ENERGYBAL = VOLBAL+1;
124 static constexpr
integer nEqn = ENERGYBAL+1;
137 switchControl(
bool const isProducer,
142 real64 const & targetPhaseRate,
143 real64 const & targetTotalRate,
144 real64 const & targetMassRate,
145 real64 const & currentBHP,
147 real64 const & currentTotalVolRate,
148 real64 const & currentMassRate,
151 template<
integer NC,
integer IS_THERMAL >
157 integer const targetPhaseIndex,
159 real64 const & targetPhaseRate,
160 real64 const & targetTotalRate,
161 real64 const & targetMassRate,
162 real64 const & currentBHP,
166 real64 const & currentTotalVolRate,
168 real64 const & massDensity,
179 using Deriv = constitutive::multifluid::DerivativeOffset;
184 template<
integer NC,
integer IS_THERMAL >
188 compute(
real64 const & gravCoef,
189 real64 const & gravCoefNext,
192 real64 const & totalMassDens,
193 real64 const & totalMassDensNext,
197 real64 ( &localPresRelJacobian )[2*(NC+1+IS_THERMAL)] );
199 template<
integer NC,
integer IS_THERMAL >
203 bool const isLocallyOwned,
205 integer const targetPhaseIndex,
215 bool & controlHasSwitched,
229 template<
integer NC >
233 compute(
integer const numPhases,
238 real64 ( &localVolBalanceJacobian )[NC+1] );
240 template<
integer NC >
262 fields::flow::temperature,
263 fields::flow::globalCompDensity,
264 fields::flow::phaseVolumeFraction >;
268 fields::multifluid::phaseMassDensity >;
278 template<
typename VIEWTYPE >
287 real64 const & currentTime,
326 integer const targetPhaseIndex,
328 real64 const & currentTime,
344 template<
integer NUM_COMP,
integer NUM_PHASE >
361 constitutive::MultiFluidBase
const & fluid )
363 m_phaseVolFrac( subRegion.getField< fields::well::phaseVolumeFraction >() ),
364 m_dPhaseVolFrac( subRegion.getField< fields::well::dPhaseVolumeFraction >() ),
365 m_dCompFrac_dCompDens( subRegion.getField< fields::well::dGlobalCompFraction_dGlobalCompDensity >() ),
367 m_dPhaseMassDens( fluid.dPhaseMassDensity() ),
368 m_totalMassDens( subRegion.getField< fields::well::totalMassDensity >() ),
369 m_dTotalMassDens( subRegion.getField< fields::well::dTotalMassDensity >() )
378 template<
typename FUNC = NoOpFunc >
382 FUNC && totalMassDensityKernelOp = NoOpFunc{} )
const
384 using Deriv = constitutive::multifluid::DerivativeOffset;
387 arraySlice2d<
real64 const, compflow::USD_PHASE_DC - 1 > dPhaseVolFrac = m_dPhaseVolFrac[ei];
388 arraySlice2d<
real64 const, compflow::USD_COMP_DC - 1 > dCompFrac_dCompDens = m_dCompFrac_dCompDens[ei];
390 arraySlice2d<
real64 const, constitutive::multifluid::USD_PHASE_DC - 2 > dPhaseMassDens = m_dPhaseMassDens[ei][0];
392 arraySlice1d<
real64, compflow::USD_FLUID_DC - 1 > dTotalMassDens = m_dTotalMassDens[ei];
398 dTotalMassDens[Deriv::dP]=0.0;
401 dTotalMassDens[Deriv::dC+ic]=0.0;
406 totalMassDens += phaseVolFrac[ip] * phaseMassDens[ip];
407 dTotalMassDens[Deriv::dP] += dPhaseVolFrac[ip][Deriv::dP] * phaseMassDens[ip] + phaseVolFrac[ip] * dPhaseMassDens[ip][Deriv::dP];
409 applyChainRule(
numComp, dCompFrac_dCompDens, dPhaseMassDens[ip], dMassDens_dC, Deriv::dC );
412 dTotalMassDens[Deriv::dC+ic] += dPhaseVolFrac[ip][Deriv::dC+ic] * phaseMassDens[ip]
413 + phaseVolFrac[ip] * dMassDens_dC[ic];
416 totalMassDensityKernelOp( ip );
458 template<
typename POLICY >
463 constitutive::MultiFluidBase
const & fluid )
467 isothermalCompositionalMultiphaseBaseKernels::internal::kernelLaunchSelectorCompSwitch( numComp, [&] (
auto NC )
469 integer constexpr NUM_COMP = NC();
474 else if( numPhase == 3 )
476 isothermalCompositionalMultiphaseBaseKernels::internal::kernelLaunchSelectorCompSwitch( numComp, [&] (
auto NC )
478 integer constexpr NUM_COMP = NC();
508 integer const targetPhaseIndex,
510 constitutive::MultiFluidBase
const & fluid,
514 real64 const minNormalizer )
534 m_totalDens_n( fluid.totalDensity_n() )
539 LinfStackVariables & stack )
const override
550 if( idof == ROFFSET::CONTROL )
559 normalizer = m_targetBHP;
564 normalizer = LvArray::math::max( LvArray::math::abs( m_targetTotalRate ),
m_minNormalizer );
569 normalizer = LvArray::math::max( LvArray::math::abs( m_targetPhaseRate ),
m_minNormalizer );
574 normalizer = LvArray::math::max( LvArray::math::abs( m_targetMassRate ),
m_minNormalizer );
580 normalizer = m_targetBHP;
584 else if( idof >= ROFFSET::MASSBAL && idof < ROFFSET::MASSBAL +
m_numComp )
595 normalizer =
m_dt * LvArray::math::abs( m_targetMassRate );
600 normalizer =
m_dt * LvArray::math::abs( m_targetTotalRate ) * m_totalDens_n[iwelem][0];
606 normalizer = LvArray::math::max( normalizer,
m_volume[iwelem] * m_totalDens_n[iwelem][0] );
609 else if( idof == ROFFSET::MASSBAL +
m_numComp )
614 normalizer =
m_dt * LvArray::math::abs( m_targetPhaseRate );
620 normalizer =
m_dt * LvArray::math::abs( m_targetMassRate/ m_totalDens_n[iwelem][0] );
624 normalizer =
m_dt * LvArray::math::abs( m_targetTotalRate );
632 normalizer = LvArray::math::max( normalizer,
m_volume[iwelem] );
636 if( val > stack.localValue[0] )
638 stack.localValue[0] = val;
645 L2StackVariables & stack )
const override
648 GEOS_ERROR(
"The L2 norm is not implemented for CompositionalMultiphaseWell" );
678 real64 const m_targetTotalRate;
679 real64 const m_targetPhaseRate;
680 real64 const m_targetMassRate;
714 template<
typename POLICY >
718 integer const targetPhaseIndex,
720 string const & dofKey,
723 constitutive::MultiFluidBase
const & fluid,
727 real64 const minNormalizer,
728 real64 (& residualNorm)[1] )
734 numComp, numDof, targetPhaseIndex, subRegion, fluid, wellControls, time, dt, minNormalizer );
735 ResidualNormKernel::launchLinf< POLICY >( subRegion.
size(), kernel, residualNorm );
762 template<
typename POLICY >
765 real64 const maxAbsolutePresChange,
766 real64 const maxCompFracChange,
767 real64 const maxRelativeCompDensChange,
775 subRegion.
getField< fields::well::pressure >();
777 subRegion.
getField< fields::well::globalCompDensity >();
779 subRegion.
getField< fields::well::pressureScalingFactor >();
781 subRegion.
getField< fields::well::globalCompDensityScalingFactor >();
782 isothermalCompositionalMultiphaseBaseKernels::
783 SolutionScalingKernel kernel( maxRelativePresChange, maxAbsolutePresChange, maxCompFracChange, maxRelativeCompDensChange, rankOffset,
784 numComp, dofKey, subRegion, localSolution, pressure, compDens, pressureScalingFactor, compDensScalingFactor );
785 return isothermalCompositionalMultiphaseBaseKernels::
786 SolutionScalingKernel::
787 launch< POLICY >( subRegion.
size(), kernel );
800 template<
integer NUM_COMP,
integer IS_THERMAL >
808 using FLUID_PROP_COFFSET = constitutive::multifluid::DerivativeOffsetC< NUM_COMP, IS_THERMAL >;
837 constitutive::MultiFluidBase
const & fluid,
840 BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags >
const kernelFlags )
848 m_volume( subRegion.getElementVolume() ),
849 m_dCompFrac_dCompDens( subRegion.getField< fields::flow::dGlobalCompFraction_dGlobalCompDensity >() ),
850 m_phaseVolFrac_n( subRegion.getField< fields::flow::phaseVolumeFraction_n >() ),
851 m_phaseVolFrac( subRegion.getField< fields::flow::phaseVolumeFraction >() ),
852 m_dPhaseVolFrac( subRegion.getField< fields::flow::dPhaseVolumeFraction >() ),
854 m_phaseDens( fluid.phaseDensity() ),
855 m_dPhaseDens( fluid.dPhaseDensity() ),
857 m_phaseCompFrac( fluid.phaseCompFraction() ),
858 m_dPhaseCompFrac( fluid.dPhaseCompFraction() ),
859 m_compDens( subRegion.getField< fields::flow::globalCompDensity >() ),
860 m_compDens_n( subRegion.getField< fields::flow::globalCompDensity_n >() ),
863 m_kernelFlags( kernelFlags )
929 if constexpr ( IS_THERMAL )
934 stack.dofColIndices[0] =
m_dofNumber[ei] + WJ_COFFSET::dP;
937 stack.dofColIndices[ic+1] =
m_dofNumber[ei] + WJ_COFFSET::dC+ic;
939 if constexpr ( IS_THERMAL )
959 template<
typename FUNC = NoOpFunc >
963 FUNC && phaseAmountKernelOp = NoOpFunc{} )
const
966 using Deriv = constitutive::multifluid::DerivativeOffset;
972 arraySlice1d<
real64 const, compflow::USD_PHASE - 1 > phaseVolFrac = m_phaseVolFrac[ei];
973 arraySlice2d<
real64 const, compflow::USD_PHASE_DC - 1 > dPhaseVolFrac = m_dPhaseVolFrac[ei];
976 arraySlice1d<
real64 const, constitutive::multifluid::USD_PHASE - 2 > phaseDens = m_phaseDens[ei][0];
977 arraySlice2d<
real64 const, constitutive::multifluid::USD_PHASE_DC - 2 > dPhaseDens = m_dPhaseDens[ei][0];
980 arraySlice2d<
real64 const, constitutive::multifluid::USD_PHASE_COMP - 2 > phaseCompFrac = m_phaseCompFrac[ei][0];
981 arraySlice3d<
real64 const, constitutive::multifluid::USD_PHASE_COMP_DC - 2 > dPhaseCompFrac = m_dPhaseCompFrac[ei][0];
984 real64 dPhaseAmount[FLUID_PROP_COFFSET::nDer]{};
991 real64 const phaseAmount = stack.volume * phaseVolFrac[ip] * phaseDens[ip];
992 real64 const phaseAmount_n = stack.volume * phaseVolFrac_n[ip] * phaseDens_n[ip];
994 dPhaseAmount[FLUID_PROP_COFFSET::dP]=stack.volume * ( dPhaseVolFrac[ip][Deriv::dP] * phaseDens[ip]
995 + phaseVolFrac[ip] * dPhaseDens[ip][Deriv::dP] );
998 applyChainRule(
numComp, dCompFrac_dCompDens, dPhaseDens[ip], dPhaseAmount_dC, Deriv::dC );
999 applyChainRule(
numComp, dCompFrac_dCompDens, dPhaseDens[ip], &dPhaseAmount[FLUID_PROP_COFFSET::dC], Deriv::dC );
1002 dPhaseAmount_dC[jc] = dPhaseAmount_dC[jc] * phaseVolFrac[ip]
1003 + phaseDens[ip] * dPhaseVolFrac[ip][Deriv::dC+jc];
1004 dPhaseAmount_dC[jc] *= stack.volume;
1005 dPhaseAmount[FLUID_PROP_COFFSET::dC+jc] = dPhaseAmount[FLUID_PROP_COFFSET::dC+jc] * phaseVolFrac[ip]
1006 + phaseDens[ip] * dPhaseVolFrac[ip][Deriv::dC+jc];
1007 dPhaseAmount[FLUID_PROP_COFFSET::dC+jc] *= stack.volume;
1013 real64 const phaseCompAmount = phaseAmount * phaseCompFrac[ip][ic];
1014 real64 const phaseCompAmount_n = phaseAmount_n * phaseCompFrac_n[ip][ic];
1016 real64 const dPhaseCompAmount_dP = dPhaseAmount[FLUID_PROP_COFFSET::dP] * phaseCompFrac[ip][ic]
1017 + phaseAmount * dPhaseCompFrac[ip][ic][Deriv::dP];
1019 stack.
localResidual[ic] += phaseCompAmount - phaseCompAmount_n;
1026 applyChainRule(
numComp, dCompFrac_dCompDens, dPhaseCompFrac[ip][ic], dPhaseCompFrac_dC, Deriv::dC );
1029 real64 const dPhaseCompAmount_dC = dPhaseCompFrac_dC[jc] * phaseAmount
1030 + phaseCompFrac[ip][ic] * dPhaseAmount[FLUID_PROP_COFFSET::dC+jc];
1035 if constexpr ( IS_THERMAL )
1037 dPhaseAmount[FLUID_PROP_COFFSET::dT] = stack.volume * (dPhaseVolFrac[ip][Deriv::dT] * phaseDens[ip] + phaseVolFrac[ip] * dPhaseDens[ip][Deriv::dT] );
1041 stack.
localJacobian[ic][
numComp+1] += dPhaseAmount[FLUID_PROP_COFFSET::dT] * phaseCompFrac[ip][ic]
1042 + phaseAmount * dPhaseCompFrac[ip][ic][Deriv::dT];
1047 phaseAmountKernelOp( ip, phaseAmount, phaseAmount_n, dPhaseAmount );
1074 using Deriv = constitutive::multifluid::DerivativeOffset;
1076 arraySlice1d<
real64 const, compflow::USD_PHASE - 1 > phaseVolFrac = m_phaseVolFrac[ei];
1077 arraySlice2d<
real64 const, compflow::USD_PHASE_DC - 1 > dPhaseVolFrac = m_dPhaseVolFrac[ei];
1079 real64 oneMinusPhaseVolFracSum = 1.0;
1086 oneMinusPhaseVolFracSum -= phaseVolFrac[ip];
1094 if constexpr ( IS_THERMAL)
1117 using namespace compositionalMultiphaseUtilities;
1121 if constexpr ( IS_THERMAL)
1142 if( m_kernelFlags.isSet( isothermalCompositionalMultiphaseBaseKernels::KernelFlags::TotalMassEquation ) )
1155 for(
integer i = 0; i < numRows; ++i )
1158 m_localMatrix.addToRow< serialAtomic >( stack.eqnRowIndices[i],
1159 stack.dofColIndices,
1173 template<
typename POLICY,
typename KERNEL_TYPE >
1176 KERNEL_TYPE
const & kernelComponent )
1181 if( kernelComponent.skipElement( ei ) )
1186 typename KERNEL_TYPE::StackVariables stack;
1188 kernelComponent.setup( ei, stack );
1189 kernelComponent.computeAccumulation( ei, stack );
1190 kernelComponent.computeVolumeBalance( ei, stack );
1191 kernelComponent.complete( ei, stack );
1253 BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags >
const m_kernelFlags;
1275 template<
typename POLICY >
1281 BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > kernelFlags,
1282 string const dofKey,
1284 constitutive::MultiFluidBase
const & fluid,
1288 geos::internal::kernelLaunchSelectorCompThermSwitch( numComps, 0, [&](
auto NC,
auto IS_THERMAL )
1292 integer constexpr istherm = IS_THERMAL();
1295 kernel( numPhases, isProducer, rankOffset, dofKey, subRegion, fluid, localMatrix, localRhs, kernelFlags );
1297 launch< POLICY, ElementBasedAssemblyKernel< NUM_COMP, istherm > >( subRegion.
size(), kernel );
1309 template<
integer NC,
integer IS_THERMAL >
1318 using FLUID_PROP_COFFSET = constitutive::multifluid::DerivativeOffsetC< NC, IS_THERMAL >;
1322 using CP_Deriv = constitutive::multifluid::DerivativeOffsetC< NC, IS_THERMAL >;
1332 static constexpr
integer maxNumElems = 2;
1333 static constexpr
integer maxStencilSize = 2;
1350 string const wellDofKey,
1355 BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > kernelFlags )
1359 m_wellElemDofNumber ( subRegion.getReference<
array1d<
globalIndex > >( wellDofKey ) ),
1362 m_connRate ( subRegion.getField< fields::well::mixtureConnectionRate >() ),
1363 m_wellElemCompFrac ( subRegion.getField< fields::well::globalCompFraction >() ),
1364 m_dWellElemCompFrac_dCompDens ( subRegion.getField< fields::well::dGlobalCompFraction_dGlobalCompDensity >() ),
1367 m_useTotalMassEquation ( kernelFlags.isSet( isothermalCompositionalMultiphaseBaseKernels::KernelFlags::TotalMassEquation ) ),
1369 m_injection ( wellControls.getInjectionStream() )
1383 : stencilSize( size ),
1384 numConnectedElems( 2 ),
1385 dofColIndices( size *
numDof )
1418 return (
m_elemStatus[ei]==WellElementSubRegion::WellElemStatus::CLOSED );
1432 if( m_nextWellElemIndex[iconn] <0 )
1454 using namespace compositionalMultiphaseUtilities;
1460 for(
integer ic = 0; ic < NC; ++ic )
1462 oneSidedEqnRowIndices[ic] = stack.offsetUp + WJ_ROFFSET::MASSBAL + ic -
m_rankOffset;
1466 globalIndex oneSidedDofColIndices_dPresCompTempUp[CP_Deriv::nDer]{};
1467 globalIndex oneSidedDofColIndices_dRate = stack.offsetCurrent + WJ_COFFSET::dQ;
1470 oneSidedDofColIndices_dPresCompTempUp[ioff++] = stack.offsetUp + WJ_COFFSET::dP;
1472 if constexpr ( IS_THERMAL )
1474 oneSidedDofColIndices_dPresCompTempUp[ioff++] = stack.offsetUp + WJ_COFFSET::dT;
1476 for(
integer jdof = 0; jdof < NC; ++jdof )
1478 oneSidedDofColIndices_dPresCompTempUp[ioff++] = stack.offsetUp + WJ_COFFSET::dC+ jdof;
1480 if( m_useTotalMassEquation > 0 )
1483 real64 work[CP_Deriv::nDer]{};
1486 shiftElementsAheadByOneAndReplaceFirstElementWithSum(
numEqn, stack.
localFlux );
1490 if( oneSidedEqnRowIndices[i] >= 0 && oneSidedEqnRowIndices[i] <
m_localMatrix.numRows() )
1492 m_localMatrix.addToRow< parallelDeviceAtomic >( oneSidedEqnRowIndices[i],
1493 &oneSidedDofColIndices_dRate,
1496 m_localMatrix.addToRowBinarySearchUnsorted< parallelDeviceAtomic >( oneSidedEqnRowIndices[i],
1497 oneSidedDofColIndices_dPresCompTempUp,
1500 RAJA::atomicAdd( parallelDeviceAtomic{}, &
m_localRhs[oneSidedEqnRowIndices[i]], stack.
localFlux[i] );
1510 for(
integer ic = 0; ic < NC; ++ic )
1513 eqnRowIndices[TAG::NEXT *
numEqn+ic] = stack.offsetNext + WJ_ROFFSET::MASSBAL + ic -
m_rankOffset;
1514 eqnRowIndices[TAG::CURRENT *
numEqn+ic] = stack.offsetCurrent + WJ_ROFFSET::MASSBAL + ic -
m_rankOffset;
1518 globalIndex dofColIndices_dPresCompUp[CP_Deriv::nDer]{};
1519 globalIndex dofColIndices_dRate = stack.offsetCurrent + WJ_COFFSET::dQ;
1523 dofColIndices_dPresCompUp[ioff++] = stack.offsetUp + WJ_COFFSET::dP;
1525 if constexpr ( IS_THERMAL )
1527 dofColIndices_dPresCompUp[ioff++] = stack.offsetUp + WJ_COFFSET::dT;
1529 for(
integer jdof = 0; jdof < NC; ++jdof )
1531 dofColIndices_dPresCompUp[ioff++] = stack.offsetUp + WJ_COFFSET::dC+ jdof;
1535 if( m_useTotalMassEquation > 0 )
1538 real64 work[CP_Deriv::nDer]{};
1544 for(
integer i = 0; i < 2*NC; ++i )
1546 if( eqnRowIndices[i] >= 0 && eqnRowIndices[i] <
m_localMatrix.numRows() )
1548 m_localMatrix.addToRow< parallelDeviceAtomic >( eqnRowIndices[i],
1549 &dofColIndices_dRate,
1552 m_localMatrix.addToRowBinarySearchUnsorted< parallelDeviceAtomic >( eqnRowIndices[i],
1553 dofColIndices_dPresCompUp,
1556 RAJA::atomicAdd( parallelDeviceAtomic{}, &
m_localRhs[eqnRowIndices[i]], stack.
localFlux[i] );
1566 computeExit(
real64 const & dt,
1567 real64 const ( &compFlux )[NC ],
1571 for(
integer ic = 0; ic < NC; ++ic )
1573 stack.localFlux[ic] = -dt * compFlux[ic];
1575 stack.localFluxJacobian_dQ[ic][0] = -dt * dCompFlux[ic][WJ_COFFSET::dQ];
1577 stack.localFluxJacobian[ic][CP_Deriv::dP] = -dt * dCompFlux[ic][WJ_COFFSET::dP];
1579 for(
integer jdof = 0; jdof < NC; ++jdof )
1581 stack.localFluxJacobian[ic][CP_Deriv::dC+jdof] = -dt * dCompFlux[ic][WJ_COFFSET::dC+jdof];
1583 if constexpr ( IS_THERMAL )
1585 stack.localFluxJacobian[ic][CP_Deriv::dT] = -dt * dCompFlux[ic][WJ_COFFSET::dT];
1593 compute(
real64 const & dt,
1594 real64 const ( &compFlux )[NC ],
1599 for(
integer ic = 0; ic < NC; ++ic )
1601 stack.localFlux[TAG::NEXT * NC +ic] = dt * compFlux[ic];
1602 stack.localFlux[TAG::CURRENT * NC +ic] = -dt * compFlux[ic];
1604 stack.localFluxJacobian_dQ[TAG::NEXT * NC+ ic][0] = dt * dCompFlux[ic][WJ_COFFSET::dQ];
1605 stack.localFluxJacobian_dQ[TAG::CURRENT * NC + +ic][0] = -dt * dCompFlux[ic][WJ_COFFSET::dQ];
1608 stack.localFluxJacobian[TAG::NEXT * NC +ic][CP_Deriv::dP] = dt * dCompFlux[ic][WJ_COFFSET::dP];
1609 stack.localFluxJacobian[TAG::CURRENT * NC+ ic][CP_Deriv::dP] = -dt * dCompFlux[ic][WJ_COFFSET::dP];
1611 if constexpr ( IS_THERMAL )
1613 stack.localFluxJacobian[TAG::NEXT * NC +ic][CP_Deriv::dT] = dt * dCompFlux[ic][WJ_COFFSET::dT];
1614 stack.localFluxJacobian[TAG::CURRENT * NC +ic][CP_Deriv::dT] = -dt * dCompFlux[ic][WJ_COFFSET::dT];
1618 for(
integer jdof = 0; jdof < NC; ++jdof )
1620 stack.localFluxJacobian[TAG::NEXT * NC +ic][CP_Deriv::dC+jdof] = dt * dCompFlux[ic][WJ_COFFSET::dC+jdof];
1621 stack.localFluxJacobian[TAG::CURRENT * NC +ic][CP_Deriv::dC+jdof] = -dt * dCompFlux[ic][WJ_COFFSET::dC+jdof];
1633 template<
typename FUNC = NoOpFunc >
1638 FUNC && compFluxKernelOp = NoOpFunc{} )
const
1641 using namespace compositionalMultiphaseUtilities;
1648 for(
integer ic = 0; ic < NC; ++ic )
1650 for(
integer jc = 0; jc < NC; ++jc )
1663 localIndex iwelemNext = m_nextWellElemIndex[iwelem];
1666 if( iwelemNext >= 0 )
1668 if(
m_elemStatus[iwelemNext]==WellElementSubRegion::WellElemStatus::CLOSED )
1674 real64 const currentConnRate = m_connRate[iwelem];
1682 for(
integer ic = 0; ic < NC; ++ic )
1684 compFracUp[ic] = m_injection[ic];
1685 for(
integer jc = 0; jc < NC; ++jc )
1687 dComp[ic][jc] = m_dWellElemCompFrac_dCompDens[iwelemUp][ic][jc];
1689 for(
integer jc = 0; jc < NC; ++jc )
1691 dCompFlux[ic][WJ_COFFSET::dC+jc] = 0.0;
1699 || currentConnRate < 0 )
1705 iwelemUp = iwelemNext;
1709 for(
integer ic = 0; ic < NC; ++ic )
1711 compFracUp[ic] = m_wellElemCompFrac[iwelemUp][ic];
1712 for(
integer jc = 0; jc < NC; ++jc )
1714 dCompFlux[ic][WJ_COFFSET::dC+jc] = m_dWellElemCompFrac_dCompDens[iwelemUp][ic][jc];
1715 dComp[ic][jc] = m_dWellElemCompFrac_dCompDens[iwelemUp][ic][jc];
1722 for(
integer ic = 0; ic < NC; ++ic )
1724 compFlux[ic] = compFracUp[ic] * currentConnRate;
1725 dCompFlux[ic][WJ_COFFSET::dQ] = compFracUp[ic];
1727 dCompFlux[ic][WJ_COFFSET::dP] = 0.0;
1728 if constexpr ( IS_THERMAL )
1730 dCompFlux[ic][WJ_COFFSET::dT] = 0.0;
1732 for(
integer jc = 0; jc < NC; ++jc )
1734 dCompFlux[ic][WJ_COFFSET::dC+jc] = dCompFlux[ic][WJ_COFFSET::dC+jc] * currentConnRate;
1738 stack.offsetUp = m_wellElemDofNumber[iwelemUp];
1739 stack.iwelemUp = iwelemUp;
1740 stack.offsetCurrent = m_wellElemDofNumber[iwelem];
1741 stack.iwelemCurrent= iwelem;
1744 if( iwelemNext < 0 )
1760 stack.offsetNext = m_wellElemDofNumber[iwelemNext];
1762 stack.iwelemNext = iwelemNext;
1763 compFluxKernelOp( iwelemNext, iwelemUp, currentConnRate, dComp );
1774 template<
typename POLICY,
typename KERNEL_TYPE >
1777 KERNEL_TYPE
const & kernelComponent )
1782 typename KERNEL_TYPE::StackVariables stack( 1 );
1783 if( kernelComponent.skipElement( ie ))
1787 kernelComponent.setup( ie, stack );
1788 kernelComponent.computeFlux( ie, stack );
1789 kernelComponent.complete( ie, stack );
1853 template<
typename POLICY >
1858 BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > kernelFlags,
1859 string const dofKey,
1865 isothermalCompositionalMultiphaseBaseKernels::internal::kernelLaunchSelectorCompSwitch( numComps, [&](
auto NC )
1867 integer constexpr NUM_COMP = NC();
1870 kernelType kernel( dt, rankOffset, dofKey, wellControls, subRegion, localMatrix, localRhs, kernelFlags );
1871 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.
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.
GEOS_HOST_DEVICE bool skipElement(localIndex const ei) const
Getter for the element.
arrayView4d< real64 const, constitutive::multifluid::USD_PHASE_COMP > const m_phaseCompFrac_n
Views on the phase component fraction.
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.
arrayView1d< integer const > const m_elemStatus
View on the well status.
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< integer const > const m_elemStatus
View on the well status.
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 time, 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::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.
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.
LvArray::CRSMatrixView< T, COL_INDEX, INDEX_TYPE const, LvArray::ChaiBuffer > CRSMatrixView
Alias for CRS Matrix View.
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.
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.
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.