GEOS
SinglePhaseWellKernels.hpp
Go to the documentation of this file.
1 /*
2  * ------------------------------------------------------------------------------------------------------------
3  * SPDX-License-Identifier: LGPL-2.1-only
4  *
5  * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC
6  * Copyright (c) 2018-2024 TotalEnergies
7  * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University
8  * Copyright (c) 2023-2024 Chevron
9  * Copyright (c) 2019- GEOS/GEOSX Contributors
10  * All rights reserved
11  *
12  * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
13  * ------------------------------------------------------------------------------------------------------------
14  */
15 
20 #ifndef GEOS_PHYSICSSOLVERS_FLUIDFLOW_WELLS_SINGLEPHASEWELLKERNELS_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_WELLS_SINGLEPHASEWELLKERNELS_HPP
22 
23 #include "constitutive/fluid/singlefluid/SingleFluidFields.hpp"
24 #include "constitutive/fluid/singlefluid/SingleFluidBase.hpp"
25 #include "constitutive/fluid/singlefluid/SingleFluidLayouts.hpp"
26 #include "common/DataTypes.hpp"
27 #include "common/GEOS_RAJA_Interface.hpp"
31 #include "physicsSolvers/fluidFlow/wells/WellControls.hpp"
33 
34 namespace geos
35 {
36 
37 namespace singlePhaseWellKernels
38 {
39 
40 // tag to access well and reservoir elements in perforation rates computation
42 {
43  static constexpr integer RES = 0;
44  static constexpr integer WELL = 1;
45 };
46 
47 // tag to access the next and current well elements of a connection
48 struct ElemTag
49 {
50  static constexpr integer CURRENT = 0;
51  static constexpr integer NEXT = 1;
52 };
53 
54 // define the column offset of the derivatives
55 struct ColOffset
56 {
57  static constexpr integer DPRES = 0;
58  static constexpr integer DRATE = 1;
59 };
60 
61 // define the row offset of the residual equations
62 struct RowOffset
63 {
64  static constexpr integer CONTROL = 0;
65  static constexpr integer MASSBAL = 1;
66 };
67 
68 
69 /******************************** ControlEquationHelper ********************************/
70 
72 {
73 
76 
77  // add an epsilon to the checks to avoid control changes due to tiny pressure/rate updates
78  static constexpr real64 EPS = 1e-15;
79 
81  inline
82  static
83  void
84  switchControl( bool const isProducer,
85  WellControls::Control const & currentControl,
86  real64 const & targetBHP,
87  real64 const & targetRate,
88  real64 const & currentBHP,
89  real64 const & currentVolRate,
90  WellControls::Control & newControl );
91 
93  inline
94  static
95  void
96  compute( globalIndex const rankOffset,
97  WellControls::Control const currentControl,
98  real64 const & targetBHP,
99  real64 const & targetRate,
100  real64 const & currentBHP,
101  real64 const & dCurrentBHP_dPres,
102  real64 const & currentVolRate,
103  real64 const & dCurrentVolRate_dPres,
104  real64 const & dCurrentVolRate_dRate,
105  globalIndex const dofNumber,
106  CRSMatrixView< real64, globalIndex const > const & localMatrix,
107  arrayView1d< real64 > const & localRhs );
108 
109 };
110 
111 
112 /******************************** FluxKernel ********************************/
113 
115 {
116 
120 
121  static void
122  launch( localIndex const size,
123  globalIndex const rankOffset,
124  arrayView1d< globalIndex const > const & wellElemDofNumber,
125  arrayView1d< localIndex const > const & nextWellElemIndex,
126  arrayView1d< real64 const > const & connRate,
127  real64 const & dt,
128  CRSMatrixView< real64, globalIndex const > const & localMatrix,
129  arrayView1d< real64 > const & localRhs );
130 
131 };
132 
133 
134 /******************************** PressureRelationKernel ********************************/
135 
137 {
138 
142 
143  static localIndex
144  launch( localIndex const size,
145  globalIndex const rankOffset,
146  bool const isLocallyOwned,
147  localIndex const iwelemControl,
148  WellControls const & wellControls,
149  real64 const & timeAtEndOfStep,
150  arrayView1d< globalIndex const > const & wellElemDofNumber,
151  arrayView1d< real64 const > const & wellElemGravCoef,
152  arrayView1d< localIndex const > const & nextWellElemIndex,
153  arrayView1d< real64 const > const & wellElemPressure,
156  CRSMatrixView< real64, globalIndex const > const & localMatrix,
157  arrayView1d< real64 > const & localRhs );
158 
159 };
160 
161 
162 /******************************** PerforationKernel ********************************/
163 
165 {
166 
168 
171 
172  using SingleFluidAccessors =
173  StencilMaterialAccessors< constitutive::SingleFluidBase,
174  fields::singlefluid::density,
175  fields::singlefluid::dDensity,
176  fields::singlefluid::viscosity,
177  fields::singlefluid::dViscosity >;
178 
186  template< typename VIEWTYPE >
188 
190  inline
191  static
192  void
193  compute( real64 const & resPressure,
194  real64 const & resDensity,
195  real64 const & dResDensity_dPres,
196  real64 const & resViscosity,
197  real64 const & dResViscosity_dPres,
198  real64 const & wellElemGravCoef,
199  real64 const & wellElemPressure,
200  real64 const & wellElemDensity,
201  real64 const & dWellElemDensity_dPres,
202  real64 const & wellElemViscosity,
203  real64 const & dWellElemViscosity_dPres,
204  real64 const & perfGravCoef,
205  real64 const & trans,
206  real64 & perfRate,
207  arraySlice1d< real64 > const & dPerfRate_dPres );
208 
209  static void
210  launch( localIndex const size,
211  ElementViewConst< arrayView1d< real64 const > > const & resPressure,
216  arrayView1d< real64 const > const & wellElemGravCoef,
217  arrayView1d< real64 const > const & wellElemPressure,
222  arrayView1d< real64 const > const & perfGravCoef,
223  arrayView1d< localIndex const > const & perfWellElemIndex,
224  arrayView1d< real64 const > const & perfTransmissibility,
225  arrayView1d< localIndex const > const & resElementRegion,
226  arrayView1d< localIndex const > const & resElementSubRegion,
227  arrayView1d< localIndex const > const & resElementIndex,
228  arrayView1d< real64 > const & perfRate,
229  arrayView2d< real64 > const & dPerfRate_dPres );
230 
231 };
232 
233 /******************************** AccumulationKernel ********************************/
234 
236 {
237 
240 
241  static void
242  launch( localIndex const size,
243  globalIndex const rankOffset,
244  arrayView1d< globalIndex const > const & wellElemDofNumber,
245  arrayView1d< integer const > const & wellElemGhostRank,
246  arrayView1d< real64 const > const & wellElemVolume,
250  CRSMatrixView< real64, globalIndex const > const & localMatrix,
251  arrayView1d< real64 > const & localRhs );
252 
253 };
254 
255 /******************************** PressureInitializationKernel ********************************/
256 
258 {
259 
262 
263  using SingleFluidAccessors =
264  StencilMaterialAccessors< constitutive::SingleFluidBase,
265  fields::singlefluid::density >;
266 
274  template< typename VIEWTYPE >
276 
277  static void
278  launch( localIndex const perforationSize,
279  localIndex const subRegionSize,
280  localIndex const numPerforations,
281  WellControls const & wellControls,
282  real64 const & currentTime,
283  ElementViewConst< arrayView1d< real64 const > > const & resPressure,
285  arrayView1d< localIndex const > const & resElementRegion,
286  arrayView1d< localIndex const > const & resElementSubRegion,
287  arrayView1d< localIndex const > const & resElementIndex,
288  arrayView1d< real64 const > const & perfGravCoef,
289  arrayView1d< real64 const > const & wellElemGravCoef,
290  arrayView1d< real64 > const & wellElemPressure );
291 
292 };
293 
294 /******************************** RateInitializationKernel ********************************/
295 
297 {
298 
299  static void
300  launch( localIndex const subRegionSize,
301  WellControls const & wellControls,
302  real64 const & currentTime,
304  arrayView1d< real64 > const & connRate );
305 
306 };
307 
308 
309 /******************************** ResidualNormKernel ********************************/
310 
315 {
316 public:
317 
319  using Base::m_minNormalizer;
320  using Base::m_rankOffset;
321  using Base::m_localResidual;
322  using Base::m_dofNumber;
323 
324  ResidualNormKernel( globalIndex const rankOffset,
325  arrayView1d< real64 const > const & localResidual,
326  arrayView1d< globalIndex const > const & dofNumber,
328  WellElementSubRegion const & subRegion,
329  constitutive::SingleFluidBase const & fluid,
330  WellControls const & wellControls,
331  real64 const timeAtEndOfStep,
332  real64 const dt,
333  real64 const minNormalizer )
334  : Base( rankOffset,
335  localResidual,
336  dofNumber,
337  ghostRank,
338  minNormalizer ),
339  m_dt( dt ),
340  m_isLocallyOwned( subRegion.isLocallyOwned() ),
342  m_currentControl( wellControls.getControl() ),
343  m_targetBHP( wellControls.getTargetBHP( timeAtEndOfStep ) ),
344  m_targetRate( wellControls.getTargetTotalRate( timeAtEndOfStep ) ),
345  m_volume( subRegion.getElementVolume() ),
346  m_density_n( fluid.density_n() )
347  {}
348 
350  virtual void computeLinf( localIndex const iwelem,
351  LinfStackVariables & stack ) const override
352  {
353  for( localIndex idof = 0; idof < 2; ++idof )
354  {
355  real64 normalizer = 0.0;
356  if( idof == singlePhaseWellKernels::RowOffset::CONTROL )
357  {
358  // for the top well element, normalize using the current control
359  if( m_isLocallyOwned && iwelem == m_iwelemControl )
360  {
362  {
363  // this residual entry is in pressure units
364  normalizer = m_targetBHP;
365  }
367  {
368  // this residual entry is in volume / time units
369  normalizer = LvArray::math::max( LvArray::math::abs( m_targetRate ), m_minNormalizer );
370  }
371  }
372  // for the pressure difference equation, always normalize by the BHP
373  else
374  {
375  // this residual is in pressure units
376  normalizer = m_targetBHP;
377  }
378  }
379  else // SinglePhaseWell::RowOffset::MASSBAL
380  {
381  // this residual entry is in mass units
382  normalizer = m_dt * LvArray::math::abs( m_targetRate ) * m_density_n[iwelem][0];
383 
384  // to make sure that everything still works well if the rate is zero, we add this check
385  normalizer = LvArray::math::max( normalizer, m_volume[iwelem] * m_density_n[iwelem][0] );
386  }
387 
388  // we have the normalizer now, we can compute a dimensionless Linfty norm contribution
389  real64 const val = LvArray::math::abs( m_localResidual[stack.localRow + idof] ) / normalizer;
390  if( val > stack.localValue[0] )
391  {
392  stack.localValue[0] = val;
393  }
394 
395  }
396  }
397 
399  virtual void computeL2( localIndex const iwelem,
400  L2StackVariables & stack ) const override
401  {
402  GEOS_UNUSED_VAR( iwelem, stack );
403  GEOS_ERROR( "The L2 norm is not implemented for SinglePhaseWell" );
404  }
405 
406 
407 protected:
408 
410  real64 const m_dt;
411 
413  bool const m_isLocallyOwned;
414 
417 
420  real64 const m_targetBHP;
421  real64 const m_targetRate;
422 
425 
428 
429 };
430 
435 {
436 public:
437 
451  template< typename POLICY >
452  static void
453  createAndLaunch( globalIndex const rankOffset,
454  string const & dofKey,
455  arrayView1d< real64 const > const & localResidual,
456  WellElementSubRegion const & subRegion,
457  constitutive::SingleFluidBase const & fluid,
458  WellControls const & wellControls,
459  real64 const timeAtEndOfStep,
460  real64 const dt,
461  real64 const minNormalizer,
462  real64 (& residualNorm)[1] )
463  {
464  arrayView1d< globalIndex const > const dofNumber = subRegion.getReference< array1d< globalIndex > >( dofKey );
465  arrayView1d< integer const > const ghostRank = subRegion.ghostRank();
466 
467  ResidualNormKernel kernel( rankOffset, localResidual, dofNumber, ghostRank, subRegion, fluid, wellControls, timeAtEndOfStep, dt, minNormalizer );
468  ResidualNormKernel::launchLinf< POLICY >( subRegion.size(), kernel, residualNorm );
469  }
470 
471 };
472 
473 } // end namespace singlePhaseWellKernels
474 
475 } // end namespace geos
476 
477 #endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_WELLS_SINGLEPHASEWELLKERNELS_HPP
#define GEOS_HOST_DEVICE
Marks a host-device function.
Definition: GeosxMacros.hpp:49
#define GEOS_UNUSED_VAR(...)
Mark an unused variable and silence compiler warnings.
Definition: GeosxMacros.hpp:84
#define GEOS_ERROR(msg)
Raise a hard error and terminate the program.
Definition: Logger.hpp:157
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 &currentTime) const
Get the target total rate.
real64 getTargetBHP(real64 const &currentTime) 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.
Definition: Group.hpp:1275
localIndex size() const
Get the "size" of the group, which determines the number of elements in resizable wrappers.
Definition: Group.hpp:1317
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.
arrayView1d< real64 const > const m_localResidual
View on the local residual.
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 timeAtEndOfStep, real64 const dt, real64 const minNormalizer, real64(&residualNorm)[1])
Create a new kernel and launch.
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.
Definition: DataTypes.hpp:180
LvArray::CRSMatrixView< T, COL_INDEX, localIndex const, LvArray::ChaiBuffer > CRSMatrixView
Alias for CRS Matrix View.
Definition: DataTypes.hpp:310
GEOS_GLOBALINDEX_TYPE globalIndex
Global index type (for indexing objects across MPI partitions).
Definition: DataTypes.hpp:88
double real64
64-bit floating point type.
Definition: DataTypes.hpp:99
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:85
ArraySlice< T, 1, USD > arraySlice1d
Alias for 1D array slice.
Definition: DataTypes.hpp:184
std::int32_t integer
Signed integer type.
Definition: DataTypes.hpp:82
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.
Definition: DataTypes.hpp:196
Array< T, 1 > array1d
Alias for 1D array.
Definition: DataTypes.hpp:176
ArrayView< T, 3, USD > arrayView3d
Alias for 3D array view.
Definition: DataTypes.hpp:212
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.