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  if( wellControls.isProducer() )
532  {
533  m_targetBHP = wellControls.getMinBHPConstraint()->getConstraintValue( time );
534  }
535  else
536  {
537  m_targetBHP = wellControls.getMaxBHPConstraint()->getConstraintValue( time );
538  }
539  }
540 
541 
543  void computeMassEnergyNormalizers( localIndex const iwelem,
544  real64 & massNormalizer,
545  real64 & energyNormalizer ) const
546  {
547  massNormalizer = LvArray::math::max( m_minNormalizer, m_density_n[iwelem][0] * m_volume[iwelem] );
548  energyNormalizer = m_internalEnergy_n[iwelem][0] * m_density_n[iwelem][0] * m_volume[iwelem];
549 
550  // warning: internal energy can be negative
551  energyNormalizer = LvArray::math::max( m_minNormalizer, LvArray::math::abs( energyNormalizer ) );
552  }
553 
555  virtual void computeLinf( localIndex const iwelem,
556  LinfStackVariables & stack ) const override
557  {
558  real64 normalizer = 0.0;
559  for( integer idof = 0; idof < WJ_ROFFSET::nEqn; ++idof )
560  {
561  // Step 1: compute a normalizer for the control or pressure equation
562 
563  // for the control equation, we distinguish two cases
564  if( idof == WJ_ROFFSET::CONTROL )
565  {
566 
567  // for the top well element, normalize using the current control
568  if( m_isLocallyOwned && iwelem == m_iwelemControl )
569  {
570  if( m_currentControl == WellControls::Control::BHP )
571  {
572  // the residual entry is in pressure units
573  normalizer = m_targetBHP;
574  }
575  else if( m_currentControl == WellControls::Control::TOTALVOLRATE )
576  {
577  // the residual entry is in volume / time units
578  normalizer = LvArray::math::max( LvArray::math::abs( m_constraintValue ), m_minNormalizer );
579  }
580  else if( m_currentControl == WellControls::Control::MASSRATE )
581  {
582  // the residual entry is in volume / time units
583  normalizer = LvArray::math::max( LvArray::math::abs( m_constraintValue ), m_minNormalizer );
584  }
585  }
586  // for the pressure difference equation, always normalize by the BHP
587  else
588  {
589  normalizer = m_targetBHP;
590  }
591  }
592  // Step 2: compute a normalizer for the mass balance equation
593  else if( idof == WJ_ROFFSET::MASSBAL )
594  {
595 
596  // this residual entry is in mass units
597  normalizer = m_dt * LvArray::math::abs( m_constraintValue ) * m_density_n[iwelem][0];
598 
599  // to make sure that everything still works well if the rate is zero, we add this check
600  normalizer = LvArray::math::max( normalizer, m_volume[iwelem] * m_density_n[iwelem][0] );
601 
602 
603  // we have the normalizer now, we can compute a dimensionless Linfty norm contribution
604  real64 const val = LvArray::math::abs( m_localResidual[stack.localRow + idof] ) / normalizer;
605  if( val > stack.localValue[0] )
606  {
607  stack.localValue[0] = val;
608  }
609 
610  }
611  // step 3: energy residual
612  else if( idof == WJ_ROFFSET::ENERGYBAL )
613  {
614  real64 massNormalizer = 0.0, energyNormalizer = 0.0;
615  computeMassEnergyNormalizers( iwelem, massNormalizer, energyNormalizer );
616  real64 const valEnergy = LvArray::math::abs( m_localResidual[stack.localRow + WJ_ROFFSET::ENERGYBAL] ) / energyNormalizer;
617  if( valEnergy > stack.localValue[1] )
618  {
619  stack.localValue[1] = valEnergy;
620  }
621  }
622  }
623  }
624 
626  virtual void computeL2( localIndex const iwelem,
627  L2StackVariables & stack ) const override
628  {
629  GEOS_UNUSED_VAR( iwelem, stack );
630  GEOS_ERROR( "The L2 norm is not implemented for SinglePhaseWell" );
631  }
632 
633 
634 protected:
635 
637  real64 const m_dt;
638 
640  bool const m_isLocallyOwned;
641 
644 
646  bool const m_isProducer;
647 
650  real64 const m_constraintValue;
651  real64 m_targetBHP;
652 
655 
659 
660 };
661 
662 /*
663  *@class ResidualNormKernelFactory
664  */
666 {
667 public:
668 
685  template< typename POLICY >
686  static void
687  createAndLaunch( globalIndex const rankOffset,
688  string const & dofKey,
689  arrayView1d< real64 const > const & localResidual,
690  WellElementSubRegion const & subRegion,
691  constitutive::SingleFluidBase const & fluid,
692  WellControls const & wellControls,
693  real64 const time,
694  real64 const dt,
695  real64 const minNormalizer,
696  real64 (& residualNorm)[2] )
697  {
698  using kernelType = ResidualNormKernel;
699  arrayView1d< globalIndex const > const dofNumber = subRegion.getReference< array1d< globalIndex > >( dofKey );
700  arrayView1d< integer const > const ghostRank = subRegion.ghostRank();
701 
702  kernelType kernel( rankOffset, localResidual, dofNumber, ghostRank,
703  subRegion, fluid, wellControls, time, dt, minNormalizer );
704  kernelType::template launchLinf< POLICY >( subRegion.size(), kernel, residualNorm );
705 
706  }
707 
708 };
709 
710 } // end namespace singlePhaseWellKernels
711 
712 } // end namespace geos
713 
714 #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.
real64 getConstraintValue(real64 const &currentTime) const
Get the target bottom hole pressure value.
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.
MinimumBHPConstraint * getMinBHPConstraint()
Getters for constraints.
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: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