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 "constitutive/fluid/singlefluid/SingleFluidLayouts.hpp"
27 #include "common/DataTypes.hpp"
28 #include "common/GEOS_RAJA_Interface.hpp"
32 #include "physicsSolvers/fluidFlow/wells/WellControls.hpp"
36 
37 namespace geos
38 {
39 
40 namespace singlePhaseWellKernels
41 {
42 
43 // tag to access well and reservoir elements in perforation rates computation
45 {
46  static constexpr integer RES = 0;
47  static constexpr integer WELL = 1;
48 };
49 
50 // tag to access the next and current well elements of a connection
51 struct ElemTag
52 {
53  static constexpr integer CURRENT = 0;
54  static constexpr integer NEXT = 1;
55 };
56 
57 // define the column offset of the derivatives
58 struct ColOffset
59 {
60  static constexpr integer DPRES = 0;
61  static constexpr integer DRATE = 1;
62 };
63 
64 template< integer IS_THERMAL >
66 
67 template<>
68 struct ColOffset_WellJac< 0 >
69 {
70  static constexpr integer dP = 0;
71  static constexpr integer dQ = dP + 1;
72  static integer constexpr nDer = dQ + 1;
73 
74 };
75 
76 template<>
77 struct ColOffset_WellJac< 1 >
78 {
79  static constexpr integer dP = 0;
80  static constexpr integer dQ = dP + 1;
81  static constexpr integer dT = dQ+1;
83  static integer constexpr nDer = dT + 1;
84 };
85 
86 // define the row offset of the residual equations
87 struct RowOffset
88 {
89  static constexpr integer CONTROL = 0;
90  static constexpr integer MASSBAL = 1;
91 };
92 
93 template< integer IS_THERMAL >
95 
96 template<>
97 struct RowOffset_WellJac< 0 >
98 {
99  static constexpr integer CONTROL = 0;
100  static constexpr integer MASSBAL = 1;
101  static constexpr integer nEqn = MASSBAL+1;
102 };
103 template<>
104 struct RowOffset_WellJac< 1 >
105 {
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;
110 
111 };
112 /******************************** ControlEquationHelper ********************************/
113 
115 {
116 
119 
120  // add an epsilon to the checks to avoid control changes due to tiny pressure/rate updates
121  static constexpr real64 EPS = 1e-15;
122 
124  inline
125  static
126  void
127  switchControl( bool const isProducer,
128  WellControls::Control const & currentControl,
129  real64 const & targetBHP,
130  real64 const & targetRate,
131  real64 const & currentBHP,
132  real64 const & currentVolRate,
133  WellControls::Control & newControl );
134 
135  template< integer IS_THERMAL >
137  inline
138  static
139  void
140  compute( globalIndex const rankOffset,
141  WellControls::Control const currentControl,
142  real64 const & targetBHP,
143  real64 const & targetRate,
144  real64 const & currentBHP,
145  arrayView1d< real64 const > const & dCurrentBHP,
146  real64 const & currentVolRate,
147  arrayView1d< real64 const > const & dCurrentVolRate,
148  globalIndex const dofNumber,
149  CRSMatrixView< real64, globalIndex const > const & localMatrix,
150  arrayView1d< real64 > const & localRhs );
151 
152 };
153 
154 
155 /******************************** FluxKernel ********************************/
156 
158 {
159 
163 
164  template< integer IS_THERMAL >
165  static void
166  launch( localIndex const size,
167  globalIndex const rankOffset,
168  arrayView1d< globalIndex const > const & wellElemDofNumber,
169  arrayView1d< localIndex const > const & nextWellElemIndex,
170  arrayView1d< real64 const > const & connRate,
171  real64 const & dt,
172  CRSMatrixView< real64, globalIndex const > const & localMatrix,
173  arrayView1d< real64 > const & localRhs );
174 
175 };
176 
177 
178 /******************************** PressureRelationKernel ********************************/
179 
181 {
182 
186 
187  template< integer IS_THERMAL >
188  static localIndex
189  launch( localIndex const size,
190  globalIndex const rankOffset,
191  bool const isLocallyOwned,
192  localIndex const iwelemControl,
193  WellControls const & wellControls,
194  real64 const & time,
195  arrayView1d< globalIndex const > const & wellElemDofNumber,
196  arrayView1d< real64 const > const & wellElemGravCoef,
197  arrayView1d< localIndex const > const & nextWellElemIndex,
198  arrayView1d< real64 const > const & wellElemPressure,
201  CRSMatrixView< real64, globalIndex const > const & localMatrix,
202  arrayView1d< real64 > const & localRhs );
203 
204 };
205 
206 
207 /******************************** PerforationKernel ********************************/
208 
210 {
211 
213 
216 
217  using SingleFluidAccessors =
218  StencilMaterialAccessors< constitutive::SingleFluidBase,
219  fields::singlefluid::density,
220  fields::singlefluid::dDensity,
221  fields::singlefluid::viscosity,
222  fields::singlefluid::dViscosity >;
223 
231  template< typename VIEWTYPE >
233 
234  template< integer IS_THERMAL >
236  inline
237  static
238  void
239  compute( real64 const & resPressure,
240  real64 const & resDensity,
241  arraySlice1d< real64 const > const & dResDensity,
242  real64 const & resViscosity,
243  arraySlice1d< real64 const > const & dResViscosity,
244  real64 const & wellElemGravCoef,
245  real64 const & wellElemPressure,
246  real64 const & wellElemDensity,
247  arraySlice1d< real64 const > const & dWellElemDensity,
248  real64 const & wellElemViscosity,
249  arraySlice1d< real64 const > const & dWellElemViscosity,
250  real64 const & perfGravCoef,
251  real64 const & trans,
252  real64 & perfRate,
253  arraySlice2d< real64 > const & dPerfRate,
254  arraySlice1d< real64 > const & dPerfRate_dPres );
255 
256  template< integer IS_THERMAL >
257  static void
258  launch( localIndex const size,
259  ElementViewConst< arrayView1d< real64 const > > const & resPressure,
264  arrayView1d< real64 const > const & wellElemGravCoef,
265  arrayView1d< real64 const > const & wellElemPressure,
270  arrayView1d< real64 const > const & perfGravCoef,
271  arrayView1d< localIndex const > const & perfWellElemIndex,
272  arrayView1d< real64 const > const & perfTransmissibility,
273  arrayView1d< localIndex const > const & resElementRegion,
274  arrayView1d< localIndex const > const & resElementSubRegion,
275  arrayView1d< localIndex const > const & resElementIndex,
276  arrayView1d< real64 > const & perfRate,
277  arrayView3d< real64 > const & dPerfRate );
278 
279 };
280 
281 /******************************** AccumulationKernel ********************************/
282 
284 {
285 
288 
289  static void
290  launch( localIndex const size,
291  globalIndex const rankOffset,
292  arrayView1d< globalIndex const > const & wellElemDofNumber,
293  arrayView1d< integer const > const & wellElemGhostRank,
294  arrayView1d< real64 const > const & wellElemVolume,
298  CRSMatrixView< real64, globalIndex const > const & localMatrix,
299  arrayView1d< real64 > const & localRhs );
300 
301 };
302 
303 /******************************** ElementBasedAssemblyKernel ********************************/
304 
310 template< integer IS_THERMAL >
312 {
313 public:
314 
315  // Well jacobian column and row indicies
316  using FLUID_PROP_COFFSET = constitutive::singlefluid::DerivativeOffsetC< IS_THERMAL >;
319 
321  static constexpr integer numDof = 1 + IS_THERMAL; // tjb review
322 
324  static constexpr integer numEqn = 2 + IS_THERMAL;
325 
326 
338  string const dofKey,
339  WellElementSubRegion const & subRegion,
340  constitutive::SingleFluidBase const & fluid,
341  CRSMatrixView< real64, globalIndex const > const & localMatrix,
342  arrayView1d< real64 > const & localRhs )
343  : m_rankOffset( rankOffset ),
344  m_iwelemControl( subRegion.getTopWellElementIndex() ),
345  m_dofNumber( subRegion.getReference< array1d< globalIndex > >( dofKey ) ),
346  m_elemGhostRank( subRegion.ghostRank() ),
347  m_wellElemVolume( subRegion.getElementVolume() ),
348  m_wellElemDensity( fluid.density() ),
349  m_dWellElemDensity( fluid.dDensity() ),
350  m_wellElemDensity_n( fluid.density_n() ),
351  m_localMatrix( localMatrix ),
352  m_localRhs( localRhs )
353  {}
354 
355 
362  integer elemGhostRank( localIndex const ei ) const
363  { return m_elemGhostRank( ei ); }
364 
365 
366 
374  template< typename FUNC = NoOpFunc >
376  void computeAccumulation( localIndex const iwelem,
377  FUNC && kernelOp = NoOpFunc{} ) const
378  {
379 
380  localIndex const eqnRowIndex = m_dofNumber[iwelem] + WJ_ROFFSET::MASSBAL - m_rankOffset;
381  globalIndex const presDofColIndex = m_dofNumber[iwelem] + WJ_COFFSET::dP;
382 
383  real64 const localAccum = m_wellElemVolume[iwelem] * ( m_wellElemDensity[iwelem][0] - m_wellElemDensity_n[iwelem][0] );
384  real64 const localAccumDP = m_wellElemVolume[iwelem] * m_dWellElemDensity[iwelem][0][FLUID_PROP_COFFSET::dP];
385 
386  // add contribution to global residual and jacobian (no need for atomics here)
387  m_localMatrix.addToRow< serialAtomic >( eqnRowIndex, &presDofColIndex, &localAccumDP, 1 );
388  m_localRhs[eqnRowIndex] += localAccum;
389 
390  if constexpr ( IS_THERMAL )
391  {
392  real64 const localAccumDT = m_wellElemVolume[iwelem] * m_dWellElemDensity[iwelem][0][FLUID_PROP_COFFSET::dT];
393  globalIndex const tempDofColIndex = m_dofNumber[iwelem] + WJ_COFFSET::dT;
394  m_localMatrix.addToRow< serialAtomic >( eqnRowIndex, &tempDofColIndex, &localAccumDT, 1 );
395  kernelOp( presDofColIndex, tempDofColIndex );
396  }
397 
398  }
399 
400 
401 
409  template< typename POLICY, typename KERNEL_TYPE >
410  static void
411  launch( localIndex const numElems,
412  KERNEL_TYPE const & kernelComponent )
413  {
415 
416  forAll< POLICY >( numElems, [=] GEOS_HOST_DEVICE ( localIndex const iwelem )
417  {
418  if( kernelComponent.elemGhostRank( iwelem ) >= 0 )
419  {
420  return;
421  }
422  kernelComponent.computeAccumulation( iwelem );
423  } );
424  }
425 
426 protected:
427 
430 
433 
436 
439 
442 
447 
452 
453 };
454 
459 {
460 public:
471  template< typename POLICY >
472  static void
473  createAndLaunch( globalIndex const rankOffset,
474  string const dofKey,
475  WellElementSubRegion const & subRegion,
476  constitutive::SingleFluidBase const & fluid,
477  CRSMatrixView< real64, globalIndex const > const & localMatrix,
478  arrayView1d< real64 > const & localRhs )
479  {
480  integer constexpr isThermal=0;
481 
483  kernel( rankOffset, dofKey, subRegion, fluid, localMatrix, localRhs );
485  launch< POLICY, ElementBasedAssemblyKernel< isThermal > >( subRegion.size(), kernel );
486  }
487 };
488 
489 /******************************** PressureTemperatyrInitializationKernel ********************************/
490 
491 // tjb make this templated on thermal
493 {
494 
496  StencilAccessors< fields::flow::pressure,
497  fields::flow::temperature >;
498 
499  using SingleFluidAccessors =
500  StencilMaterialAccessors< constitutive::SingleFluidBase,
501  fields::singlefluid::density >;
502 
510  template< typename VIEWTYPE >
512 
513  static void
514  launch( integer const isThermal,
515  localIndex const perforationSize,
516  localIndex const subRegionSize,
517  localIndex const numPerforations,
518  WellControls const & wellControls,
519  real64 const & currentTime,
520  ElementViewConst< arrayView1d< real64 const > > const & resPressure,
521  ElementViewConst< arrayView1d< real64 const > > const & resTemperature,
523  arrayView1d< localIndex const > const & resElementRegion,
524  arrayView1d< localIndex const > const & resElementSubRegion,
525  arrayView1d< localIndex const > const & resElementIndex,
526  arrayView1d< real64 const > const & perfGravCoef,
527  arrayView1d< real64 const > const & wellElemGravCoef,
528  arrayView1d< real64 > const & wellElemPressure,
529  arrayView1d< real64 > const & wellElemTemperature );
530 
531 };
532 
533 /******************************** FaceBasedAssemblyKernel ********************************/
541 template< integer IS_THERMAL >
543 {
544 public:
545 
549 
550  using FLUID_PROP_COFFSET = constitutive::singlefluid::DerivativeOffsetC< IS_THERMAL >;
553 
554  using CP_Deriv = constitutive::singlefluid::DerivativeOffsetC< IS_THERMAL >;
555 
557  static constexpr integer numDof = WJ_COFFSET::nDer; // tjb revisit
558 
560  static constexpr integer numEqn = WJ_COFFSET::nDer;// tjb revisit
561 
562  static constexpr integer maxNumElems = 2;
563  static constexpr integer maxStencilSize = 2;
575  globalIndex const rankOffset,
576  string const wellDofKey,
577  WellControls const & wellControls,
578  WellElementSubRegion const & subRegion,
579  CRSMatrixView< real64, globalIndex const > const & localMatrix,
580  arrayView1d< real64 > const & localRhs )
581  :
582  m_dt( dt ),
583  m_rankOffset( rankOffset ),
584  m_wellElemDofNumber ( subRegion.getReference< array1d< globalIndex > >( wellDofKey ) ),
585  m_nextWellElemIndex ( subRegion.getReference< array1d< localIndex > >( WellElementSubRegion::viewKeyStruct::nextWellElementIndexString()) ),
586  m_connRate ( subRegion.getField< fields::well::connectionRate >() ),
587  m_localMatrix( localMatrix ),
588  m_localRhs ( localRhs ),
589  m_isProducer ( wellControls.isProducer() )
590  {}
591 
592 
600  template< typename FUNC = NoOpFunc >
602  inline
603  void computeFlux( localIndex const iwelem,
604  FUNC && compFluxKernelOp = NoOpFunc{} ) const
605  {
606  // 1) Compute the flux and its derivatives
607 
608  /* currentConnRate < 0 flow from iwelem to iwelemNext
609  * currentConnRate > 0 flow from iwelemNext to iwelem
610  * With this convention, currentConnRate < 0 at the last connection for a producer
611  * currentConnRate > 0 at the last connection for a injector
612  */
613 
614  // get next well element index
615  localIndex const iwelemNext = m_nextWellElemIndex[iwelem];
616 
617  // there is nothing to upwind for single-phase flow
618  real64 const currentConnRate = m_connRate[iwelem];
619  real64 const flux = m_dt * currentConnRate;
620  real64 const dFlux_dRate = m_dt;
621 
622  // 2) Assemble the flux into residual and Jacobian
623  if( iwelemNext < 0 )
624  {
625  // flux terms
626  real64 const oneSidedLocalFlux = -flux;
627  real64 const oneSidedLocalFluxJacobian_dRate = -dFlux_dRate;
628 
629  // jacobian indices
630  globalIndex const oneSidedEqnRowIndex = m_wellElemDofNumber[iwelem] + ROFFSET::MASSBAL - m_rankOffset;
631  globalIndex const oneSidedDofColIndex_dRate = m_wellElemDofNumber[iwelem] + COFFSET::DRATE;
632 
633  if( oneSidedEqnRowIndex >= 0 && oneSidedEqnRowIndex < m_localMatrix.numRows() )
634  {
635  m_localMatrix.addToRow< parallelDeviceAtomic >( oneSidedEqnRowIndex,
636  &oneSidedDofColIndex_dRate,
637  &oneSidedLocalFluxJacobian_dRate,
638  1 );
639  RAJA::atomicAdd( parallelDeviceAtomic{}, &m_localRhs[oneSidedEqnRowIndex], oneSidedLocalFlux );
640  }
641  }
642  else
643  {
644  // local working variables and arrays
645  globalIndex eqnRowIndices[2]{};
646 
647  real64 localFlux[2]{};
648  real64 localFluxJacobian_dRate[2]{};
649 
650  // flux terms
651  localFlux[TAG::NEXT] = flux;
652  localFlux[TAG::CURRENT] = -flux;
653 
654  localFluxJacobian_dRate[TAG::NEXT] = dFlux_dRate;
655  localFluxJacobian_dRate[TAG::CURRENT] = -dFlux_dRate;
656 
657  // indices
658  eqnRowIndices[TAG::CURRENT] = m_wellElemDofNumber[iwelem] + ROFFSET::MASSBAL - m_rankOffset;
659  eqnRowIndices[TAG::NEXT] = m_wellElemDofNumber[iwelemNext] + ROFFSET::MASSBAL - m_rankOffset;
660  globalIndex const dofColIndex_dRate = m_wellElemDofNumber[iwelem] + COFFSET::DRATE;
661 
662  for( localIndex i = 0; i < 2; ++i )
663  {
664  if( eqnRowIndices[i] >= 0 && eqnRowIndices[i] < m_localMatrix.numRows() )
665  {
666  m_localMatrix.addToRow< parallelDeviceAtomic >( eqnRowIndices[i],
667  &dofColIndex_dRate,
668  &localFluxJacobian_dRate[i],
669  1 );
670  RAJA::atomicAdd( parallelDeviceAtomic{}, &m_localRhs[eqnRowIndices[i]], localFlux[i] );
671  }
672  }
673  }
674  compFluxKernelOp( iwelemNext, currentConnRate );
675 
676  }
677 
678 
686  template< typename POLICY, typename KERNEL_TYPE >
687  static void
688  launch( localIndex const numElements,
689  KERNEL_TYPE const & kernelComponent )
690  {
692  forAll< POLICY >( numElements, [=] GEOS_HOST_DEVICE ( localIndex const ie )
693  {
694  kernelComponent.computeFlux( ie );
695  } );
696  }
697 
698 protected:
700  real64 const m_dt;
703 
708 
711 
714 
719 
721  bool const m_isProducer;
722 
723 };
724 
729 {
730 public:
731 
743  template< typename POLICY >
744  static void
746  globalIndex const rankOffset,
747  string const dofKey,
748  WellControls const & wellControls,
749  WellElementSubRegion const & subRegion,
750  CRSMatrixView< real64, globalIndex const > const & localMatrix,
751  arrayView1d< real64 > const & localRhs )
752  {
753  integer isThermal=0;
754  geos::internal::kernelLaunchSelectorThermalSwitch( isThermal, [&]( auto IS_THERMAL )
755  {
756 
757  integer constexpr istherm = IS_THERMAL();
758 
759  using kernelType = FaceBasedAssemblyKernel< istherm >;
760  kernelType kernel( dt, rankOffset, dofKey, wellControls, subRegion, localMatrix, localRhs );
761  kernelType::template launch< POLICY >( subRegion.size(), kernel );
762  } );
763  }
764 };
765 /******************************** RateInitializationKernel ********************************/
766 
768 {
769 
770  static void
771  launch( localIndex const subRegionSize,
772  WellControls const & wellControls,
773  real64 const & currentTime,
775  arrayView1d< real64 > const & connRate );
776 
777 };
778 
779 
780 /******************************** ResidualNormKernel ********************************/
781 
786 {
787 public:
788 
790  using Base::m_minNormalizer;
791  using Base::m_rankOffset;
792  using Base::m_localResidual;
793  using Base::m_dofNumber;
794 
795  ResidualNormKernel( globalIndex const rankOffset,
796  arrayView1d< real64 const > const & localResidual,
797  arrayView1d< globalIndex const > const & dofNumber,
799  WellElementSubRegion const & subRegion,
800  constitutive::SingleFluidBase const & fluid,
801  WellControls const & wellControls,
802  real64 const time,
803  real64 const dt,
804  real64 const minNormalizer )
805  : Base( rankOffset,
806  localResidual,
807  dofNumber,
808  ghostRank,
809  minNormalizer ),
810  m_dt( dt ),
811  m_isLocallyOwned( subRegion.isLocallyOwned() ),
813  m_currentControl( wellControls.getControl() ),
814  m_targetBHP( wellControls.getTargetBHP( time ) ),
815  m_targetRate( wellControls.getTargetTotalRate( time ) ),
816  m_targetMassRate( wellControls.getTargetMassRate( time ) ),
817  m_volume( subRegion.getElementVolume() ),
818  m_density_n( fluid.density_n() )
819  {}
820 
822  virtual void computeLinf( localIndex const iwelem,
823  LinfStackVariables & stack ) const override
824  {
825  for( localIndex idof = 0; idof < 2; ++idof )
826  {
827  real64 normalizer = 0.0;
828  if( idof == singlePhaseWellKernels::RowOffset::CONTROL )
829  {
830  // for the top well element, normalize using the current control
831  if( m_isLocallyOwned && iwelem == m_iwelemControl )
832  {
834  {
835  // this residual entry is in pressure units
836  normalizer = m_targetBHP;
837  }
839  {
840  // this residual entry is in volume / time units
841  normalizer = LvArray::math::max( LvArray::math::abs( m_targetRate ), m_minNormalizer );
842  }
844  {
845  // the residual entry is in volume / time units
846  normalizer = LvArray::math::max( LvArray::math::abs( m_targetMassRate ), m_minNormalizer );
847  }
848  }
849  // for the pressure difference equation, always normalize by the BHP
850  else
851  {
852  // this residual is in pressure units
853  normalizer = m_targetBHP;
854  }
855  }
856  else // SinglePhaseWell::RowOffset::MASSBAL
857  {
858  // this residual entry is in mass units
859  normalizer = m_dt * LvArray::math::abs( m_targetRate ) * m_density_n[iwelem][0];
860 
861  // to make sure that everything still works well if the rate is zero, we add this check
862  normalizer = LvArray::math::max( normalizer, m_volume[iwelem] * m_density_n[iwelem][0] );
863  }
864 
865  // we have the normalizer now, we can compute a dimensionless Linfty norm contribution
866  real64 const val = LvArray::math::abs( m_localResidual[stack.localRow + idof] ) / normalizer;
867  if( val > stack.localValue[0] )
868  {
869  stack.localValue[0] = val;
870  }
871 
872  }
873  }
874 
876  virtual void computeL2( localIndex const iwelem,
877  L2StackVariables & stack ) const override
878  {
879  GEOS_UNUSED_VAR( iwelem, stack );
880  GEOS_ERROR( "The L2 norm is not implemented for SinglePhaseWell" );
881  }
882 
883 
884 protected:
885 
887  real64 const m_dt;
888 
890  bool const m_isLocallyOwned;
891 
894 
897  real64 const m_targetBHP;
898  real64 const m_targetRate;
899  real64 const m_targetMassRate;
900 
903 
906 
907 };
908 
913 {
914 public:
915 
929  template< typename POLICY >
930  static void
931  createAndLaunch( globalIndex const rankOffset,
932  string const & dofKey,
933  arrayView1d< real64 const > const & localResidual,
934  WellElementSubRegion const & subRegion,
935  constitutive::SingleFluidBase const & fluid,
936  WellControls const & wellControls,
937  real64 const time,
938  real64 const dt,
939  real64 const minNormalizer,
940  real64 (& residualNorm)[1] )
941  {
942  arrayView1d< globalIndex const > const dofNumber = subRegion.getReference< array1d< globalIndex > >( dofKey );
943  arrayView1d< integer const > const ghostRank = subRegion.ghostRank();
944 
945  ResidualNormKernel kernel( rankOffset, localResidual, dofNumber, ghostRank, subRegion, fluid, wellControls, time, dt, minNormalizer );
946  ResidualNormKernel::launchLinf< POLICY >( subRegion.size(), kernel, residualNorm );
947  }
948 
949 };
950 
951 } // end namespace singlePhaseWellKernels
952 
953 } // end namespace geos
954 
955 #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
#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 &currentTime) const
Get the target total rate.
real64 getTargetMassRate(real64 const &currentTime) const
Get the target mass 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, 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.
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.
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.
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.
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:188
LvArray::CRSMatrixView< T, COL_INDEX, localIndex const, LvArray::ChaiBuffer > CRSMatrixView
Alias for CRS Matrix View.
Definition: DataTypes.hpp:318
GEOS_GLOBALINDEX_TYPE globalIndex
Global index type (for indexing objects across MPI partitions).
Definition: DataTypes.hpp:87
ArraySlice< T, 2, USD > arraySlice2d
Alias for 2D array slice.
Definition: DataTypes.hpp:208
double real64
64-bit floating point type.
Definition: DataTypes.hpp:98
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:84
ArraySlice< T, 1, USD > arraySlice1d
Alias for 1D array slice.
Definition: DataTypes.hpp:192
std::int32_t integer
Signed integer type.
Definition: DataTypes.hpp:81
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.
Definition: DataTypes.hpp:204
Array< T, 1 > array1d
Alias for 1D array.
Definition: DataTypes.hpp:184
ArrayView< T, 3, USD > arrayView3d
Alias for 3D array view.
Definition: DataTypes.hpp:220
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.