20 #ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_WELLS_SINGLEPHASEWELLKERNELS_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_WELLS_SINGLEPHASEWELLKERNELS_HPP
24 #include "common/GEOS_RAJA_Interface.hpp"
27 #include "constitutive/fluid/singlefluid/SingleFluidFields.hpp"
28 #include "constitutive/fluid/singlefluid/SingleFluidBase.hpp"
29 #include "constitutive/fluid/singlefluid/SingleFluidLayouts.hpp"
30 #include "constitutive/fluid/singlefluid/SingleFluidLayouts.hpp"
35 #include "physicsSolvers/fluidFlow/wells/WellControls.hpp"
38 #include "physicsSolvers/fluidFlow/wells/WellConstraintsBase.hpp"
45 namespace singlePhaseWellKernels
51 static constexpr
integer RES = 0;
52 static constexpr
integer WELL = 1;
58 static constexpr
integer CURRENT = 0;
59 static constexpr
integer NEXT = 1;
65 static constexpr
integer DPRES = 0;
66 static constexpr
integer DRATE = 1;
69 template<
integer IS_THERMAL >
75 static constexpr
integer dP = 0;
76 static constexpr
integer dQ = dP + 1;
77 static integer constexpr nDer = dQ + 1;
84 static constexpr
integer dP = 0;
85 static constexpr
integer dQ = dP + 1;
86 static constexpr
integer dT = dQ+1;
94 static constexpr
integer CONTROL = 0;
95 static constexpr
integer MASSBAL = 1;
98 template<
integer IS_THERMAL >
104 static constexpr
integer CONTROL = 0;
105 static constexpr
integer MASSBAL = 1;
106 static constexpr
integer nEqn = MASSBAL+1;
111 static constexpr
integer CONTROL = 0;
112 static constexpr
integer MASSBAL = 1;
113 static constexpr
integer ENERGYBAL = MASSBAL+1;
114 static constexpr
integer nEqn = ENERGYBAL+1;
126 static constexpr
real64 EPS = 1e-15;
132 switchControl(
bool const isProducer,
135 real64 const & targetRate,
136 real64 const & currentBHP,
137 real64 const & currentVolRate,
140 template<
integer IS_THERMAL >
148 real64 const & targetRate,
149 real64 const & currentBHP,
151 real64 const & currentVolRate,
169 template<
integer IS_THERMAL >
192 template<
integer IS_THERMAL >
220 fields::singlefluid::density,
221 fields::singlefluid::dDensity,
222 fields::singlefluid::viscosity,
223 fields::singlefluid::dViscosity >;
232 template<
typename VIEWTYPE >
235 template<
integer IS_THERMAL >
240 compute(
real64 const & resPressure,
241 real64 const & resDensity,
243 real64 const & resViscosity,
245 real64 const & wellElemGravCoef,
246 real64 const & wellElemPressure,
247 real64 const & wellElemDensity,
249 real64 const & wellElemViscosity,
251 real64 const & perfGravCoef,
257 template<
integer IS_THERMAL >
311 template<
integer IS_THERMAL >
317 using FLUID_PROP_COFFSET = constitutive::singlefluid::DerivativeOffsetC< IS_THERMAL >;
341 constitutive::SingleFluidBase
const & fluid,
350 m_dWellElemDensity( fluid.dDensity() ),
351 m_wellElemDensity_n( fluid.density_n() ),
375 template<
typename FUNC = NoOpFunc >
378 FUNC && kernelOp = NoOpFunc{} )
const
385 real64 const localAccumDP =
m_wellElemVolume[iwelem] * m_dWellElemDensity[iwelem][0][FLUID_PROP_COFFSET::dP];
388 m_localMatrix.addToRow< serialAtomic >( eqnRowIndex, &presDofColIndex, &localAccumDP, 1 );
391 if constexpr ( IS_THERMAL )
393 real64 const localAccumDT =
m_wellElemVolume[iwelem] * m_dWellElemDensity[iwelem][0][FLUID_PROP_COFFSET::dT];
395 m_localMatrix.addToRow< serialAtomic >( eqnRowIndex, &tempDofColIndex, &localAccumDT, 1 );
396 kernelOp( presDofColIndex, tempDofColIndex );
410 template<
typename POLICY,
typename KERNEL_TYPE >
413 KERNEL_TYPE
const & kernelComponent )
419 if( kernelComponent.elemGhostRank( iwelem ) >= 0 )
423 kernelComponent.computeAccumulation( iwelem );
472 template<
typename POLICY >
477 constitutive::SingleFluidBase
const & fluid,
484 kernel( rankOffset, dofKey, subRegion, fluid, localMatrix, localRhs );
486 launch< POLICY, ElementBasedAssemblyKernel< isThermal > >( subRegion.
size(), kernel );
498 fields::flow::temperature >;
502 fields::singlefluid::density >;
511 template<
typename VIEWTYPE >
515 launch(
integer const isThermal,
520 real64 const & refWellElemGravCoef,
521 real64 const & currentTime,
543 template<
integer IS_THERMAL >
552 using FLUID_PROP_COFFSET = constitutive::singlefluid::DerivativeOffsetC< IS_THERMAL >;
556 using CP_Deriv = constitutive::singlefluid::DerivativeOffsetC< IS_THERMAL >;
564 static constexpr
integer maxNumElems = 2;
565 static constexpr
integer maxStencilSize = 2;
578 string const wellDofKey,
588 m_connRate ( subRegion.getField< fields::well::connectionRate >() ),
602 template<
typename FUNC = NoOpFunc >
606 FUNC && compFluxKernelOp = NoOpFunc{} )
const
628 real64 const oneSidedLocalFlux = -flux;
629 real64 const oneSidedLocalFluxJacobian_dRate = -dFlux_dRate;
635 if( oneSidedEqnRowIndex >= 0 && oneSidedEqnRowIndex <
m_localMatrix.numRows() )
637 m_localMatrix.addToRow< parallelDeviceAtomic >( oneSidedEqnRowIndex,
638 &oneSidedDofColIndex_dRate,
639 &oneSidedLocalFluxJacobian_dRate,
641 RAJA::atomicAdd( parallelDeviceAtomic{}, &
m_localRhs[oneSidedEqnRowIndex], oneSidedLocalFlux );
650 real64 localFluxJacobian_dRate[2]{};
653 localFlux[TAG::NEXT] = flux;
654 localFlux[TAG::CURRENT] = -flux;
656 localFluxJacobian_dRate[TAG::NEXT] = dFlux_dRate;
657 localFluxJacobian_dRate[TAG::CURRENT] = -dFlux_dRate;
666 if( eqnRowIndices[i] >= 0 && eqnRowIndices[i] <
m_localMatrix.numRows() )
668 m_localMatrix.addToRow< parallelDeviceAtomic >( eqnRowIndices[i],
670 &localFluxJacobian_dRate[i],
672 RAJA::atomicAdd( parallelDeviceAtomic{}, &
m_localRhs[eqnRowIndices[i]], localFlux[i] );
676 compFluxKernelOp( iwelemNext, currentConnRate );
688 template<
typename POLICY,
typename KERNEL_TYPE >
691 KERNEL_TYPE
const & kernelComponent )
696 kernelComponent.computeFlux( ie );
745 template<
typename POLICY >
756 geos::internal::kernelLaunchSelectorThermalSwitch( isThermal, [&](
auto IS_THERMAL )
759 integer constexpr istherm = IS_THERMAL();
762 kernelType kernel( dt, rankOffset, dofKey, wellControls, subRegion, localMatrix, localRhs );
763 kernelType::template launch< POLICY >( subRegion.
size(), kernel );
775 real64 const & currentTime,
802 constitutive::SingleFluidBase
const & fluid,
806 real64 const minNormalizer )
824 LinfStackVariables & stack )
const override
829 if( idof == singlePhaseWellKernels::RowOffset::CONTROL )
837 normalizer = m_targetBHP;
842 normalizer = LvArray::math::max( LvArray::math::abs( m_constraintValue ),
m_minNormalizer );
847 normalizer = LvArray::math::max( LvArray::math::abs( m_constraintValue ),
m_minNormalizer );
854 normalizer = m_targetBHP;
860 normalizer =
m_dt * LvArray::math::abs( m_constraintValue ) *
m_density_n[iwelem][0];
868 if( val > stack.localValue[0] )
870 stack.localValue[0] = val;
878 L2StackVariables & stack )
const override
881 GEOS_ERROR(
"The L2 norm is not implemented for SinglePhaseWell" );
898 real64 const m_constraintValue;
930 template<
typename POLICY >
933 string const & dofKey,
936 constitutive::SingleFluidBase
const & fluid,
940 real64 const minNormalizer,
941 real64 (& residualNorm)[1] )
946 ResidualNormKernel kernel( rankOffset, localResidual, dofNumber, ghostRank, subRegion, fluid, wellControls, time, dt, minNormalizer );
947 ResidualNormKernel::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(...)
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.
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.
real64 getConstraintValue(real64 const ¤tTime) const
Get the target bottom hole pressure value.
This class describes the controls used to operate a well.
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.
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.
static void createAndLaunch(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.
arrayView1d< real64 const > const m_wellElemVolume
View on the element volumes.
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.
ElementBasedAssemblyKernel(globalIndex const rankOffset, string const dofKey, WellElementSubRegion const &subRegion, constitutive::SingleFluidBase const &fluid, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs)
Constructor.
arrayView2d< real64 const, constitutive::singlefluid::USD_FLUID > const m_wellElemDensity
Views on the density.
static constexpr integer numEqn
Compute time value for the number of equations mass bal + momentum + energy bal.
GEOS_HOST_DEVICE void computeAccumulation(localIndex const iwelem, FUNC &&kernelOp=NoOpFunc{}) const
Compute the local accumulation contributions to the residual and Jacobian.
static constexpr integer numDof
Number of Dof's set in this kernal - no dQ in accum.
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.
static void launch(localIndex const numElems, KERNEL_TYPE const &kernelComponent)
Performs the kernel launch.
arrayView1d< integer const > const m_elemGhostRank
View on the ghost ranks.
localIndex const m_iwelemControl
Index of the element where the control is enforced.
static void createAndLaunch(real64 const dt, globalIndex const rankOffset, 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.
GEOS_HOST_DEVICE void computeFlux(localIndex const iwelem, FUNC &&compFluxKernelOp=NoOpFunc{}) const
Compute the local flux contributions to the residual and Jacobian.
arrayView1d< real64 const > const m_connRate
Connection rate.
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)
Constructor for the kernel interface.
bool const m_isProducer
Well type.
arrayView2d< real64 const, compflow::USD_COMP > const m_wellElemCompFrac
Element component fraction.
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.
arrayView1d< localIndex const > const m_nextWellElemIndex
Next element index, needed since iterating over element nodes, not edges.
static constexpr integer numDof
Number of Dof's set in this kernal.
real64 const m_dt
Time step size.
static void launch(localIndex const numElements, KERNEL_TYPE const &kernelComponent)
Performs the kernel launch.
static constexpr integer numEqn
Compile time value for the number of equations except rate, momentum, energy.
arrayView1d< globalIndex const > const m_wellElemDofNumber
Reference to the degree-of-freedom numbers.
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)[1])
Create a new kernel and launch.
real64 const m_dt
Time step size.
bool const m_isLocallyOwned
Flag indicating whether the well is locally owned or not.
arrayView1d< real64 const > const m_volume
View on the volume.
arrayView2d< real64 const, constitutive::singlefluid::USD_FLUID > const m_density_n
View on total density at the previous converged time step.
virtual GEOS_HOST_DEVICE void computeL2(localIndex const iwelem, L2StackVariables &stack) const override
Compute the local values and normalizer for the L2 norm.
virtual GEOS_HOST_DEVICE void computeLinf(localIndex const iwelem, LinfStackVariables &stack) const override
Compute the local values for the Linf norm.
localIndex const m_iwelemControl
Index of the element where the control is enforced.
ConstraintTypeId const m_currentControl
Controls.
ConstraintTypeId getControl() const
Get the control type for the well.
real64 getTargetBHP(real64 const &targetTime, const ConstraintSourceId source=ConstraintSourceId::USER) const
Returns the target bottom hole pressure value.
WellConstraintBase * getCurrentConstraint()
Get the current consrtaint.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
GEOS_GLOBALINDEX_TYPE globalIndex
Global index type (for indexing objects across MPI partitions).
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, 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.
ElementRegionManager::ElementViewConst< VIEWTYPE > ElementViewConst
The type for element-based non-constitutive data parameters. Consists entirely of ArrayView's.
ElementRegionManager::ElementViewConst< VIEWTYPE > ElementViewConst
The type for element-based non-constitutive data parameters. Consists entirely of ArrayView's.