GEOS
ThermalSinglePhaseWellKernels.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_THERMALSINGLEPHASEWELLKERNELS_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_WELLS_THERMALSINGLEPHASEWELLKERNELS_HPP
22 
23 #include "constitutive/fluid/singlefluid/SingleFluidFields.hpp"
24 #include "constitutive/fluid/singlefluid/SingleFluidBase.hpp"
25 #include "common/DataTypes.hpp"
26 #include "common/GEOS_RAJA_Interface.hpp"
30 #include "physicsSolvers/fluidFlow/wells/WellControls.hpp"
32 
33 namespace geos
34 {
35 
36 namespace thermalSinglePhaseWellKernels
37 {
38 
39 
40 
41 /******************************** ElementBasedAssemblyKernel ********************************/
42 
48 template< integer IS_THERMAL >
50 {
51 public:
52 
53  // Well jacobian column and row indicies
54  using FLUID_PROP_COFFSET = constitutive::singlefluid::DerivativeOffsetC< IS_THERMAL >;
57 
59  using Base::m_rankOffset;
60  using Base::m_dofNumber;
64  using Base::m_wellElemDensity_n;
65  using Base::m_dWellElemDensity;
66  using Base::m_localMatrix;
67  using Base::m_localRhs;
68 
80  globalIndex const rankOffset,
81  string const dofKey,
82  WellElementSubRegion const & subRegion,
83  constitutive::SingleFluidBase const & fluid,
85  arrayView1d< real64 > const & localRhs )
86  : Base( rankOffset, dofKey, subRegion, fluid, localMatrix, localRhs ),
87  m_isProducer( isProducer ),
88  m_iwelemControl( subRegion.getTopWellElementIndex() ),
89  m_internalEnergy( fluid.internalEnergy() ),
90  m_internalEnergy_n( fluid.internalEnergy_n() ),
91  m_dInternalEnergy( fluid.dInternalEnergy() )
92  {}
93 
105  integer elemGhostRank( localIndex const iwelem ) const
106  { return m_elemGhostRank( iwelem ); }
107 
108 
114  template< typename FUNC = NoOpFunc >
116  void computeAccumulation( localIndex const iwelem ) const
117  {
118  Base::computeAccumulation( iwelem, [&]( globalIndex const presDofColIndex, globalIndex const tempDofColIndex )
119  {
120  // assemble the accumulation term of the energy equation
121  localIndex const eqnRowIndex = m_dofNumber[iwelem] + WJ_ROFFSET::ENERGYBAL - m_rankOffset;
122  real64 localEnergyAccum;
123  real64 localEnergyAccumDP;
124  real64 localEnergyAccumDT;
125  if( iwelem == m_iwelemControl && !m_isProducer )
126  {
127  // For top segment energy balance eqn replaced with T(n+1) - T = 0
128  // No other energy balance derivatives
129  // Assumption is global index == 0 is top segment with fixed temp BC
130 
131  localEnergyAccum = 0.0;
132  localEnergyAccumDT = 1.0;
133  localEnergyAccumDP = 0.0;
134  }
135  else
136  {
137  localEnergyAccum = m_wellElemVolume[iwelem] * ( m_wellElemDensity[iwelem][0]*m_internalEnergy[iwelem][0] - m_wellElemDensity_n[iwelem][0]*m_internalEnergy_n[iwelem][0]);
138  localEnergyAccumDP = m_wellElemVolume[iwelem] *(m_internalEnergy[iwelem][0] *m_dWellElemDensity[iwelem][0][FLUID_PROP_COFFSET::dP] +
139  m_wellElemDensity[iwelem][0]*m_dInternalEnergy[iwelem][0][FLUID_PROP_COFFSET::dP]);
140  localEnergyAccumDT = m_wellElemVolume[iwelem] *(m_internalEnergy[iwelem][0] *m_dWellElemDensity[iwelem][0][FLUID_PROP_COFFSET::dT] +
141  m_wellElemDensity[iwelem][0]*m_dInternalEnergy[iwelem][0][FLUID_PROP_COFFSET::dT]);
142  }
143  m_localRhs[eqnRowIndex] = localEnergyAccum;
144  m_localMatrix.template addToRow< serialAtomic >( eqnRowIndex, &presDofColIndex, &localEnergyAccumDP, 1 );
145  m_localMatrix.template addToRow< serialAtomic >( eqnRowIndex, &tempDofColIndex, &localEnergyAccumDT, 1 );
146 
147  } );
148  }
149 
150 
151 
159  template< typename POLICY, typename KERNEL_TYPE >
160  static void
161  launch( localIndex const numElems,
162  KERNEL_TYPE const & kernelComponent )
163  {
165 
166  forAll< POLICY >( numElems, [=] GEOS_HOST_DEVICE ( localIndex const iwelem )
167  {
168  if( kernelComponent.elemGhostRank( iwelem ) >= 0 )
169  {
170  return;
171  }
172  kernelComponent.computeAccumulation( iwelem );
173  } );
174  }
175 
176 protected:
185 
186 };
187 
188 
193 {
194 public:
206  template< typename POLICY >
207  static void
208  createAndLaunch( integer const isProducer,
209  globalIndex const rankOffset,
210  string const dofKey,
211  WellElementSubRegion const & subRegion,
212  constitutive::SingleFluidBase const & fluid,
213  CRSMatrixView< real64, globalIndex const > const & localMatrix,
214  arrayView1d< real64 > const & localRhs )
215  {
216  integer constexpr isThermal = 1;
218  kernel( isProducer, rankOffset, dofKey, subRegion, fluid, localMatrix, localRhs );
220  launch< POLICY, ElementBasedAssemblyKernel< isThermal > >( subRegion.size(), kernel );
221 
222  }
223 };
224 
225 /******************************** FaceBasedAssemblyKernel ********************************/
226 
232 template< integer IS_THERMAL >
234 {
235 public:
236 
238 
239  // Well jacobian column and row indicies
240 
241  using FLUID_PROP_COFFSET = constitutive::singlefluid::DerivativeOffsetC< IS_THERMAL >;
245 
246 
247  using Base::m_isProducer;
248  using Base::m_dt;
249  using Base::m_localRhs;
250  using Base::m_localMatrix;
251  using Base::m_rankOffset;
253  using Base::maxNumElems;
254  using Base::maxStencilSize;
255 
256 
258  static constexpr integer numDof = WJ_COFFSET::nDer;
259 
261  static constexpr integer numEqn = WJ_ROFFSET::nEqn - 2;
262 
275  globalIndex const rankOffset,
276  string const wellDofKey,
277  WellControls const & wellControls,
278  WellElementSubRegion const & subRegion,
279  constitutive::SingleFluidBase const & fluid,
280  CRSMatrixView< real64, globalIndex const > const & localMatrix,
281  arrayView1d< real64 > const & localRhs )
282  : Base( dt
283  , rankOffset
284  , wellDofKey
285  , wellControls
286  , subRegion
287  , localMatrix
288  , localRhs ),
289 
290  m_globalWellElementIndex( subRegion.getGlobalWellElementIndex() ),
291  m_enthalpy( fluid.enthalpy()),
292  m_dEnthalpy( fluid.dEnthalpy())
293  { }
294 
304  inline
305  void computeFlux( localIndex const iwelem ) const
306  {
307  Base::computeFlux ( iwelem, [&] ( localIndex const & iwelemNext
308  , real64 const & currentConnRate )
309  {
310  if( iwelemNext < 0 )
311  {
312  globalIndex dofRowIndices = m_wellElemDofNumber[iwelem] + WJ_ROFFSET::ENERGYBAL - m_rankOffset;
313 
314  if( dofRowIndices >= 0 && dofRowIndices < m_localMatrix.numRows() )
315  {
316  globalIndex dofColIndices_dRate = m_wellElemDofNumber[iwelem] + WJ_COFFSET::dQ;
317  globalIndex dofColIndices[FLUID_PROP_COFFSET::nDer]{};
318  dofColIndices[0]= m_wellElemDofNumber[iwelem] + WJ_COFFSET::dP;
319  dofColIndices[1]= m_wellElemDofNumber[iwelem] + WJ_COFFSET::dT;
320 
321  real64 localEnergyFlux[1]{};
322  real64 localEnergyFluxJacobian_dQ[1]{};
323  real64 localEnergyFluxJacobian[numDof]{};
324 
325  real64 eflux = -m_dt * m_enthalpy[iwelem][0];
326  localEnergyFlux[0]= eflux * currentConnRate;
327  localEnergyFluxJacobian_dQ[0] = -m_dt *m_enthalpy[iwelem][0];
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];
330  if( !m_isProducer && m_globalWellElementIndex[iwelem] == 0 )
331  {
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;
336  }
337 
338  m_localMatrix.template addToRow< parallelDeviceAtomic >( dofRowIndices,
339  &dofColIndices_dRate,
340  localEnergyFluxJacobian_dQ,
341  1 );
342  m_localMatrix.template addToRowBinarySearchUnsorted< parallelDeviceAtomic >( dofRowIndices,
343  dofColIndices,
344  localEnergyFluxJacobian,
345  FLUID_PROP_COFFSET::nDer );
346  RAJA::atomicAdd( parallelDeviceAtomic{}, &m_localRhs[dofRowIndices], localEnergyFlux[0] );
347  }
348  }
349  else
350  {
351  globalIndex row_current = m_wellElemDofNumber[iwelem] + WJ_ROFFSET::ENERGYBAL - m_rankOffset;
352  globalIndex row_next = m_wellElemDofNumber[iwelemNext] + WJ_ROFFSET::ENERGYBAL - m_rankOffset;
353 
354  // Setup Jacobian global row indicies
355  // equations for ENERGY balances
356  globalIndex eqnRowIndices[2]{};
357  eqnRowIndices[TAG::CURRENT ] = row_current;
358  eqnRowIndices[TAG::NEXT ] = row_next;
359 
360  // Setup Jacobian global col indicies ( Mapping from local jac order to well jac order)
361  globalIndex dofColIndices[FLUID_PROP_COFFSET::nDer]{};
362  dofColIndices[0]= m_wellElemDofNumber[iwelem] + WJ_COFFSET::dP;
363  dofColIndices[1]= m_wellElemDofNumber[iwelem] + WJ_COFFSET::dT;
364 
365  globalIndex dofColIndices_dRate = m_wellElemDofNumber[iwelem] + WJ_COFFSET::dQ;
366 
367  real64 localEnergyFlux[2]{};
368  real64 localEnergyFluxJacobian_dQ[2][1]{};
369  real64 localEnergyFluxJacobian[2][numDof]{};
370 
371  real64 eflux = m_dt * m_enthalpy[iwelem][0];
372  real64 eflux_dq = m_dt * m_enthalpy[iwelem][0];
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];
375 
376  if( !m_isProducer && m_globalWellElementIndex[iwelemNext] == 0 )
377  {
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;
382  }
383  else
384  {
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;
389  }
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;
394 
395  // Note this updates diag and offdiag
396  for( integer i = 0; i < 2; ++i )
397  {
398  if( eqnRowIndices[i] >= 0 && eqnRowIndices[i] < m_localMatrix.numRows() )
399  {
400  m_localMatrix.template addToRow< parallelDeviceAtomic >( eqnRowIndices[i],
401  &dofColIndices_dRate,
402  localEnergyFluxJacobian_dQ[i],
403  1 );
404  m_localMatrix.template addToRowBinarySearchUnsorted< parallelDeviceAtomic >( eqnRowIndices[i],
405  dofColIndices,
406  localEnergyFluxJacobian[i],
407  FLUID_PROP_COFFSET::nDer );
408  RAJA::atomicAdd( parallelDeviceAtomic{}, &m_localRhs[eqnRowIndices[i]], localEnergyFlux[i] );
409  }
410  }
411  }
412 
413  } );
414 
415  }
416 
417 
426  template< typename POLICY, typename KERNEL_TYPE >
427  static void
428  launch( localIndex const numElements,
429  KERNEL_TYPE const & kernelComponent )
430  {
432  forAll< POLICY >( numElements, [=] GEOS_HOST_DEVICE ( localIndex const ie )
433  {
434  kernelComponent.computeFlux( ie );
435 
436  } );
437  }
438 
439 protected:
440 
443 
447 };
448 
453 {
454 public:
455 
467  template< typename POLICY >
468  static void
470  real64 const dt,
471  globalIndex const rankOffset,
472  string const dofKey,
473  WellControls const & wellControls,
474  WellElementSubRegion const & subRegion,
475  constitutive::SingleFluidBase const & fluid,
476  CRSMatrixView< real64, globalIndex const > const & localMatrix,
477  arrayView1d< real64 > const & localRhs )
478  {
479  integer constexpr isThermal=1;
480  using kernelType = FaceBasedAssemblyKernel< isThermal >;
481  kernelType kernel( dt, rankOffset, dofKey, wellControls, subRegion, fluid, localMatrix, localRhs );
482  kernelType::template launch< POLICY >( subRegion.size(), kernel );
483  }
484 };
485 
486 /******************************** ResidualNormKernel ********************************/
487 
493 {
494 public:
495 
496 
498 
500  using Base::m_minNormalizer;
501  using Base::m_rankOffset;
502  using Base::m_localResidual;
503  using Base::m_dofNumber;
504 
505  ResidualNormKernel( globalIndex const rankOffset,
506  arrayView1d< real64 const > const & localResidual,
507  arrayView1d< globalIndex const > const & dofNumber,
508  arrayView1d< localIndex const > const & ghostRank,
509  WellElementSubRegion const & subRegion,
510  constitutive::SingleFluidBase const & fluid,
511  WellControls const & wellControls,
512  real64 const time,
513  real64 const dt,
514  real64 const minNormalizer )
515  : Base( rankOffset,
516  localResidual,
517  dofNumber,
518  ghostRank,
519  minNormalizer ),
520  m_dt( dt ),
521  m_isLocallyOwned( subRegion.isLocallyOwned() ),
522  m_iwelemControl( subRegion.getTopWellElementIndex() ),
523  m_isProducer( wellControls.isProducer() ),
524  m_currentControl( wellControls.getControl() ),
525  m_targetBHP( wellControls.getTargetBHP( time ) ),
526  m_targetRate( wellControls.getTargetTotalRate( time ) ),
527  m_targetMassRate( wellControls.getTargetMassRate( time ) ),
528  m_volume( subRegion.getElementVolume() ),
529  m_density_n( fluid.density_n() ),
530 
531  m_internalEnergy_n( fluid.internalEnergy_n() )
532  {}
533 
534 
536  void computeMassEnergyNormalizers( localIndex const iwelem,
537  real64 & massNormalizer,
538  real64 & energyNormalizer ) const
539  {
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];
542 
543  // warning: internal energy can be negative
544  energyNormalizer = LvArray::math::max( m_minNormalizer, LvArray::math::abs( energyNormalizer ) );
545  }
546 
548  virtual void computeLinf( localIndex const iwelem,
549  LinfStackVariables & stack ) const override
550  {
551  real64 normalizer = 0.0;
552  for( integer idof = 0; idof < WJ_ROFFSET::nEqn; ++idof )
553  {
554  // Step 1: compute a normalizer for the control or pressure equation
555 
556  // for the control equation, we distinguish two cases
557  if( idof == WJ_ROFFSET::CONTROL )
558  {
559 
560  // for the top well element, normalize using the current control
561  if( m_isLocallyOwned && iwelem == m_iwelemControl )
562  {
563  if( m_currentControl == WellControls::Control::BHP )
564  {
565  // the residual entry is in pressure units
566  normalizer = m_targetBHP;
567  }
568  else if( m_currentControl == WellControls::Control::TOTALVOLRATE )
569  {
570  // the residual entry is in volume / time units
571  normalizer = LvArray::math::max( LvArray::math::abs( m_targetRate ), m_minNormalizer );
572  }
573  else if( m_currentControl == WellControls::Control::MASSRATE )
574  {
575  // the residual entry is in volume / time units
576  normalizer = LvArray::math::max( LvArray::math::abs( m_targetMassRate ), m_minNormalizer );
577  }
578  }
579  // for the pressure difference equation, always normalize by the BHP
580  else
581  {
582  normalizer = m_targetBHP;
583  }
584  }
585  // Step 2: compute a normalizer for the mass balance equation
586  else if( idof == WJ_ROFFSET::MASSBAL )
587  {
588 
589  // this residual entry is in mass units
590  normalizer = m_dt * LvArray::math::abs( m_targetRate ) * m_density_n[iwelem][0];
591 
592  // to make sure that everything still works well if the rate is zero, we add this check
593  normalizer = LvArray::math::max( normalizer, m_volume[iwelem] * m_density_n[iwelem][0] );
594 
595 
596  // we have the normalizer now, we can compute a dimensionless Linfty norm contribution
597  real64 const val = LvArray::math::abs( m_localResidual[stack.localRow + idof] ) / normalizer;
598  if( val > stack.localValue[0] )
599  {
600  stack.localValue[0] = val;
601  }
602 
603  }
604  // step 3: energy residual
605  else if( idof == WJ_ROFFSET::ENERGYBAL )
606  {
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] )
611  {
612  stack.localValue[1] = valEnergy;
613  }
614  }
615  }
616  }
617 
619  virtual void computeL2( localIndex const iwelem,
620  L2StackVariables & stack ) const override
621  {
622  GEOS_UNUSED_VAR( iwelem, stack );
623  GEOS_ERROR( "The L2 norm is not implemented for SinglePhaseWell" );
624  }
625 
626 
627 protected:
628 
630  real64 const m_dt;
631 
633  bool const m_isLocallyOwned;
634 
637 
639  bool const m_isProducer;
640 
643  real64 const m_targetBHP;
644  real64 const m_targetRate;
645  real64 const m_targetMassRate;
646 
649 
653 
654 };
655 
656 /*
657  *@class ResidualNormKernelFactory
658  */
660 {
661 public:
662 
679  template< typename POLICY >
680  static void
681  createAndLaunch( globalIndex const rankOffset,
682  string const & dofKey,
683  arrayView1d< real64 const > const & localResidual,
684  WellElementSubRegion const & subRegion,
685  constitutive::SingleFluidBase const & fluid,
686  WellControls const & wellControls,
687  real64 const time,
688  real64 const dt,
689  real64 const minNormalizer,
690  real64 (& residualNorm)[2] )
691  {
692  using kernelType = ResidualNormKernel;
693  arrayView1d< globalIndex const > const dofNumber = subRegion.getReference< array1d< globalIndex > >( dofKey );
694  arrayView1d< integer const > const ghostRank = subRegion.ghostRank();
695 
696  kernelType kernel( rankOffset, localResidual, dofNumber, ghostRank,
697  subRegion, fluid, wellControls, time, dt, minNormalizer );
698  kernelType::template launchLinf< POLICY >( subRegion.size(), kernel, residualNorm );
699 
700  }
701 
702 };
703 
704 } // end namespace singlePhaseWellKernels
705 
706 } // end namespace geos
707 
708 #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.
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 &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.
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.
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.
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< 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.
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.
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.
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.
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.
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.
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
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
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