20 #ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_WELLS_SINGLEPHASEWELLKERNELS_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_WELLS_SINGLEPHASEWELLKERNELS_HPP
23 #include "constitutive/fluid/singlefluid/SingleFluidFields.hpp"
24 #include "constitutive/fluid/singlefluid/SingleFluidBase.hpp"
25 #include "constitutive/fluid/singlefluid/SingleFluidLayouts.hpp"
26 #include "constitutive/fluid/singlefluid/SingleFluidLayouts.hpp"
28 #include "common/GEOS_RAJA_Interface.hpp"
32 #include "physicsSolvers/fluidFlow/wells/WellControls.hpp"
40 namespace singlePhaseWellKernels
46 static constexpr
integer RES = 0;
47 static constexpr
integer WELL = 1;
53 static constexpr
integer CURRENT = 0;
54 static constexpr
integer NEXT = 1;
60 static constexpr
integer DPRES = 0;
61 static constexpr
integer DRATE = 1;
64 template<
integer IS_THERMAL >
70 static constexpr
integer dP = 0;
71 static constexpr
integer dQ = dP + 1;
72 static integer constexpr nDer = dQ + 1;
79 static constexpr
integer dP = 0;
80 static constexpr
integer dQ = dP + 1;
81 static constexpr
integer dT = dQ+1;
89 static constexpr
integer CONTROL = 0;
90 static constexpr
integer MASSBAL = 1;
93 template<
integer IS_THERMAL >
99 static constexpr
integer CONTROL = 0;
100 static constexpr
integer MASSBAL = 1;
101 static constexpr
integer nEqn = MASSBAL+1;
106 static constexpr
integer CONTROL = 0;
107 static constexpr
integer MASSBAL = 1;
108 static constexpr
integer ENERGYBAL = MASSBAL+1;
109 static constexpr
integer nEqn = ENERGYBAL+1;
121 static constexpr
real64 EPS = 1e-15;
127 switchControl(
bool const isProducer,
130 real64 const & targetRate,
131 real64 const & currentBHP,
132 real64 const & currentVolRate,
135 template<
integer IS_THERMAL >
143 real64 const & targetRate,
144 real64 const & currentBHP,
146 real64 const & currentVolRate,
164 template<
integer IS_THERMAL >
187 template<
integer IS_THERMAL >
191 bool const isLocallyOwned,
219 fields::singlefluid::density,
220 fields::singlefluid::dDensity,
221 fields::singlefluid::viscosity,
222 fields::singlefluid::dViscosity >;
231 template<
typename VIEWTYPE >
234 template<
integer IS_THERMAL >
239 compute(
real64 const & resPressure,
240 real64 const & resDensity,
242 real64 const & resViscosity,
244 real64 const & wellElemGravCoef,
245 real64 const & wellElemPressure,
246 real64 const & wellElemDensity,
248 real64 const & wellElemViscosity,
250 real64 const & perfGravCoef,
256 template<
integer IS_THERMAL >
310 template<
integer IS_THERMAL >
316 using FLUID_PROP_COFFSET = constitutive::singlefluid::DerivativeOffsetC< IS_THERMAL >;
340 constitutive::SingleFluidBase
const & fluid,
349 m_dWellElemDensity( fluid.dDensity() ),
350 m_wellElemDensity_n( fluid.density_n() ),
374 template<
typename FUNC = NoOpFunc >
377 FUNC && kernelOp = NoOpFunc{} )
const
384 real64 const localAccumDP =
m_wellElemVolume[iwelem] * m_dWellElemDensity[iwelem][0][FLUID_PROP_COFFSET::dP];
387 m_localMatrix.addToRow< serialAtomic >( eqnRowIndex, &presDofColIndex, &localAccumDP, 1 );
390 if constexpr ( IS_THERMAL )
392 real64 const localAccumDT =
m_wellElemVolume[iwelem] * m_dWellElemDensity[iwelem][0][FLUID_PROP_COFFSET::dT];
394 m_localMatrix.addToRow< serialAtomic >( eqnRowIndex, &tempDofColIndex, &localAccumDT, 1 );
395 kernelOp( presDofColIndex, tempDofColIndex );
409 template<
typename POLICY,
typename KERNEL_TYPE >
412 KERNEL_TYPE
const & kernelComponent )
418 if( kernelComponent.elemGhostRank( iwelem ) >= 0 )
422 kernelComponent.computeAccumulation( iwelem );
471 template<
typename POLICY >
476 constitutive::SingleFluidBase
const & fluid,
483 kernel( rankOffset, dofKey, subRegion, fluid, localMatrix, localRhs );
485 launch< POLICY, ElementBasedAssemblyKernel< isThermal > >( subRegion.
size(), kernel );
497 fields::flow::temperature >;
501 fields::singlefluid::density >;
510 template<
typename VIEWTYPE >
514 launch(
integer const isThermal,
519 real64 const & currentTime,
541 template<
integer IS_THERMAL >
550 using FLUID_PROP_COFFSET = constitutive::singlefluid::DerivativeOffsetC< IS_THERMAL >;
554 using CP_Deriv = constitutive::singlefluid::DerivativeOffsetC< IS_THERMAL >;
562 static constexpr
integer maxNumElems = 2;
563 static constexpr
integer maxStencilSize = 2;
576 string const wellDofKey,
586 m_connRate ( subRegion.getField< fields::well::connectionRate >() ),
600 template<
typename FUNC = NoOpFunc >
604 FUNC && compFluxKernelOp = NoOpFunc{} )
const
626 real64 const oneSidedLocalFlux = -flux;
627 real64 const oneSidedLocalFluxJacobian_dRate = -dFlux_dRate;
633 if( oneSidedEqnRowIndex >= 0 && oneSidedEqnRowIndex <
m_localMatrix.numRows() )
635 m_localMatrix.addToRow< parallelDeviceAtomic >( oneSidedEqnRowIndex,
636 &oneSidedDofColIndex_dRate,
637 &oneSidedLocalFluxJacobian_dRate,
639 RAJA::atomicAdd( parallelDeviceAtomic{}, &
m_localRhs[oneSidedEqnRowIndex], oneSidedLocalFlux );
648 real64 localFluxJacobian_dRate[2]{};
651 localFlux[TAG::NEXT] = flux;
652 localFlux[TAG::CURRENT] = -flux;
654 localFluxJacobian_dRate[TAG::NEXT] = dFlux_dRate;
655 localFluxJacobian_dRate[TAG::CURRENT] = -dFlux_dRate;
664 if( eqnRowIndices[i] >= 0 && eqnRowIndices[i] <
m_localMatrix.numRows() )
666 m_localMatrix.addToRow< parallelDeviceAtomic >( eqnRowIndices[i],
668 &localFluxJacobian_dRate[i],
670 RAJA::atomicAdd( parallelDeviceAtomic{}, &
m_localRhs[eqnRowIndices[i]], localFlux[i] );
674 compFluxKernelOp( iwelemNext, currentConnRate );
686 template<
typename POLICY,
typename KERNEL_TYPE >
689 KERNEL_TYPE
const & kernelComponent )
694 kernelComponent.computeFlux( ie );
743 template<
typename POLICY >
754 geos::internal::kernelLaunchSelectorThermalSwitch( isThermal, [&](
auto IS_THERMAL )
757 integer constexpr istherm = IS_THERMAL();
760 kernelType kernel( dt, rankOffset, dofKey, wellControls, subRegion, localMatrix, localRhs );
761 kernelType::template launch< POLICY >( subRegion.
size(), kernel );
773 real64 const & currentTime,
800 constitutive::SingleFluidBase
const & fluid,
804 real64 const minNormalizer )
823 LinfStackVariables & stack )
const override
828 if( idof == singlePhaseWellKernels::RowOffset::CONTROL )
836 normalizer = m_targetBHP;
841 normalizer = LvArray::math::max( LvArray::math::abs( m_targetRate ),
m_minNormalizer );
846 normalizer = LvArray::math::max( LvArray::math::abs( m_targetMassRate ),
m_minNormalizer );
853 normalizer = m_targetBHP;
859 normalizer =
m_dt * LvArray::math::abs( m_targetRate ) *
m_density_n[iwelem][0];
867 if( val > stack.localValue[0] )
869 stack.localValue[0] = val;
877 L2StackVariables & stack )
const override
880 GEOS_ERROR(
"The L2 norm is not implemented for SinglePhaseWell" );
898 real64 const m_targetRate;
899 real64 const m_targetMassRate;
929 template<
typename POLICY >
932 string const & dofKey,
935 constitutive::SingleFluidBase
const & fluid,
939 real64 const minNormalizer,
940 real64 (& residualNorm)[1] )
945 ResidualNormKernel kernel( rankOffset, localResidual, dofNumber, ghostRank, subRegion, fluid, wellControls, time, dt, minNormalizer );
946 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(msg)
Raise a hard error and terminate the program.
#define GEOS_MARK_FUNCTION
Mark function with both Caliper and NVTX if enabled.
typename ElementViewAccessor< VIEWTYPE >::NestedViewTypeConst ElementViewConst
The ElementViewAccessor at the ElementRegionManager level is the type resulting from ElementViewAcces...
arrayView1d< real64 const > getElementVolume() const
Get the volume of each element in this subregion.
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.
This class describes the controls used to operate a well.
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.
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.
WellControls::Control const m_currentControl
Controls.
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).
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, 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.
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.