20 #ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_MULTIPHASEKERNELS_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_MULTIPHASEKERNELS_HPP
23 #include "codingUtilities/Utilities.hpp"
26 #include "common/GEOS_RAJA_Interface.hpp"
27 #include "constitutive/fluid/twophaseimmisciblefluid/TwoPhaseImmiscibleFluid.hpp"
28 #include "constitutive/solid/CoupledSolidBase.hpp"
29 #include "constitutive/fluid/twophaseimmisciblefluid/TwoPhaseImmiscibleFluidFields.hpp"
30 #include "constitutive/capillaryPressure/CapillaryPressureFields.hpp"
31 #include "constitutive/capillaryPressure/CapillaryPressureBase.hpp"
32 #include "constitutive/permeability/PermeabilityBase.hpp"
33 #include "constitutive/permeability/PermeabilityFields.hpp"
34 #include "constitutive/relativePermeability/RelativePermeabilityBase.hpp"
35 #include "constitutive/relativePermeability/RelativePermeabilityFields.hpp"
42 #include "physicsSolvers/fluidFlow/ImmiscibleMultiphaseFlowFields.hpp"
45 #include "physicsSolvers/fluidFlow/kernels/immiscibleMultiphase/KernelLaunchSelectors.hpp"
49 namespace immiscibleMultiphaseKernels
51 using namespace constitutive;
70 template<
typename VIEWTYPE >
77 fields::flow::pressure,
78 fields::flow::gravityCoefficient,
79 fields::immiscibleMultiphaseFlow::phaseVolumeFraction,
80 fields::immiscibleMultiphaseFlow::phaseMobility,
81 fields::immiscibleMultiphaseFlow::dPhaseMobility >;
85 fields::twophaseimmisciblefluid::phaseDensity,
86 fields::twophaseimmisciblefluid::dPhaseDensity >;
90 fields::cappres::phaseCapPressure,
91 fields::cappres::dPhaseCapPressure_dPhaseVolFraction >;
95 fields::permeability::permeability,
96 fields::permeability::dPerm_dPressure >;
117 DofNumberAccessor
const & dofNumberAccessor,
126 integer const useTotalMassEquation,
127 integer const checkPhasePresenceInGravity )
128 : m_numPhases ( numPhases ),
129 m_rankOffset( rankOffset ),
131 m_dofNumber( dofNumberAccessor.toNestedViewConst() ),
132 m_permeability( permeabilityAccessors.get( fields::permeability::permeability {} ) ),
133 m_dPerm_dPres( permeabilityAccessors.get( fields::permeability::dPerm_dPressure {} ) ),
134 m_ghostRank( multiPhaseFlowAccessors.get( fields::ghostRank {} ) ),
135 m_gravCoef( multiPhaseFlowAccessors.get( fields::flow::gravityCoefficient {} ) ),
136 m_pres( multiPhaseFlowAccessors.get( fields::flow::pressure {} ) ),
137 m_phaseVolFrac( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::phaseVolumeFraction {} ) ),
138 m_mob( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::phaseMobility {} ) ),
139 m_dMob( multiPhaseFlowAccessors.get( fields::immiscibleMultiphaseFlow::dPhaseMobility {} ) ),
140 m_dens( fluidAccessors.get( fields::twophaseimmisciblefluid::phaseDensity {} ) ),
141 m_dDens_dPres( fluidAccessors.get( fields::twophaseimmisciblefluid::dPhaseDensity {} ) ),
142 m_phaseCapPressure( capPressureAccessors.get( fields::cappres::phaseCapPressure {} ) ),
143 m_dPhaseCapPressure_dPhaseVolFrac( capPressureAccessors.get( fields::cappres::dPhaseCapPressure_dPhaseVolFraction {} ) ),
144 m_localMatrix( localMatrix ),
145 m_localRhs( localRhs ),
146 m_hasCapPressure ( hasCapPressure ),
147 m_useTotalMassEquation ( useTotalMassEquation ),
148 m_checkPhasePresenceInGravity ( checkPhasePresenceInGravity )
198 integer const m_hasCapPressure;
199 integer const m_useTotalMassEquation;
200 integer const m_checkPhasePresenceInGravity;
211 template<
integer NUM_EQN,
integer NUM_DOF,
typename STENCILWRAPPER >
223 static constexpr
localIndex maxNumElems = STENCILWRAPPER::maxNumPointsInFlux;
226 static constexpr
localIndex maxNumConns = STENCILWRAPPER::maxNumConnections;
229 static constexpr
localIndex maxStencilSize = STENCILWRAPPER::maxStencilSize;
249 STENCILWRAPPER
const & stencilWrapper,
250 DofNumberAccessor
const & dofNumberAccessor,
259 integer const useTotalMassEquation,
260 integer const checkPhasePresenceInGravity )
264 multiPhaseFlowAccessors,
266 capPressureAccessors,
267 permeabilityAccessors,
272 useTotalMassEquation,
273 checkPhasePresenceInGravity ),
274 m_stencilWrapper( stencilWrapper ),
275 m_seri( stencilWrapper.getElementRegionIndices() ),
276 m_sesri( stencilWrapper.getElementSubRegionIndices() ),
277 m_sei( stencilWrapper.getElementIndices() )
295 : stencilSize( size ),
296 numFluxElems( numElems ),
297 dofColIndices( size * numDof ),
298 localFlux( numElems * numEqn ),
299 localFluxJacobian( numElems * numEqn, size * numDof )
313 real64 transmissibility[maxNumConns][2]{};
335 {
return m_sei[iconn].size(); }
344 {
return m_stencilWrapper.numPointsInFlux( iconn ); }
359 globalIndex const offset = m_dofNumber[m_seri( iconn, i )][m_sesri( iconn, i )][m_sei( iconn, i )];
361 for(
integer jdof = 0; jdof < numDof; ++jdof )
375 template<
typename FUNC = NoOpFunc >
379 FUNC && kernelOp = NoOpFunc{} )
const
383 m_stencilWrapper.computeWeights( iconn,
394 for( k[1] = k[0] + 1; k[1] < stack.
numFluxElems; ++k[1] )
397 real64 densMean[numEqn]{};
398 real64 dDensMean_dP[numEqn][2]{};
400 real64 presGrad[numEqn]{};
401 real64 dPresGrad_dP[numEqn][2]{};
403 real64 gravHead[numEqn]{};
404 real64 dGravHead_dP[numEqn][2]{};
407 real64 dCapGrad_dP[numEqn][2]{};
408 real64 dCapGrad_dS[numEqn][2]{};
411 real64 dFlux_dP[numEqn][2]{};
412 real64 dFlux_dS[numEqn][2]{};
414 real64 mobility[numEqn]{};
415 real64 dMob_dP[numEqn][2]{};
416 real64 dMob_dS[numEqn][2]{};
422 localIndex const seri[2] = {m_seri( iconn, k[0] ), m_seri( iconn, k[1] )};
423 localIndex const sesri[2] = {m_sesri( iconn, k[0] ), m_sesri( iconn, k[1] )};
424 localIndex const sei[2] = {m_sei( iconn, k[0] ), m_sei( iconn, k[1] )};
427 for(
integer ip = 0; ip < m_numPhases; ++ip )
431 for(
integer ke = 0; ke < 2; ++ke )
434 bool const phaseExists = (m_phaseVolFrac[seri[ke]][sesri[ke]][sei[ke]][ip] > 0);
435 if( m_checkPhasePresenceInGravity && !phaseExists )
440 real64 const density = m_dens[seri[ke]][sesri[ke]][sei[ke]][0][ip];
441 real64 const dDens_dP = m_dDens_dPres[seri[ke]][sesri[ke]][sei[ke]][0][ip][Deriv::dP];
444 densMean[ip] += density;
445 dDensMean_dP[ip][ke] = dDens_dP;
452 densMean[ip] /= denom;
453 for(
integer ke = 0; ke < 2; ++ke )
455 dDensMean_dP[ip][ke] /= denom;
463 real64 dPresGrad_dTrans = 0.0;
464 real64 dGravHead_dTrans = 0.0;
465 real64 dCapGrad_dTrans = 0.0;
466 constexpr
int signPotDiff[2] = {1, -1};
468 for(
integer ke = 0; ke < 2; ++ke )
474 real64 const pressure = m_pres[er][esr][ei];
475 presGrad[ip] += trans[ke] * pressure;
476 dPresGrad_dTrans += signPotDiff[ke] * pressure;
477 dPresGrad_dP[ip][ke] = trans[ke];
479 real64 const gravD = trans[ke] * m_gravCoef[er][esr][ei];
480 real64 pot = trans[ke] * pressure - densMean[ip] * gravD;
482 gravHead[ip] += densMean[ip] * gravD;
483 dGravHead_dTrans += signPotDiff[ke] * densMean[ip] * m_gravCoef[er][esr][ei];
485 for(
integer i = 0; i < 2; ++i )
487 dGravHead_dP[ip][i] += dDensMean_dP[ip][i] * gravD;
490 if( m_hasCapPressure )
492 real64 const capPres = m_phaseCapPressure[er][esr][ei][0][ip];
493 dCapGrad_dTrans -= signPotDiff[ke] * capPres;
494 pot -= trans[ke] * capPres;
496 capGrad[ip] -= trans[ke] * capPres;
499 potScale = fmax( potScale, fabs( pot ) );
502 for(
integer ke = 0; ke < 2; ++ke )
504 dPresGrad_dP[ip][ke] += dTrans_dP[ke] * dPresGrad_dTrans;
505 dGravHead_dP[ip][ke] += dTrans_dP[ke] * dGravHead_dTrans;
507 if( m_hasCapPressure )
509 real64 const dCapPres_dS = m_dPhaseCapPressure_dPhaseVolFrac[seri[ke]][sesri[ke]][sei[ke]][0][ip][ip];
511 dCapGrad_dP[ip][ke] += dTrans_dP[ke] * dCapGrad_dTrans;
515 dCapGrad_dS[ip][ke] -= trans[ke] * dCapPres_dS;
524 real64 potGrad = presGrad[ip] - gravHead[ip];
525 if( m_hasCapPressure )
527 potGrad += capGrad[ip];
531 real64 constexpr upwRelTol = 1e-8;
532 real64 const upwAbsTol = fmax( potScale * upwRelTol, LvArray::NumericLimits< real64 >::epsilon );
536 real64 const alpha = ( potGrad + upwAbsTol ) / ( 2 * upwAbsTol );
539 if( alpha <= 0.0 || alpha >= 1.0 )
543 mobility[ip] = m_mob[seri[k_up]][sesri[k_up]][sei[k_up]][ip];
544 dMob_dP[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dP];
545 dMob_dS[ip][k_up] = m_dMob[seri[k_up]][sesri[k_up]][sei[k_up]][ip][Deriv::dS];
549 real64 const mobWeights[2] = { alpha, 1.0 - alpha };
550 for(
integer ke = 0; ke < 2; ++ke )
552 mobility[ip] += mobWeights[ke] * m_mob[seri[ke]][sesri[ke]][sei[ke]][ip];
553 dMob_dP[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dP];
555 dMob_dS[ip][ke] = mobWeights[ke] * m_dMob[seri[ke]][sesri[ke]][sei[ke]][ip][Deriv::dS];
561 for(
integer ke = 0; ke < 2; ++ke )
563 dFlux_dP[ip][ke] += dPresGrad_dP[ip][ke];
568 for(
integer ke = 0; ke < 2; ++ke )
570 dFlux_dP[ip][ke] -= dGravHead_dP[ip][ke];
577 if( m_hasCapPressure )
579 for(
integer ke = 0; ke < 2; ++ke )
581 dFlux_dP[ip][ke] += dCapGrad_dP[ip][ke];
586 dFlux_dS[ip][ke] += dCapGrad_dS[ip][ke];
591 fluxVal[ip] = mobility[ip] * potGrad;
593 for(
integer ke = 0; ke < 2; ++ke )
595 dFlux_dP[ip][ke] *= mobility[ip];
600 dFlux_dS[ip][ke] *= mobility[ip];
604 for(
integer ke = 0; ke < 2; ++ke )
606 dFlux_dP[ip][ke] += dMob_dP[ip][ke] * potGrad;
611 dFlux_dS[ip][ke] += dMob_dS[ip][ke] * potGrad;
616 stack.
localFlux[k[0]*numEqn + ip] += m_dt * fluxVal[ip];
617 stack.
localFlux[k[1]*numEqn + ip] -= m_dt * fluxVal[ip];
619 for(
integer ke = 0; ke < 2; ++ke )
622 localIndex const localDofIndexPres = k[ke] * numDof;
623 stack.
localFluxJacobian[k[0]*numEqn + ip][localDofIndexPres] += m_dt * dFlux_dP[ip][ke];
624 stack.
localFluxJacobian[k[1]*numEqn + ip][localDofIndexPres] -= m_dt * dFlux_dP[ip][ke];
627 localIndex const localDofIndexSat = k[ke] * numDof + 1;
628 stack.
localFluxJacobian[k[0]*numEqn + ip][localDofIndexSat] += m_dt * dFlux_dS[ip][ke];
629 stack.
localFluxJacobian[k[1]*numEqn + ip][localDofIndexSat] -= m_dt * dFlux_dS[ip][ke];
633 kernelOp( k, seri, sesri, sei, connectionIndex, alpha, mobility, potGrad, fluxVal, dFlux_dP, dFlux_dS );
648 template<
typename FUNC = NoOpFunc >
652 FUNC && kernelOp = NoOpFunc{} )
const
654 using namespace compositionalMultiphaseUtilities;
656 if( m_useTotalMassEquation )
660 shiftBlockRowsAheadByOneAndReplaceFirstRowWithColumnSum( m_numPhases, numEqn, numDof * stack.
stencilSize, stack.
numFluxElems,
662 shiftBlockElementsAheadByOneAndReplaceFirstElementWithSum( m_numPhases, numEqn, stack.
numFluxElems,
671 if( m_ghostRank[m_seri( iconn, i )][m_sesri( iconn, i )][m_sei( iconn, i )] < 0 )
673 globalIndex const globalRow = m_dofNumber[m_seri( iconn, i )][m_sesri( iconn, i )][m_sei( iconn, i )];
674 localIndex const localRow = LvArray::integerConversion< localIndex >( globalRow - m_rankOffset );
679 for(
integer ic = 0; ic < numEqn; ++ic )
681 RAJA::atomicAdd( parallelDeviceAtomic{}, &m_localRhs[localRow + ic],
683 m_localMatrix.addToRowBinarySearchUnsorted< parallelDeviceAtomic >
691 kernelOp( i, localRow );
703 template<
typename POLICY,
typename KERNEL_TYPE >
706 KERNEL_TYPE
const & kernelComponent )
712 typename KERNEL_TYPE::StackVariables stack( kernelComponent.stencilSize( iconn ),
713 kernelComponent.numPointsInFlux( iconn ) );
715 kernelComponent.setup( iconn, stack );
716 kernelComponent.computeFlux( iconn, stack );
717 kernelComponent.complete( iconn, stack );
729 typename STENCILWRAPPER::IndexContainerViewConstType
const m_seri;
730 typename STENCILWRAPPER::IndexContainerViewConstType
const m_sesri;
731 typename STENCILWRAPPER::IndexContainerViewConstType
const m_sei;
757 template<
typename POLICY,
typename STENCILWRAPPER >
761 string const & dofKey,
763 integer const useTotalMassEquation,
764 integer const checkPhasePresenceInGravity,
765 string const & solverName,
767 STENCILWRAPPER
const & stencilWrapper,
777 dofNumberAccessor.setName( solverName +
"/accessors/" + dofKey );
780 typename kernelType::ImmiscibleMultiphaseFlowAccessors flowAccessors( elemManager, solverName );
781 typename kernelType::MultiphaseFluidAccessors fluidAccessors( elemManager, solverName );
782 typename kernelType::CapPressureAccessors capPressureAccessors( elemManager, solverName );
783 typename kernelType::PermeabilityAccessors permAccessors( elemManager, solverName );
785 kernelType kernel( numPhases, rankOffset, stencilWrapper, dofNumberAccessor,
786 flowAccessors, fluidAccessors, capPressureAccessors, permAccessors,
787 dt, localMatrix, localRhs, hasCapPressure, useTotalMassEquation,
788 checkPhasePresenceInGravity );
789 kernelType::template launch< POLICY >( stencilWrapper.size(), kernel );
796 enum class KernelFlags
798 TotalMassEquation = 1 << 0,
816 template<
integer NUM_EQN,
integer NUM_DOF >
846 constitutive::TwoPhaseImmiscibleFluid
const & fluid,
847 constitutive::CoupledSolidBase
const & solid,
850 BitFlags< KernelFlags >
const kernelFlags )
851 : m_numPhases( numPhases ),
852 m_rankOffset( rankOffset ),
854 m_elemGhostRank( subRegion.ghostRank() ),
855 m_volume( subRegion.getElementVolume() ),
856 m_porosity( solid.getPorosity() ),
857 m_dPoro_dPres( solid.getDporosity_dPressure() ),
858 m_phaseVolFrac( subRegion.getField< fields::immiscibleMultiphaseFlow::phaseVolumeFraction >() ),
859 m_phaseDens( fluid.phaseDensity() ),
860 m_dPhaseDens( fluid.dPhaseDensity() ),
861 m_phaseMass_n( subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass_n >() ),
862 m_localMatrix( localMatrix ),
863 m_localRhs( localRhs ),
864 m_kernelFlags( kernelFlags )
906 {
return m_elemGhostRank( ei ); }
919 stack.
poreVolume = m_volume[ei] * m_porosity[ei][0];
923 stack.
localRow = m_dofNumber[ei] - m_rankOffset;
924 for(
integer idof = 0; idof < numDof; ++idof )
926 stack.
dofIndices[idof] = m_dofNumber[ei] + idof;
939 constexpr
int sign[2] = {1, -1};
942 for(
integer ip = 0; ip < m_numPhases; ++ip )
944 real64 const phaseMass = stack.
poreVolume * m_phaseVolFrac[ei][ip] * m_phaseDens[ei][0][ip];
945 real64 const phaseMass_n = m_phaseMass_n[ei][ip];
950 + stack.
poreVolume * m_phaseVolFrac[ei][ip] * m_dPhaseDens[ei][0][ip][0];
967 using namespace compositionalMultiphaseUtilities;
969 if( m_kernelFlags.isSet( KernelFlags::TotalMassEquation ) )
973 shiftRowsAheadByOneAndReplaceFirstRowWithColumnSum( m_numPhases, numDof, stack.
localJacobian, work );
974 shiftElementsAheadByOneAndReplaceFirstElementWithSum( m_numPhases, stack.
localResidual );
980 integer const numRows = m_numPhases;
981 for(
integer i = 0; i < numRows; ++i )
984 m_localMatrix.addToRow< serialAtomic >( stack.
localRow + i,
998 template<
typename POLICY,
typename KERNEL_TYPE >
1001 KERNEL_TYPE
const & kernelComponent )
1007 if( kernelComponent.elemGhostRank( ei ) >= 0 )
1012 typename KERNEL_TYPE::StackVariables stack;
1014 kernelComponent.setup( ei, stack );
1015 kernelComponent.computeAccumulation( ei, stack );
1016 kernelComponent.complete( ei, stack );
1053 BitFlags< KernelFlags >
const m_kernelFlags;
1076 template<
typename POLICY >
1080 integer const useTotalMassEquation,
1081 string const dofKey,
1083 constitutive::TwoPhaseImmiscibleFluid
const & fluid,
1084 constitutive::CoupledSolidBase
const & solid,
1089 geos::immiscibleMultiphaseKernels::kernelLaunchSelectorPhaseSwitch( numPhases, [&] (
auto NP )
1091 integer constexpr NUM_EQN = NP();
1092 integer constexpr NUM_DOF = NP();
1094 BitFlags< KernelFlags > kernelFlags;
1095 if( useTotalMassEquation )
1096 kernelFlags.set( KernelFlags::TotalMassEquation );
1099 fluid, solid, localMatrix, localRhs, kernelFlags );
1115 template<
integer NUM_PHASE >
1132 TwoPhaseImmiscibleFluid
const & fluid,
1133 RelativePermeabilityBase
const & relperm )
1135 m_phaseDens( fluid.phaseDensity() ),
1136 m_dPhaseDens( fluid.dPhaseDensity() ),
1137 m_phaseVisc( fluid.phaseViscosity() ),
1138 m_dPhaseVisc( fluid.dPhaseViscosity() ),
1139 m_phaseRelPerm( relperm.phaseRelPerm() ),
1140 m_dPhaseRelPerm_dPhaseVolFrac( relperm.dPhaseRelPerm_dPhaseVolFraction() ),
1141 m_phaseMob( subRegion.getField< fields::immiscibleMultiphaseFlow::phaseMobility >() ),
1142 m_dPhaseMob( subRegion.getField< fields::immiscibleMultiphaseFlow::dPhaseMobility >() )
1152 template<
typename POLICY,
typename KERNEL_TYPE >
1155 KERNEL_TYPE
const & kernelComponent )
1159 kernelComponent.compute( ei );
1169 template<
typename FUNC = NoOpFunc >
1172 FUNC && phaseMobilityKernelOp = NoOpFunc{} )
const
1176 arraySlice1d<
real64, immiscibleFlow::USD_PHASE - 1 >
const phaseMob = m_phaseMob[ei];
1177 arraySlice2d<
real64, immiscibleFlow::USD_PHASE_DS - 1 >
const dPhaseMob = m_dPhaseMob[ei];
1178 constexpr
int sign[2] = {1, -1};
1180 for(
integer ip = 0; ip < numPhase; ++ip )
1182 real64 const density = m_phaseDens[ei][0][ip];
1183 real64 const dDens_dP = m_dPhaseDens[ei][0][ip][Deriv::dP];
1184 real64 const viscosity = m_phaseVisc[ei][0][ip];
1185 real64 const dVisc_dP = m_dPhaseVisc[ei][0][ip][Deriv::dP];
1187 real64 const relPerm = m_phaseRelPerm[ei][0][ip];
1189 real64 const mobility = relPerm * density / viscosity;
1191 phaseMob[ip] = mobility;
1192 dPhaseMob[ip][Deriv::dP] = mobility * (dDens_dP / density - dVisc_dP / viscosity);
1197 real64 const dRelPerm_dS = sign[ip] * m_dPhaseRelPerm_dPhaseVolFrac[ei][0][ip][ip];
1198 dPhaseMob[ip][Deriv::dS] = dRelPerm_dS * density / viscosity;
1204 phaseMobilityKernelOp( ip, phaseMob[ip], dPhaseMob[ip] );
1250 template<
typename POLICY >
1254 TwoPhaseImmiscibleFluid
const & fluid,
1255 RelativePermeabilityBase
const & relperm )
1268 template<
typename POLICY,
typename FLUID_WRAPPER >
1271 FLUID_WRAPPER
const & fluidWrapper,
1276 for(
localIndex q = 0; q < fluidWrapper.numGauss(); ++q )
1278 fluidWrapper.update( k, q, pres[k] );
1301 using Base::m_minNormalizer;
1302 using Base::m_rankOffset;
1303 using Base::m_localResidual;
1304 using Base::m_dofNumber;
1312 constitutive::CoupledSolidBase
const & solid,
1313 real64 const minNormalizer )
1319 m_numPhases( numPhases ),
1321 m_porosity_n( solid.getPorosity_n() ),
1322 m_phaseMass_n( subRegion.template getField< fields::immiscibleMultiphaseFlow::phaseMass_n >() )
1327 LinfStackVariables & stack )
const override
1329 real64 massNormalizer = 0;
1330 for(
integer idof = 0; idof < m_numPhases; ++idof )
1332 massNormalizer += LvArray::math::max( m_minNormalizer, m_phaseMass_n[ei][idof] );
1335 for(
integer idof = 0; idof < m_numPhases; ++idof )
1337 real64 const valMass = LvArray::math::abs( m_localResidual[stack.localRow + idof] ) / massNormalizer;
1338 if( valMass > stack.localValue[0] )
1340 stack.localValue[0] = valMass;
1358 L2StackVariables & stack )
const override
1360 for(
integer idof = 0; idof < m_numPhases; ++idof )
1362 real64 const massNormalizer = LvArray::math::max( m_minNormalizer, m_phaseMass_n[ei][idof] );
1363 stack.localValue[0] += m_localResidual[stack.localRow + idof] * m_localResidual[stack.localRow + idof];
1364 stack.localNormalizer[0] += massNormalizer;
1403 template<
typename POLICY >
1408 string const dofKey,
1411 constitutive::CoupledSolidBase
const & solid,
1412 real64 const minNormalizer,
1413 real64 (& residualNorm)[1],
1414 real64 (& residualNormalizer)[1] )
1419 ResidualNormKernel kernel( rankOffset, localResidual, dofNumber, ghostRank, numPhases, subRegion, solid, minNormalizer );
1420 if( normType == physicsSolverBaseKernels::NormType::Linf )
1422 ResidualNormKernel::launchLinf< POLICY >( subRegion.
size(), kernel, residualNorm );
1426 ResidualNormKernel::launchL2< POLICY >( subRegion.
size(), kernel, residualNorm, residualNormalizer );
#define GEOS_HOST_DEVICE
Marks a host-device function.
#define GEOS_UNUSED_PARAM(X)
Mark an unused argument and silence compiler warnings.
static constexpr integer numNorm
Compile time value for the number of norms to compute.
#define GEOS_ASSERT_GT(lhs, rhs)
Assert that one value compares greater than the other in debug builds.
#define GEOS_ASSERT_GE(lhs, rhs)
Assert that one value compares greater than or equal to the other in debug builds.
NormType
Type of norm used to check convergence TODO: find a way to put this inside the class.
#define GEOS_MARK_FUNCTION
Mark function with both Caliper and NVTX if enabled.
The ElementRegionManager class provides an interface to ObjectManagerBase in order to manage ElementR...
ElementViewAccessor< ArrayView< T const, NDIM, getUSD< PERM > > > constructArrayViewAccessor(string const &name, string const &neighborName=string()) const
This is a function to construct a ElementViewAccessor to access array data registered on the mesh.
array1d< array1d< VIEWTYPE > > ElementViewAccessor
The ElementViewAccessor at the ElementRegionManager level is an array of array of VIEWTYPE.
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.
A struct to automatically construct and store element view accessors.
A struct to automatically construct and store element view accessors.
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.
static void createAndLaunch(integer const numPhases, globalIndex const rankOffset, integer const useTotalMassEquation, string const dofKey, ElementSubRegionBase const &subRegion, constitutive::TwoPhaseImmiscibleFluid const &fluid, constitutive::CoupledSolidBase const &solid, 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.
GEOS_HOST_DEVICE void complete(localIndex const GEOS_UNUSED_PARAM(ei), StackVariables &stack) const
Performs the complete phase for the kernel.
arrayView1d< real64 const > const m_volume
View on the element volumes.
AccumulationKernel(localIndex const numPhases, globalIndex const rankOffset, string const dofKey, ElementSubRegionBase const &subRegion, constitutive::TwoPhaseImmiscibleFluid const &fluid, constitutive::CoupledSolidBase const &solid, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs, BitFlags< KernelFlags > const kernelFlags)
Constructor.
static void launch(localIndex const numElems, KERNEL_TYPE const &kernelComponent)
Performs the kernel launch.
integer const m_numPhases
Number of fluid phases.
arrayView1d< globalIndex const > const m_dofNumber
View on the dof numbers.
globalIndex const m_rankOffset
Offset for my MPI rank.
arrayView1d< integer const > const m_elemGhostRank
View on the ghost ranks.
arrayView2d< real64 const > const m_porosity
Views on the porosity.
arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const m_phaseVolFrac
Views on the phase volume fractions.
CRSMatrixView< real64, globalIndex const > const m_localMatrix
View on the local CRS matrix.
GEOS_HOST_DEVICE integer elemGhostRank(localIndex const ei) const
Getter for the ghost rank of an element.
arrayView1d< real64 > const m_localRhs
View on the local RHS.
arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > const m_phaseDens
Views on the phase densities.
GEOS_HOST_DEVICE void computeAccumulation(localIndex const ei, StackVariables &stack) const
Compute the local accumulation contributions to the residual and Jacobian.
GEOS_HOST_DEVICE void setup(localIndex const ei, StackVariables &stack) const
Performs the setup phase for the kernel.
Base class for FluxComputeKernel that holds all data not dependent on template parameters (like stenc...
ElementViewConst< arrayView3d< real64 const > > m_permeability
Views on permeability.
FluxComputeKernelBase(integer const numPhases, globalIndex const rankOffset, DofNumberAccessor const &dofNumberAccessor, ImmiscibleMultiphaseFlowAccessors const &multiPhaseFlowAccessors, MultiphaseFluidAccessors const &fluidAccessors, CapPressureAccessors const &capPressureAccessors, PermeabilityAccessors const &permeabilityAccessors, real64 const &dt, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs, integer const hasCapPressure, integer const useTotalMassEquation, integer const checkPhasePresenceInGravity)
Constructor for the kernel interface.
ElementViewConst< arrayView1d< integer const > > const m_ghostRank
Views on ghost rank numbers and gravity coefficients.
ElementRegionManager::ElementViewConst< VIEWTYPE > ElementViewConst
The type for element-based data. Consists entirely of ArrayView's.
ElementViewConst< arrayView1d< real64 const > > const m_pres
Views on pressure and phase volume fraction.
ElementViewConst< arrayView2d< real64 const, immiscibleFlow::USD_PHASE > > const m_mob
Views on fluid mobility.
ElementViewConst< arrayView1d< globalIndex const > > const m_dofNumber
Views on dof numbers.
real64 const m_dt
Time step size.
globalIndex const m_rankOffset
Offset for my MPI rank.
integer const m_numPhases
Number of fluid phases.
arrayView1d< real64 > const m_localRhs
View on the local RHS.
CRSMatrixView< real64, globalIndex const > const m_localMatrix
View on the local CRS matrix.
ElementViewConst< arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > > const m_dens
Views on fluid density.
ElementViewConst< arrayView3d< real64 const, cappres::USD_CAPPRES > > const m_phaseCapPressure
Views on capillary pressure.
static void createAndLaunch(integer const numPhases, globalIndex const rankOffset, string const &dofKey, integer const hasCapPressure, integer const useTotalMassEquation, integer const checkPhasePresenceInGravity, string const &solverName, ElementRegionManager const &elemManager, STENCILWRAPPER const &stencilWrapper, real64 const &dt, 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.
GEOS_HOST_DEVICE void complete(localIndex const iconn, StackVariables &stack, FUNC &&kernelOp=NoOpFunc{}) const
Performs the complete phase for the kernel.
GEOS_HOST_DEVICE void computeFlux(localIndex const iconn, StackVariables &stack, FUNC &&kernelOp=NoOpFunc{}) const
Compute the local flux contributions to the residual and Jacobian.
STENCILWRAPPER const m_stencilWrapper
Reference to the stencil wrapper.
static void launch(localIndex const numConnections, KERNEL_TYPE const &kernelComponent)
Performs the kernel launch.
GEOS_HOST_DEVICE localIndex numPointsInFlux(localIndex const iconn) const
Getter for the number of elements at this connection.
FluxComputeKernel(integer const numPhases, globalIndex const rankOffset, STENCILWRAPPER const &stencilWrapper, DofNumberAccessor const &dofNumberAccessor, ImmiscibleMultiphaseFlowAccessors const &multiPhaseFlowAccessors, MultiphaseFluidAccessors const &fluidAccessors, CapPressureAccessors const &capPressureAccessors, PermeabilityAccessors const &permeabilityAccessors, real64 const &dt, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs, integer const hasCapPressure, integer const useTotalMassEquation, integer const checkPhasePresenceInGravity)
Constructor for the kernel interface.
GEOS_HOST_DEVICE localIndex stencilSize(localIndex const iconn) const
Getter for the stencil size at this connection.
GEOS_HOST_DEVICE void setup(localIndex const iconn, StackVariables &stack) const
Performs the setup phase for the kernel.
STENCILWRAPPER::IndexContainerViewConstType const m_seri
Connection to element maps.
static void createAndLaunch(integer const numPhase, ObjectManagerBase &subRegion, TwoPhaseImmiscibleFluid const &fluid, RelativePermeabilityBase const &relperm)
Create a new kernel and launch.
Define the interface for the property kernel in charge of computing the phase mobilities.
arrayView3d< real64 const, relperm::USD_RELPERM > m_phaseRelPerm
Views on the phase relative permeabilities.
PhaseMobilityKernel(ObjectManagerBase &subRegion, TwoPhaseImmiscibleFluid const &fluid, RelativePermeabilityBase const &relperm)
Constructor.
arrayView2d< real64, immiscibleFlow::USD_PHASE > m_phaseMob
Views on the phase mobilities.
arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > m_phaseVisc
Views on the phase viscosities.
GEOS_HOST_DEVICE void compute(localIndex const ei, FUNC &&phaseMobilityKernelOp=NoOpFunc{}) const
Compute the phase mobilities in an element.
arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > m_phaseDens
Views on the phase densities.
static void launch(localIndex const numElems, KERNEL_TYPE const &kernelComponent)
Performs the kernel launch.
static void createAndLaunch(physicsSolverBaseKernels::NormType const normType, integer const numPhases, globalIndex const rankOffset, string const dofKey, arrayView1d< real64 const > const &localResidual, ElementSubRegionBase const &subRegion, constitutive::CoupledSolidBase const &solid, real64 const minNormalizer, real64(&residualNorm)[1], real64(&residualNormalizer)[1])
Create a new kernel and launch.
Define the interface for the property kernel in charge of computing the residual norm.
arrayView1d< real64 const > const m_volume
View on the volume.
integer const m_numPhases
Number of fluid phases.
virtual GEOS_HOST_DEVICE void computeLinf(localIndex const ei, LinfStackVariables &stack) const override
Compute the local values for the Linf norm.
virtual GEOS_HOST_DEVICE void computeL2(localIndex const ei, L2StackVariables &stack) const override
Compute the local values and normalizer for the L2 norm.
arrayView2d< real64 const, immiscibleFlow::USD_PHASE > const m_phaseMass_n
View on mass at the previous converged time step.
arrayView2d< real64 const > const m_porosity_n
View on porosity at the previous converged time step.
Define the base interface for the residual calculations.
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.
Trait struct for ghostRank data.
indices of pressure and saturation derivatives
Kernel variables (dof numbers, jacobian and residual) located on the stack.
real64 dPoreVolume_dPres
Derivative of pore volume with respect to pressure.
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 poreVolume
Pore volume at time n+1.
real64 localResidual[numEqn]
C-array storage for the element local residual vector (all equations except volume balance)
real64 localJacobian[numEqn][numDof]
C-array storage for the element local Jacobian matrix (all equations except volume balance,...
Kernel variables (dof numbers, jacobian and residual) located on the stack.
localIndex const stencilSize
Stencil size for a given connection.
real64 transmissibility[maxNumConns][2]
Transmissibility.
GEOS_HOST_DEVICE StackVariables(localIndex const size, localIndex numElems)
Constructor for the stack variables.
stackArray2d< real64, maxNumElems *numEqn *maxStencilSize *numDof > localFluxJacobian
Storage for the face local Jacobian matrix.
localIndex const numFluxElems
Number of elements for a given connection.
stackArray1d< globalIndex, maxNumElems *numDof > dofColIndices
Indices of the matrix rows/columns corresponding to the dofs in this face.
real64 dTrans_dPres[maxNumConns][2]
Derivatives of transmissibility with respect to pressure.
stackArray1d< real64, maxNumElems *numEqn > localFlux
Storage for the face local residual vector (all equations except volume balance)