20 #ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_WELLS_THERMALSINGLEPHASEWELLKERNELS_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_WELLS_THERMALSINGLEPHASEWELLKERNELS_HPP
23 #include "constitutive/fluid/singlefluid/SingleFluidFields.hpp"
24 #include "constitutive/fluid/singlefluid/SingleFluidBase.hpp"
26 #include "common/GEOS_RAJA_Interface.hpp"
30 #include "physicsSolvers/fluidFlow/wells/WellControls.hpp"
36 namespace thermalSinglePhaseWellKernels
48 template<
integer IS_THERMAL >
54 using FLUID_PROP_COFFSET = constitutive::singlefluid::DerivativeOffsetC< IS_THERMAL >;
64 using Base::m_wellElemDensity_n;
65 using Base::m_dWellElemDensity;
83 constitutive::SingleFluidBase
const & fluid,
86 :
Base( rankOffset, dofKey, subRegion, fluid, localMatrix, localRhs ),
90 m_internalEnergy_n( fluid.internalEnergy_n() ),
91 m_dInternalEnergy( fluid.dInternalEnergy() )
114 template<
typename FUNC = NoOpFunc >
123 real64 localEnergyAccumDP;
124 real64 localEnergyAccumDT;
131 localEnergyAccum = 0.0;
132 localEnergyAccumDT = 1.0;
133 localEnergyAccumDP = 0.0;
139 m_wellElemDensity[iwelem][0]*m_dInternalEnergy[iwelem][0][FLUID_PROP_COFFSET::dP]);
141 m_wellElemDensity[iwelem][0]*m_dInternalEnergy[iwelem][0][FLUID_PROP_COFFSET::dT]);
144 m_localMatrix.template addToRow< serialAtomic >( eqnRowIndex, &presDofColIndex, &localEnergyAccumDP, 1 );
145 m_localMatrix.template addToRow< serialAtomic >( eqnRowIndex, &tempDofColIndex, &localEnergyAccumDT, 1 );
159 template<
typename POLICY,
typename KERNEL_TYPE >
162 KERNEL_TYPE
const & kernelComponent )
168 if( kernelComponent.elemGhostRank( iwelem ) >= 0 )
172 kernelComponent.computeAccumulation( iwelem );
206 template<
typename POLICY >
212 constitutive::SingleFluidBase
const & fluid,
216 integer constexpr isThermal = 1;
218 kernel( isProducer, rankOffset, dofKey, subRegion, fluid, localMatrix, localRhs );
220 launch< POLICY, ElementBasedAssemblyKernel< isThermal > >( subRegion.
size(), kernel );
232 template<
integer IS_THERMAL >
241 using FLUID_PROP_COFFSET = constitutive::singlefluid::DerivativeOffsetC< IS_THERMAL >;
253 using Base::maxNumElems;
254 using Base::maxStencilSize;
276 string const wellDofKey,
279 constitutive::SingleFluidBase
const & fluid,
292 m_dEnthalpy( fluid.dEnthalpy())
308 ,
real64 const & currentConnRate )
314 if( dofRowIndices >= 0 && dofRowIndices <
m_localMatrix.numRows() )
316 globalIndex dofColIndices_dRate = m_wellElemDofNumber[iwelem] + WJ_COFFSET::dQ;
317 globalIndex dofColIndices[FLUID_PROP_COFFSET::nDer]{};
321 real64 localEnergyFlux[1]{};
322 real64 localEnergyFluxJacobian_dQ[1]{};
326 localEnergyFlux[0]= eflux * currentConnRate;
328 localEnergyFluxJacobian[FLUID_PROP_COFFSET::dP] = -
m_dt * currentConnRate * m_dEnthalpy[iwelem][0][FLUID_PROP_COFFSET::dP];
329 localEnergyFluxJacobian[FLUID_PROP_COFFSET::dT] = -
m_dt * currentConnRate * m_dEnthalpy[iwelem][0][FLUID_PROP_COFFSET::dT];
332 localEnergyFlux[0]= 0.0;
333 localEnergyFluxJacobian_dQ[0] = 0.0;
334 localEnergyFluxJacobian[FLUID_PROP_COFFSET::dP] = 0.0;
335 localEnergyFluxJacobian[FLUID_PROP_COFFSET::dT] = 0.0;
338 m_localMatrix.template addToRow< parallelDeviceAtomic >( dofRowIndices,
339 &dofColIndices_dRate,
340 localEnergyFluxJacobian_dQ,
342 m_localMatrix.template addToRowBinarySearchUnsorted< parallelDeviceAtomic >( dofRowIndices,
344 localEnergyFluxJacobian,
345 FLUID_PROP_COFFSET::nDer );
346 RAJA::atomicAdd( parallelDeviceAtomic{}, &
m_localRhs[dofRowIndices], localEnergyFlux[0] );
357 eqnRowIndices[TAG::CURRENT ] = row_current;
358 eqnRowIndices[TAG::NEXT ] = row_next;
361 globalIndex dofColIndices[FLUID_PROP_COFFSET::nDer]{};
367 real64 localEnergyFlux[2]{};
368 real64 localEnergyFluxJacobian_dQ[2][1]{};
373 real64 dprop_dp =
m_dt * currentConnRate *m_dEnthalpy[iwelem][0][FLUID_PROP_COFFSET::dP];
374 real64 dprop_dt =
m_dt * currentConnRate * m_dEnthalpy[iwelem][0][FLUID_PROP_COFFSET::dT];
378 localEnergyFlux[TAG::NEXT ] = 0.0;
379 localEnergyFluxJacobian_dQ [TAG::NEXT ][0] = 0.0;
380 localEnergyFluxJacobian[TAG::NEXT ][FLUID_PROP_COFFSET::dP] = 0.0;
381 localEnergyFluxJacobian[TAG::NEXT][FLUID_PROP_COFFSET::dT] = 0.0;
385 localEnergyFlux[TAG::NEXT ] = eflux * currentConnRate;
386 localEnergyFluxJacobian_dQ [TAG::NEXT ][0] = eflux_dq;
387 localEnergyFluxJacobian[TAG::NEXT ][FLUID_PROP_COFFSET::dP] = dprop_dp;
388 localEnergyFluxJacobian[TAG::NEXT][FLUID_PROP_COFFSET::dT] = dprop_dt;
390 localEnergyFlux[TAG::CURRENT ] = -eflux * currentConnRate;
391 localEnergyFluxJacobian_dQ [TAG::CURRENT][0] = -eflux_dq;
392 localEnergyFluxJacobian[TAG::CURRENT][FLUID_PROP_COFFSET::dP] = -dprop_dp;
393 localEnergyFluxJacobian[TAG::CURRENT][FLUID_PROP_COFFSET::dT] = -dprop_dt;
396 for(
integer i = 0; i < 2; ++i )
398 if( eqnRowIndices[i] >= 0 && eqnRowIndices[i] <
m_localMatrix.numRows() )
400 m_localMatrix.template addToRow< parallelDeviceAtomic >( eqnRowIndices[i],
401 &dofColIndices_dRate,
402 localEnergyFluxJacobian_dQ[i],
404 m_localMatrix.template addToRowBinarySearchUnsorted< parallelDeviceAtomic >( eqnRowIndices[i],
406 localEnergyFluxJacobian[i],
407 FLUID_PROP_COFFSET::nDer );
408 RAJA::atomicAdd( parallelDeviceAtomic{}, &
m_localRhs[eqnRowIndices[i]], localEnergyFlux[i] );
426 template<
typename POLICY,
typename KERNEL_TYPE >
429 KERNEL_TYPE
const & kernelComponent )
434 kernelComponent.computeFlux( ie );
467 template<
typename POLICY >
475 constitutive::SingleFluidBase
const & fluid,
481 kernelType kernel( dt, rankOffset, dofKey, wellControls, subRegion, fluid, localMatrix, localRhs );
482 kernelType::template launch< POLICY >( subRegion.
size(), kernel );
500 using Base::m_minNormalizer;
501 using Base::m_rankOffset;
502 using Base::m_localResidual;
503 using Base::m_dofNumber;
510 constitutive::SingleFluidBase
const & fluid,
514 real64 const minNormalizer )
524 m_currentControl( wellControls.
getControl() ),
529 m_density_n( fluid.density_n() ),
531 m_internalEnergy_n( fluid.internalEnergy_n() )
536 void computeMassEnergyNormalizers(
localIndex const iwelem,
538 real64 & energyNormalizer )
const
540 massNormalizer = LvArray::math::max( m_minNormalizer, m_density_n[iwelem][0] * m_volume[iwelem] );
541 energyNormalizer = m_internalEnergy_n[iwelem][0] * m_density_n[iwelem][0] * m_volume[iwelem];
544 energyNormalizer = LvArray::math::max( m_minNormalizer, LvArray::math::abs( energyNormalizer ) );
549 LinfStackVariables & stack )
const override
552 for(
integer idof = 0; idof < WJ_ROFFSET::nEqn; ++idof )
557 if( idof == WJ_ROFFSET::CONTROL )
561 if( m_isLocallyOwned && iwelem == m_iwelemControl )
563 if( m_currentControl == WellControls::Control::BHP )
566 normalizer = m_targetBHP;
568 else if( m_currentControl == WellControls::Control::TOTALVOLRATE )
571 normalizer = LvArray::math::max( LvArray::math::abs( m_targetRate ), m_minNormalizer );
573 else if( m_currentControl == WellControls::Control::MASSRATE )
576 normalizer = LvArray::math::max( LvArray::math::abs( m_targetMassRate ), m_minNormalizer );
582 normalizer = m_targetBHP;
586 else if( idof == WJ_ROFFSET::MASSBAL )
590 normalizer = m_dt * LvArray::math::abs( m_targetRate ) * m_density_n[iwelem][0];
593 normalizer = LvArray::math::max( normalizer, m_volume[iwelem] * m_density_n[iwelem][0] );
597 real64 const val = LvArray::math::abs( m_localResidual[stack.localRow + idof] ) / normalizer;
598 if( val > stack.localValue[0] )
600 stack.localValue[0] = val;
605 else if( idof == WJ_ROFFSET::ENERGYBAL )
607 real64 massNormalizer = 0.0, energyNormalizer = 0.0;
608 computeMassEnergyNormalizers( iwelem, massNormalizer, energyNormalizer );
609 real64 const valEnergy = LvArray::math::abs( m_localResidual[stack.localRow + WJ_ROFFSET::ENERGYBAL] ) / energyNormalizer;
610 if( valEnergy > stack.localValue[1] )
612 stack.localValue[1] = valEnergy;
620 L2StackVariables & stack )
const override
623 GEOS_ERROR(
"The L2 norm is not implemented for SinglePhaseWell" );
644 real64 const m_targetRate;
645 real64 const m_targetMassRate;
679 template<
typename POLICY >
682 string const & dofKey,
685 constitutive::SingleFluidBase
const & fluid,
689 real64 const minNormalizer,
690 real64 (& residualNorm)[2] )
696 kernelType kernel( rankOffset, localResidual, dofNumber, ghostRank,
697 subRegion, fluid, wellControls, time, dt, minNormalizer );
698 kernelType::template launchLinf< POLICY >( subRegion.
size(), kernel, residualNorm );
#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.
arrayView1d< real64 const > getElementVolume() const
Get the volume of each element in this subregion.
array1d< integer > const & ghostRank()
Get the ghost information of each object.
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 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.
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 residual calculations.
Define the interface for the assembly kernel in charge of accumulation.
arrayView1d< real64 const > const m_wellElemVolume
View on the element volumes.
arrayView1d< real64 > const m_localRhs
View on the local RHS.
arrayView2d< real64 const, constitutive::singlefluid::USD_FLUID > const m_wellElemDensity
Views on the density.
GEOS_HOST_DEVICE void computeAccumulation(localIndex const iwelem, FUNC &&kernelOp=NoOpFunc{}) const
Compute the local accumulation contributions to the residual and Jacobian.
CRSMatrixView< real64, globalIndex const > const m_localMatrix
View on the local CRS matrix.
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.
Define the interface for the assembly kernel in charge of flux terms.
GEOS_HOST_DEVICE void computeFlux(localIndex const iwelem, FUNC &&compFluxKernelOp=NoOpFunc{}) const
Compute the local flux contributions to the residual and Jacobian.
bool const m_isProducer
Well type.
CRSMatrixView< real64, globalIndex const > const m_localMatrix
View on the local CRS matrix.
arrayView1d< real64 > const m_localRhs
View on the local RHS.
integer const m_rankOffset
Rank offset for calculating row/col Jacobian indices.
real64 const m_dt
Time step size.
arrayView1d< globalIndex const > const m_wellElemDofNumber
Reference to the degree-of-freedom numbers.
static void createAndLaunch(integer const isProducer, globalIndex const rankOffset, string const dofKey, WellElementSubRegion const &subRegion, constitutive::SingleFluidBase 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 energy balance.
static void launch(localIndex const numElems, KERNEL_TYPE const &kernelComponent)
Performs the kernel launch.
ElementBasedAssemblyKernel(integer const isProducer, globalIndex const rankOffset, string const dofKey, WellElementSubRegion const &subRegion, constitutive::SingleFluidBase const &fluid, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs)
Constructor.
arrayView1d< real64 const > const m_wellElemVolume
View on the element volumes.
GEOS_HOST_DEVICE void computeAccumulation(localIndex const iwelem) const
Compute the local accumulation contributions to the residual and Jacobian.
arrayView1d< real64 > const m_localRhs
View on the local RHS.
arrayView2d< real64 const, constitutive::singlefluid::USD_FLUID > const m_internalEnergy
Views on fluid internal energy.
arrayView2d< real64 const, constitutive::singlefluid::USD_FLUID > const m_wellElemDensity
Views on the density.
integer const m_isProducer
Well type.
GEOS_HOST_DEVICE integer elemGhostRank(localIndex const iwelem) const
Getter for the ghost rank of an element.
localIndex const m_iwelemControl
Index of the element where the control is enforced.
CRSMatrixView< real64, globalIndex const > const m_localMatrix
View on the local CRS matrix.
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.
static void createAndLaunch(real64 const dt, globalIndex const rankOffset, string const dofKey, WellControls const &wellControls, WellElementSubRegion const &subRegion, constitutive::SingleFluidBase const &fluid, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs)
Create a new kernel and launch.
Define the interface for the assembly kernel in charge of flux terms.
bool const m_isProducer
Well type.
static constexpr integer numEqn
Compile time value for the number of equations except volume and momentum.
CRSMatrixView< real64, globalIndex const > const m_localMatrix
View on the local CRS matrix.
arrayView1d< real64 > const m_localRhs
View on the local RHS.
integer const m_rankOffset
Rank offset for calculating row/col Jacobian indices.
GEOS_HOST_DEVICE void computeFlux(localIndex const iwelem) const
Compute the local flux contributions to the residual and Jacobian.
arrayView2d< real64 const, constitutive::singlefluid::USD_FLUID > m_enthalpy
Views on enthalpy.
real64 const m_dt
Time step size.
static constexpr integer numDof
Compute time value for the number of degrees of freedom.
arrayView1d< globalIndex const > const m_wellElemDofNumber
Reference to the degree-of-freedom numbers.
FaceBasedAssemblyKernel(real64 const dt, globalIndex const rankOffset, string const wellDofKey, WellControls const &wellControls, WellElementSubRegion const &subRegion, constitutive::SingleFluidBase const &fluid, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs)
Constructor for the kernel interface.
static void launch(localIndex const numElements, KERNEL_TYPE const &kernelComponent)
Performs the kernel launch.
arrayView1d< globalIndex const > m_globalWellElementIndex
Global index of local element.
static void createAndLaunch(globalIndex const rankOffset, string const &dofKey, arrayView1d< real64 const > const &localResidual, WellElementSubRegion const &subRegion, constitutive::SingleFluidBase const &fluid, WellControls const &wellControls, real64 const time, real64 const dt, real64 const minNormalizer, real64(&residualNorm)[2])
Create a new kernel and launch.
arrayView2d< real64 const, constitutive::singlefluid::USD_FLUID > const m_density_n
View on phase/total density at the previous converged time step.
bool const m_isProducer
Flag indicating whether the well is a producer or an injector.
bool const m_isLocallyOwned
Flag indicating whether the well is locally owned or not.
virtual GEOS_HOST_DEVICE void computeLinf(localIndex const iwelem, LinfStackVariables &stack) const override
Compute the local values for the Linf norm.
WellControls::Control const m_currentControl
Controls.
real64 const m_dt
Time step size.
virtual GEOS_HOST_DEVICE void computeL2(localIndex const iwelem, L2StackVariables &stack) const override
Compute the local values and normalizer for the L2 norm.
arrayView1d< real64 const > const m_volume
View on the volume.
localIndex const m_iwelemControl
Index of the element where the control is enforced.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
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).
double real64
64-bit floating point type.
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
std::int32_t integer
Signed integer type.
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.