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.
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.
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.
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)