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_constraintValue ( wellControls.getCurrentConstraint()->getConstraintValue( time )),
526  m_volume( subRegion.getElementVolume() ),
527  m_density_n( fluid.density_n() ),
528 
529  m_internalEnergy_n( fluid.internalEnergy_n() )
530  {
531  const WellConstraintBase * currentConstraint = wellControls.getCurrentConstraint();
532  if( currentConstraint->getControl() == ConstraintTypeId::BHP )
533  {
534  m_targetBHP = currentConstraint->getConstraintValue( time );
535  }
536  else
537  {
538  m_targetBHP = std::numeric_limits< real64 >::max();
539  }
540 
541  }
542 
543 
545  void computeMassEnergyNormalizers( localIndex const iwelem,
546  real64 & massNormalizer,
547  real64 & energyNormalizer ) const
548  {
549  massNormalizer = LvArray::math::max( m_minNormalizer, m_density_n[iwelem][0] * m_volume[iwelem] );
550  energyNormalizer = m_internalEnergy_n[iwelem][0] * m_density_n[iwelem][0] * m_volume[iwelem];
551 
552  // warning: internal energy can be negative
553  energyNormalizer = LvArray::math::max( m_minNormalizer, LvArray::math::abs( energyNormalizer ) );
554  }
555 
557  virtual void computeLinf( localIndex const iwelem,
558  LinfStackVariables & stack ) const override
559  {
560  real64 normalizer = 0.0;
561  for( integer idof = 0; idof < WJ_ROFFSET::nEqn; ++idof )
562  {
563  // Step 1: compute a normalizer for the control or pressure equation
564 
565  // for the control equation, we distinguish two cases
566  if( idof == WJ_ROFFSET::CONTROL )
567  {
568 
569  // for the top well element, normalize using the current control
570  if( m_isLocallyOwned && iwelem == m_iwelemControl )
571  {
572  if( m_currentControl == ConstraintTypeId::BHP )
573  {
574  // the residual entry is in pressure units
575  normalizer = m_targetBHP;
576  }
577  else if( m_currentControl == ConstraintTypeId::TOTALVOLRATE )
578  {
579  // the residual entry is in volume / time units
580  normalizer = LvArray::math::max( LvArray::math::abs( m_constraintValue ), m_minNormalizer );
581  }
582  else if( m_currentControl == ConstraintTypeId::MASSRATE )
583  {
584  // the residual entry is in volume / time units
585  normalizer = LvArray::math::max( LvArray::math::abs( m_constraintValue ), m_minNormalizer );
586  }
587  }
588  // for the pressure difference equation, always normalize by the BHP
589  else
590  {
591  normalizer = m_targetBHP;
592  }
593  }
594  // Step 2: compute a normalizer for the mass balance equation
595  else if( idof == WJ_ROFFSET::MASSBAL )
596  {
597 
598  // this residual entry is in mass units
599  normalizer = m_dt * LvArray::math::abs( m_constraintValue ) * m_density_n[iwelem][0];
600 
601  // to make sure that everything still works well if the rate is zero, we add this check
602  normalizer = LvArray::math::max( normalizer, m_volume[iwelem] * m_density_n[iwelem][0] );
603 
604 
605  // we have the normalizer now, we can compute a dimensionless Linfty norm contribution
606  real64 const val = LvArray::math::abs( m_localResidual[stack.localRow + idof] ) / normalizer;
607  if( val > stack.localValue[0] )
608  {
609  stack.localValue[0] = val;
610  }
611 
612  }
613  // step 3: energy residual
614  else if( idof == WJ_ROFFSET::ENERGYBAL )
615  {
616  real64 massNormalizer = 0.0, energyNormalizer = 0.0;
617  computeMassEnergyNormalizers( iwelem, massNormalizer, energyNormalizer );
618  real64 const valEnergy = LvArray::math::abs( m_localResidual[stack.localRow + WJ_ROFFSET::ENERGYBAL] ) / energyNormalizer;
619  if( valEnergy > stack.localValue[1] )
620  {
621  stack.localValue[1] = valEnergy;
622  }
623  }
624  }
625  }
626 
628  virtual void computeL2( localIndex const iwelem,
629  L2StackVariables & stack ) const override
630  {
631  GEOS_UNUSED_VAR( iwelem, stack );
632  GEOS_ERROR( "The L2 norm is not implemented for SinglePhaseWell" );
633  }
634 
635 
636 protected:
637 
639  real64 const m_dt;
640 
642  bool const m_isLocallyOwned;
643 
646 
648  bool const m_isProducer;
649 
652  real64 const m_constraintValue;
653  real64 m_targetBHP;
654 
657 
661 
662 };
663 
664 /*
665  *@class ResidualNormKernelFactory
666  */
668 {
669 public:
670 
687  template< typename POLICY >
688  static void
689  createAndLaunch( globalIndex const rankOffset,
690  string const & dofKey,
691  arrayView1d< real64 const > const & localResidual,
692  WellElementSubRegion const & subRegion,
693  constitutive::SingleFluidBase const & fluid,
694  WellControls const & wellControls,
695  real64 const time,
696  real64 const dt,
697  real64 const minNormalizer,
698  real64 (& residualNorm)[2] )
699  {
700  using kernelType = ResidualNormKernel;
701  arrayView1d< globalIndex const > const dofNumber = subRegion.getReference< array1d< globalIndex > >( dofKey );
702  arrayView1d< integer const > const ghostRank = subRegion.ghostRank();
703 
704  kernelType kernel( rankOffset, localResidual, dofNumber, ghostRank,
705  subRegion, fluid, wellControls, time, dt, minNormalizer );
706  kernelType::template launchLinf< POLICY >( subRegion.size(), kernel, residualNorm );
707 
708  }
709 
710 };
711 
712 } // end namespace singlePhaseWellKernels
713 
714 } // end namespace geos
715 
716 #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.
#define GEOS_ERROR(...)
Raise a hard error and terminate the program.
Definition: Logger.hpp:226
#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.
real64 getConstraintValue(real64 const &currentTime) 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.
Definition: Group.hpp:1273
localIndex size() const
Get the "size" of the group, which determines the number of elements in resizable wrappers.
Definition: Group.hpp:1315
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.
ConstraintTypeId getControl() const
Get the control type for the well.
bool isProducer() const
Is the well a producer?
WellConstraintBase * getCurrentConstraint()
Get the current consrtaint.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Definition: DataTypes.hpp:179
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
LvArray::CRSMatrixView< T, COL_INDEX, INDEX_TYPE const, LvArray::ChaiBuffer > CRSMatrixView
Alias for CRS Matrix View.
Definition: DataTypes.hpp:309
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.
Definition: DataTypes.hpp:195
int integer
Signed integer type.
Definition: DataTypes.hpp:81
Array< T, 1 > array1d
Alias for 1D array.
Definition: DataTypes.hpp:175
ArrayView< T, 3, USD > arrayView3d
Alias for 3D array view.
Definition: DataTypes.hpp:211