GEOS
CompositionalMultiphaseWellKernels.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_COMPOSITIONALMULTIPHASEWELLKERNELS_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_WELLS_COMPOSITIONALMULTIPHASEWELLKERNELS_HPP
22 
23 #include "codingUtilities/Utilities.hpp"
24 #include "common/DataTypes.hpp"
25 #include "common/GEOS_RAJA_Interface.hpp"
26 #include "constitutive/fluid/multifluid/MultiFluidBase.hpp"
27 #include "constitutive/fluid/multifluid/MultiFluidFields.hpp"
28 #include "constitutive/relativePermeability/RelativePermeabilityBase.hpp"
29 #include "constitutive/relativePermeability/RelativePermeabilityFields.hpp"
40 #include "physicsSolvers/fluidFlow/wells/WellControls.hpp"
42 
43 namespace geos
44 {
45 
46 
47 namespace compositionalMultiphaseWellKernels
48 {
49 
50 static constexpr real64 minDensForDivision = 1e-10;
51 
52 // tag to access well and reservoir elements in perforation rates computation
54 {
55  static constexpr integer RES = 0;
56  static constexpr integer WELL = 1;
57 };
58 
59 // tag to access the next and current well elements of a connection
60 struct ElemTag
61 {
62  static constexpr integer CURRENT = 0;
63  static constexpr integer NEXT = 1;
64 };
65 
66 // define the column offset of the derivatives
67 struct ColOffset
68 {
69  static constexpr integer DPRES = 0;
70  static constexpr integer DCOMP = 1;
71 };
72 
73 template< integer NC, integer IS_THERMAL >
75 
76 template< integer NC >
77 struct ColOffset_WellJac< NC, 0 >
78 {
79  static constexpr integer dP = 0;
80  static constexpr integer dC = 1;
81  static constexpr integer dQ = dC + NC;
82  static integer constexpr nDer = dQ + 1;
83 
84 };
85 
86 template< integer NC >
87 struct ColOffset_WellJac< NC, 1 >
88 {
89  static constexpr integer dP = 0;
90  static constexpr integer dC = 1;
91  static constexpr integer dQ = dC + NC;
92  static constexpr integer dT = dQ+1;
94  static integer constexpr nDer = dT + 1;
95 };
96 
97 // define the row offset of the residual equations
98 struct RowOffset
99 {
100  static constexpr integer CONTROL = 0;
101  static constexpr integer MASSBAL = 1;
102 };
103 
104 template< integer NC, integer IS_THERMAL >
106 
107 template< integer NC >
108 struct RowOffset_WellJac< NC, 0 >
109 {
110  static constexpr integer CONTROL = 0;
111  static constexpr integer MASSBAL = 1;
112  static constexpr integer VOLBAL = MASSBAL + NC;
113  static constexpr integer nEqn = VOLBAL+1;
114 };
115 
116 template< integer NC >
117 struct RowOffset_WellJac< NC, 1 >
118 {
119  static constexpr integer CONTROL = 0;
120  static constexpr integer MASSBAL = 1;
121  static constexpr integer VOLBAL = MASSBAL + NC;
122  static constexpr integer ENERGYBAL = VOLBAL+1;
123  static constexpr integer nEqn = ENERGYBAL+1;
124 
125 };
126 /******************************** ControlEquationHelper ********************************/
128 {
131 
133  inline
134  static
135  void
136  switchControl( bool const isProducer,
137  WellControls::Control const & inputControl,
138  WellControls::Control const & currentControl,
139  integer const phasePhaseIndex,
140  real64 const & targetBHP,
141  real64 const & targetPhaseRate,
142  real64 const & targetTotalRate,
143  real64 const & targetMassRate,
144  real64 const & currentBHP,
145  arrayView1d< real64 const > const & currentPhaseVolRate,
146  real64 const & currentTotalVolRate,
147  real64 const & currentMassRate,
148  WellControls::Control & newControl );
149 
150  template< integer NC, integer IS_THERMAL >
152  inline
153  static void
154  compute( globalIndex const rankOffset,
155  WellControls::Control const currentControl,
156  integer const targetPhaseIndex,
157  real64 const & targetBHP,
158  real64 const & targetPhaseRate,
159  real64 const & targetTotalRate,
160  real64 const & targetMassRate,
161  real64 const & currentBHP,
162  arrayView1d< real64 const > const & dCurrentBHP,
163  arrayView1d< real64 const > const & currentPhaseVolRate,
164  arrayView2d< real64 const > const & dCurrentPhaseVolRate,
165  real64 const & currentTotalVolRate,
166  arrayView1d< real64 const > const & dCurrentTotalVolRate,
167  real64 const & massDensity,
168  globalIndex const dofNumber,
169  CRSMatrixView< real64, globalIndex const > const & localMatrix,
170  arrayView1d< real64 > const & localRhs );
171 
172 };
173 
174 /******************************** PressureRelationKernel ********************************/
175 
177 {
178  using Deriv = constitutive::multifluid::DerivativeOffset;
182 
183  template< integer NC, integer IS_THERMAL >
185  inline
186  static void
187  compute( real64 const & gravCoef,
188  real64 const & gravCoefNext,
189  real64 const & pres,
190  real64 const & presNext,
191  real64 const & totalMassDens,
192  real64 const & totalMassDensNext,
195  real64 & localPresRel,
196  real64 ( &localPresRelJacobian )[2*(NC+1+IS_THERMAL)] );
197 
198  template< integer NC, integer IS_THERMAL >
199  static void
200  launch( localIndex const size,
201  globalIndex const rankOffset,
202  bool const isLocallyOwned,
203  localIndex const iwelemControl,
204  integer const targetPhaseIndex,
205  WellControls const & wellControls,
206  real64 const & timeAtEndOfStep,
207  arrayView1d< globalIndex const > const & wellElemDofNumber,
208  arrayView1d< real64 const > const & wellElemGravCoef,
209  arrayView1d< localIndex const > const & nextWellElemIndex,
210  arrayView1d< real64 const > const & wellElemPressure,
211  arrayView1d< real64 const > const & wellElemTotalMassDens,
212  arrayView2d< real64 const, compflow::USD_FLUID_DC > const & dWellElemTotalMassDens,
213  bool & controlHasSwitched,
214  CRSMatrixView< real64, globalIndex const > const & localMatrix,
215  arrayView1d< real64 > const & localRhs );
216 
217 };
218 
219 /******************************** VolumeBalanceKernel ********************************/
220 
222 {
223 
226 
227  template< integer NC >
229  inline
230  static void
231  compute( integer const numPhases,
232  real64 const & volume,
235  real64 & localVolBalance,
236  real64 ( &localVolBalanceJacobian )[NC+1] );
237 
238  template< integer NC >
239  static void
240  launch( localIndex const size,
241  integer const numPhases,
242  globalIndex const rankOffset,
243  arrayView1d< globalIndex const > const & wellElemDofNumber,
244  arrayView1d< integer const > const & wellElemGhostRank,
245  arrayView2d< real64 const, compflow::USD_PHASE > const & wellElemPhaseVolFrac,
246  arrayView3d< real64 const, compflow::USD_PHASE_DC > const & dWellElemPhaseVolFrac,
247  arrayView1d< real64 const > const & wellElemVolume,
248  CRSMatrixView< real64, globalIndex const > const & localMatrix,
249  arrayView1d< real64 > const & localRhs );
250 
251 };
252 
253 /******************************** PresTempCompFracInitializationKernel ********************************/
254 
256 {
257 
258  using CompFlowAccessors =
259  StencilAccessors< fields::flow::pressure,
260  fields::flow::temperature,
261  fields::flow::globalCompDensity,
262  fields::flow::phaseVolumeFraction >;
263 
264  using MultiFluidAccessors =
265  StencilMaterialAccessors< constitutive::MultiFluidBase,
266  fields::multifluid::phaseMassDensity >;
267 
268 
276  template< typename VIEWTYPE >
278 
279  static void
280  launch( localIndex const perforationSize,
281  localIndex const subRegionSize,
282  integer const numComponents,
283  integer const numPhases,
284  localIndex const numPerforations,
285  WellControls const & wellControls,
286  real64 const & currentTime,
292  arrayView1d< localIndex const > const & resElementRegion,
293  arrayView1d< localIndex const > const & resElementSubRegion,
294  arrayView1d< localIndex const > const & resElementIndex,
295  arrayView1d< real64 const > const & perfGravCoef,
296  arrayView1d< real64 const > const & wellElemGravCoef,
297  arrayView1d< real64 > const & wellElemPres,
298  arrayView1d< real64 > const & wellElemTemp,
299  arrayView2d< real64, compflow::USD_COMP > const & wellElemCompFrac );
300 
301 };
302 
303 /******************************** CompDensInitializationKernel ********************************/
304 
306 {
307 
308  static void
309  launch( localIndex const subRegionSize,
310  integer const numComponents,
311  arrayView2d< real64 const, compflow::USD_COMP > const & wellElemCompFrac,
313  arrayView2d< real64, compflow::USD_COMP > const & wellElemCompDens );
314 
315 };
316 
317 /******************************** RateInitializationKernel ********************************/
318 
320 {
321 
322  static void
323  launch( localIndex const subRegionSize,
324  integer const targetPhaseIndex,
325  WellControls const & wellControls,
326  real64 const & currentTime,
329  arrayView1d< real64 > const & connRate );
330 
331 };
332 
333 
334 /******************************** TotalMassDensityKernel ****************************/
335 
342 template< integer NUM_COMP, integer NUM_PHASE >
344 {
345 public:
346 
348  using Base::numComp;
349 
351  static constexpr integer numPhase = NUM_PHASE;
352 
359  constitutive::MultiFluidBase const & fluid )
360  : Base(),
361  m_phaseVolFrac( subRegion.getField< fields::well::phaseVolumeFraction >() ),
362  m_dPhaseVolFrac( subRegion.getField< fields::well::dPhaseVolumeFraction >() ),
363  m_dCompFrac_dCompDens( subRegion.getField< fields::well::dGlobalCompFraction_dGlobalCompDensity >() ),
364  m_phaseMassDens( fluid.phaseMassDensity() ),
365  m_dPhaseMassDens( fluid.dPhaseMassDensity() ),
366  m_totalMassDens( subRegion.getField< fields::well::totalMassDensity >() ),
367  m_dTotalMassDens( subRegion.getField< fields::well::dTotalMassDensity >() )
368  {}
369 
376  template< typename FUNC = NoOpFunc >
378  inline
379  void compute( localIndex const ei,
380  FUNC && totalMassDensityKernelOp = NoOpFunc{} ) const
381  {
382  using Deriv = constitutive::multifluid::DerivativeOffset;
383 
384  arraySlice1d< real64 const, compflow::USD_PHASE - 1 > phaseVolFrac = m_phaseVolFrac[ei];
385  arraySlice2d< real64 const, compflow::USD_PHASE_DC - 1 > dPhaseVolFrac = m_dPhaseVolFrac[ei];
386  arraySlice2d< real64 const, compflow::USD_COMP_DC - 1 > dCompFrac_dCompDens = m_dCompFrac_dCompDens[ei];
387  arraySlice1d< real64 const, constitutive::multifluid::USD_PHASE - 2 > phaseMassDens = m_phaseMassDens[ei][0];
388  arraySlice2d< real64 const, constitutive::multifluid::USD_PHASE_DC - 2 > dPhaseMassDens = m_dPhaseMassDens[ei][0];
389  real64 & totalMassDens = m_totalMassDens[ei];
390  arraySlice1d< real64, compflow::USD_FLUID_DC - 1 > dTotalMassDens = m_dTotalMassDens[ei];
391 
392  real64 dMassDens_dC[numComp]{};
393 
394  totalMassDens = 0.0;
395 
396  dTotalMassDens[Deriv::dP]=0.0;
397  for( integer ic = 0; ic < numComp; ++ic )
398  {
399  dTotalMassDens[Deriv::dC+ic]=0.0;
400  }
401 
402  for( integer ip = 0; ip < numPhase; ++ip )
403  {
404  totalMassDens += phaseVolFrac[ip] * phaseMassDens[ip];
405  dTotalMassDens[Deriv::dP] += dPhaseVolFrac[ip][Deriv::dP] * phaseMassDens[ip] + phaseVolFrac[ip] * dPhaseMassDens[ip][Deriv::dP];
406 
407  applyChainRule( numComp, dCompFrac_dCompDens, dPhaseMassDens[ip], dMassDens_dC, Deriv::dC );
408  for( integer ic = 0; ic < numComp; ++ic )
409  {
410  dTotalMassDens[Deriv::dC+ic] += dPhaseVolFrac[ip][Deriv::dC+ic] * phaseMassDens[ip]
411  + phaseVolFrac[ip] * dMassDens_dC[ic];
412  }
413 
414  totalMassDensityKernelOp( ip ); //, phaseVolFrac, dTotalMassDens_dPres, dTotalMassDens_dCompDens );
415  }
416 
417  }
418 
419 protected:
420 
421  // inputs
422 
427 
431 
432  // outputs
433 
437 
438 
439 };
440 
445 {
446 public:
447 
456  template< typename POLICY >
457  static void
458  createAndLaunch( integer const numComp,
459  integer const numPhase,
460  ObjectManagerBase & subRegion,
461  constitutive::MultiFluidBase const & fluid )
462  {
463  if( numPhase == 2 )
464  {
465  isothermalCompositionalMultiphaseBaseKernels::internal::kernelLaunchSelectorCompSwitch( numComp, [&] ( auto NC )
466  {
467  integer constexpr NUM_COMP = NC();
468  TotalMassDensityKernel< NUM_COMP, 2 > kernel( subRegion, fluid );
469  TotalMassDensityKernel< NUM_COMP, 2 >::template launch< POLICY >( subRegion.size(), kernel );
470  } );
471  }
472  else if( numPhase == 3 )
473  {
474  isothermalCompositionalMultiphaseBaseKernels::internal::kernelLaunchSelectorCompSwitch( numComp, [&] ( auto NC )
475  {
476  integer constexpr NUM_COMP = NC();
477  TotalMassDensityKernel< NUM_COMP, 3 > kernel( subRegion, fluid );
478  TotalMassDensityKernel< NUM_COMP, 3 >::template launch< POLICY >( subRegion.size(), kernel );
479  } );
480  }
481  }
482 };
483 
484 
485 /******************************** ResidualNormKernel ********************************/
486 
491 {
492 public:
493 
495  using Base::m_minNormalizer;
496  using Base::m_rankOffset;
497  using Base::m_localResidual;
498  using Base::m_dofNumber;
499 
500  ResidualNormKernel( globalIndex const rankOffset,
501  arrayView1d< real64 const > const & localResidual,
502  arrayView1d< globalIndex const > const & dofNumber,
504  integer const numComp,
505  integer const numDof,
506  integer const targetPhaseIndex,
507  WellElementSubRegion const & subRegion,
508  constitutive::MultiFluidBase const & fluid,
509  WellControls const & wellControls,
510  real64 const timeAtEndOfStep,
511  real64 const dt,
512  real64 const minNormalizer )
513  : Base( rankOffset,
514  localResidual,
515  dofNumber,
516  ghostRank,
517  minNormalizer ),
518  m_numComp( numComp ),
519  m_numDof( numDof ),
520  m_targetPhaseIndex( targetPhaseIndex ),
521  m_dt( dt ),
522  m_isLocallyOwned( subRegion.isLocallyOwned() ),
524  m_isProducer( wellControls.isProducer() ),
525  m_currentControl( wellControls.getControl() ),
526  m_targetBHP( wellControls.getTargetBHP( timeAtEndOfStep ) ),
527  m_targetTotalRate( wellControls.getTargetTotalRate( timeAtEndOfStep ) ),
528  m_targetPhaseRate( wellControls.getTargetPhaseRate( timeAtEndOfStep ) ),
529  m_targetMassRate( wellControls.getTargetMassRate( timeAtEndOfStep ) ),
530  m_volume( subRegion.getElementVolume() ),
531  m_phaseDens_n( fluid.phaseDensity_n() ),
532  m_totalDens_n( fluid.totalDensity_n() )
533  {}
534 
536  virtual void computeLinf( localIndex const iwelem,
537  LinfStackVariables & stack ) const override
538  {
540 
541  real64 normalizer = 0.0;
542  for( integer idof = 0; idof < m_numDof; ++idof )
543  {
544 
545  // Step 1: compute a normalizer for the control or pressure equation
546 
547  // for the control equation, we distinguish two cases
548  if( idof == ROFFSET::CONTROL )
549  {
550 
551  // for the top well element, normalize using the current control
552  if( m_isLocallyOwned && iwelem == m_iwelemControl )
553  {
555  {
556  // the residual entry is in pressure units
557  normalizer = m_targetBHP;
558  }
560  {
561  // the residual entry is in volume / time units
562  normalizer = LvArray::math::max( LvArray::math::abs( m_targetTotalRate ), m_minNormalizer );
563  }
565  {
566  // the residual entry is in volume / time units
567  normalizer = LvArray::math::max( LvArray::math::abs( m_targetPhaseRate ), m_minNormalizer );
568  }
570  {
571  // the residual entry is in volume / time units
572  normalizer = LvArray::math::max( LvArray::math::abs( m_targetMassRate ), m_minNormalizer );
573  }
574  }
575  // for the pressure difference equation, always normalize by the BHP
576  else
577  {
578  normalizer = m_targetBHP;
579  }
580  }
581  // Step 2: compute a normalizer for the mass balance equations
582  else if( idof >= ROFFSET::MASSBAL && idof < ROFFSET::MASSBAL + m_numComp )
583  {
584  if( m_isProducer ) // only PHASEVOLRATE is supported for now
585  {
586  // the residual is in mass units
587  normalizer = m_dt * LvArray::math::abs( m_targetPhaseRate ) * m_phaseDens_n[iwelem][0][m_targetPhaseIndex];
588  }
589  else // Type::INJECTOR, only TOTALVOLRATE is supported for now
590  {
592  {
593  normalizer = m_dt * LvArray::math::abs( m_targetMassRate );
594  }
595  else
596  {
597  // the residual is in mass units
598  normalizer = m_dt * LvArray::math::abs( m_targetTotalRate ) * m_totalDens_n[iwelem][0];
599  }
600 
601  }
602 
603  // to make sure that everything still works well if the rate is zero, we add this check
604  normalizer = LvArray::math::max( normalizer, m_volume[iwelem] * m_totalDens_n[iwelem][0] );
605  }
606  // Step 3: compute a normalizer for the volume balance equations
607  else if( idof == ROFFSET::MASSBAL + m_numComp )
608  {
609  if( m_isProducer ) // only PHASEVOLRATE is supported for now
610  {
611  // the residual is in volume units
612  normalizer = m_dt * LvArray::math::abs( m_targetPhaseRate );
613  }
614  else // Type::INJECTOR, only TOTALVOLRATE is supported for now
615  {
617  {
618  normalizer = m_dt * LvArray::math::abs( m_targetMassRate/ m_totalDens_n[iwelem][0] );
619  }
620  else
621  {
622  normalizer = m_dt * LvArray::math::abs( m_targetTotalRate );
623  }
624 
625  }
626 
627  }
628 
629  // to make sure that everything still works well if the rate is zero, we add this check
630  normalizer = LvArray::math::max( normalizer, m_volume[iwelem] );
631 
632  // Step 4: compute the contribution to the residual
633  real64 const val = LvArray::math::abs( m_localResidual[stack.localRow + idof] ) / normalizer;
634  if( val > stack.localValue[0] )
635  {
636  stack.localValue[0] = val;
637  }
638  }
639  }
640 
642  virtual void computeL2( localIndex const iwelem,
643  L2StackVariables & stack ) const override
644  {
645  GEOS_UNUSED_VAR( iwelem, stack );
646  GEOS_ERROR( "The L2 norm is not implemented for CompositionalMultiphaseWell" );
647  }
648 
649 
650 protected:
651 
654 
657 
660 
662  real64 const m_dt;
663 
665  bool const m_isLocallyOwned;
666 
669 
671  bool const m_isProducer;
672 
675  real64 const m_targetBHP;
676  real64 const m_targetTotalRate;
677  real64 const m_targetPhaseRate;
678  real64 const m_targetMassRate;
679 
682 
686 
687 };
688 
693 {
694 public:
695 
712  template< typename POLICY >
713  static void
714  createAndLaunch( integer const numComp,
715  integer const numDof,
716  integer const targetPhaseIndex,
717  globalIndex const rankOffset,
718  string const & dofKey,
719  arrayView1d< real64 const > const & localResidual,
720  WellElementSubRegion const & subRegion,
721  constitutive::MultiFluidBase const & fluid,
722  WellControls const & wellControls,
723  real64 const timeAtEndOfStep,
724  real64 const dt,
725  real64 const minNormalizer,
726  real64 (& residualNorm)[1] )
727  {
728  arrayView1d< globalIndex const > const dofNumber = subRegion.getReference< array1d< globalIndex > >( dofKey );
729  arrayView1d< integer const > const ghostRank = subRegion.ghostRank();
730 
731  ResidualNormKernel kernel( rankOffset, localResidual, dofNumber, ghostRank,
732  numComp, numDof, targetPhaseIndex, subRegion, fluid, wellControls, timeAtEndOfStep, dt, minNormalizer );
733  ResidualNormKernel::launchLinf< POLICY >( subRegion.size(), kernel, residualNorm );
734  }
735 
736 };
737 
738 /******************************** SolutionScalingKernel ********************************/
739 
744 {
745 public:
746 
760  template< typename POLICY >
762  createAndLaunch( real64 const maxRelativePresChange,
763  real64 const maxAbsolutePresChange,
764  real64 const maxCompFracChange,
765  real64 const maxRelativeCompDensChange,
766  globalIndex const rankOffset,
767  integer const numComp,
768  string const dofKey,
769  ElementSubRegionBase & subRegion,
770  arrayView1d< real64 const > const localSolution )
771  {
772  arrayView1d< real64 const > const pressure =
773  subRegion.getField< fields::well::pressure >();
775  subRegion.getField< fields::well::globalCompDensity >();
776  arrayView1d< real64 > pressureScalingFactor =
777  subRegion.getField< fields::well::pressureScalingFactor >();
778  arrayView1d< real64 > compDensScalingFactor =
779  subRegion.getField< fields::well::globalCompDensityScalingFactor >();
780  isothermalCompositionalMultiphaseBaseKernels::
781  SolutionScalingKernel kernel( maxRelativePresChange, maxAbsolutePresChange, maxCompFracChange, maxRelativeCompDensChange, rankOffset,
782  numComp, dofKey, subRegion, localSolution, pressure, compDens, pressureScalingFactor, compDensScalingFactor );
783  return isothermalCompositionalMultiphaseBaseKernels::
784  SolutionScalingKernel::
785  launch< POLICY >( subRegion.size(), kernel );
786  }
787 
788 };
789 
790 /******************************** SolutionCheckKernel ********************************/
791 
796 {
797 public:
798 
810  template< typename POLICY >
812  createAndLaunch( integer const allowCompDensChopping,
814  real64 const scalingFactor,
815  arrayView1d< real64 const > const pressure,
817  arrayView1d< real64 > pressureScalingFactor,
818  arrayView1d< real64 > compDensScalingFactor,
819  globalIndex const rankOffset,
820  integer const numComp,
821  string const dofKey,
822  ElementSubRegionBase & subRegion,
823  arrayView1d< real64 const > const localSolution )
824  {
825 
826  isothermalCompositionalMultiphaseBaseKernels::
827  SolutionCheckKernel kernel( allowCompDensChopping, 0, scalingType, scalingFactor,
828  pressure, compDens, pressureScalingFactor, compDensScalingFactor, rankOffset,
829  numComp, dofKey, subRegion, localSolution );
830  return isothermalCompositionalMultiphaseBaseKernels::
831  SolutionCheckKernel::
832  launch< POLICY >( subRegion.size(), kernel );
833  }
834 
835 };
836 
837 /******************************** ElementBasedAssemblyKernel ********************************/
838 
845 template< integer NUM_COMP, integer IS_THERMAL >
847 {
848 public:
851 
852  // Well jacobian column and row indicies
853  using FLUID_PROP_COFFSET = constitutive::multifluid::DerivativeOffsetC< NUM_COMP, IS_THERMAL >;
857  static constexpr integer numComp = NUM_COMP;
858 
860  static constexpr integer numDof = NUM_COMP + 1 + IS_THERMAL;
861 
863  static constexpr integer numEqn = NUM_COMP + 1 + IS_THERMAL;
864 
865 
878  integer const isProducer,
879  globalIndex const rankOffset,
880  string const dofKey,
881  WellElementSubRegion const & subRegion,
882  constitutive::MultiFluidBase const & fluid,
883  CRSMatrixView< real64, globalIndex const > const & localMatrix,
884  arrayView1d< real64 > const & localRhs,
885  BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > const kernelFlags )
886  : m_numPhases( numPhases ),
887  m_isProducer( isProducer ),
888  m_rankOffset( rankOffset ),
889  m_iwelemControl( subRegion.getTopWellElementIndex() ),
890  m_dofNumber( subRegion.getReference< array1d< globalIndex > >( dofKey ) ),
891  m_elemGhostRank( subRegion.ghostRank() ),
892  m_volume( subRegion.getElementVolume() ),
893  m_dCompFrac_dCompDens( subRegion.getField< fields::flow::dGlobalCompFraction_dGlobalCompDensity >() ),
894  m_phaseVolFrac_n( subRegion.getField< fields::flow::phaseVolumeFraction_n >() ),
895  m_phaseVolFrac( subRegion.getField< fields::flow::phaseVolumeFraction >() ),
896  m_dPhaseVolFrac( subRegion.getField< fields::flow::dPhaseVolumeFraction >() ),
897  m_phaseDens_n( fluid.phaseDensity_n() ),
898  m_phaseDens( fluid.phaseDensity() ),
899  m_dPhaseDens( fluid.dPhaseDensity() ),
900  m_phaseCompFrac_n( fluid.phaseCompFraction_n() ),
901  m_phaseCompFrac( fluid.phaseCompFraction() ),
902  m_dPhaseCompFrac( fluid.dPhaseCompFraction() ),
903  m_compDens( subRegion.getField< fields::flow::globalCompDensity >() ),
904  m_compDens_n( subRegion.getField< fields::flow::globalCompDensity_n >() ),
905  m_localMatrix( localMatrix ),
906  m_localRhs( localRhs ),
907  m_kernelFlags( kernelFlags )
908  {}
909 
915  {
916 public:
917 
918  // volume information (used by both accumulation and volume balance)
919  real64 volume = 0.0;
920 
921  // Residual information
922 
925 
927  globalIndex dofIndices[numDof]{}; // NC compdens + P + thermal
928  globalIndex eqnRowIndices[numDof]{};
929  globalIndex dofColIndices[numDof]{};
930 
933 
936 
937  };
938 
945  integer elemGhostRank( localIndex const ei ) const
946  { return m_elemGhostRank( ei ); }
947 
948 
955  void setup( localIndex const ei,
956  StackVariables & stack ) const
957  {
958  // initialize the volume
959  stack.volume = m_volume[ei];
960 
961  // Note row/col indices needed to be consistent with layout of stack.localJacobian
962  // Setup row equation indices for this element ( mass + vol + thermal if valid)
963 
964  // 1) Mass Balance
965  for( integer ic = 0; ic < numComp; ++ic )
966  {
967  stack.eqnRowIndices[ic] = m_dofNumber[ei] + WJ_ROFFSET::MASSBAL + ic - m_rankOffset;
968  }
969 // 2) Volume Balance
970  stack.eqnRowIndices[numComp] = m_dofNumber[ei] + WJ_ROFFSET::VOLBAL - m_rankOffset;
971  // 3) Energy Balance
972  if constexpr ( IS_THERMAL )
973  {
974  stack.eqnRowIndices[numComp+1] = m_dofNumber[ei] + WJ_ROFFSET::ENERGYBAL - m_rankOffset;
975  }
976  // Setup equation column indices for this element ( P + COMPDENS + THERMAL if valid)
977  stack.dofColIndices[0] = m_dofNumber[ei] + WJ_COFFSET::dP;
978  for( integer ic = 0; ic < numComp; ++ic )
979  {
980  stack.dofColIndices[ic+1] = m_dofNumber[ei] + WJ_COFFSET::dC+ic;
981  }
982  if constexpr ( IS_THERMAL )
983  {
984  stack.dofColIndices[numComp+1] = m_dofNumber[ei] + WJ_COFFSET::dT;
985  }
986  if( 1 )
987  for( integer jc = 0; jc < numEqn; ++jc )
988  {
989  stack.localResidual[jc] = 0.0;
990  for( integer ic = 0; ic < numDof; ++ic )
991  {
992  stack.localJacobian[jc][ic] = 0.0;
993  }
994 
995  }
996 
997  }
998 
1006  template< typename FUNC = NoOpFunc >
1009  StackVariables & stack,
1010  FUNC && phaseAmountKernelOp = NoOpFunc{} ) const
1011  {
1012 
1013  using Deriv = constitutive::multifluid::DerivativeOffset;
1014 
1015  // construct the slices for variables accessed multiple times
1016  arraySlice2d< real64 const, compflow::USD_COMP_DC - 1 > dCompFrac_dCompDens = m_dCompFrac_dCompDens[ei];
1017 
1018  arraySlice1d< real64 const, compflow::USD_PHASE - 1 > phaseVolFrac_n = m_phaseVolFrac_n[ei];
1019  arraySlice1d< real64 const, compflow::USD_PHASE - 1 > phaseVolFrac = m_phaseVolFrac[ei];
1020  arraySlice2d< real64 const, compflow::USD_PHASE_DC - 1 > dPhaseVolFrac = m_dPhaseVolFrac[ei];
1021 
1022  arraySlice1d< real64 const, constitutive::multifluid::USD_PHASE - 2 > phaseDens_n = m_phaseDens_n[ei][0];
1023  arraySlice1d< real64 const, constitutive::multifluid::USD_PHASE - 2 > phaseDens = m_phaseDens[ei][0];
1024  arraySlice2d< real64 const, constitutive::multifluid::USD_PHASE_DC - 2 > dPhaseDens = m_dPhaseDens[ei][0];
1025 
1026  arraySlice2d< real64 const, constitutive::multifluid::USD_PHASE_COMP - 2 > phaseCompFrac_n = m_phaseCompFrac_n[ei][0];
1027  arraySlice2d< real64 const, constitutive::multifluid::USD_PHASE_COMP - 2 > phaseCompFrac = m_phaseCompFrac[ei][0];
1028  arraySlice3d< real64 const, constitutive::multifluid::USD_PHASE_COMP_DC - 2 > dPhaseCompFrac = m_dPhaseCompFrac[ei][0];
1029 
1030  // temporary work arrays
1031  real64 dPhaseAmount[FLUID_PROP_COFFSET::nDer]{};
1032  real64 dPhaseAmount_dC[numComp]{};
1033  real64 dPhaseCompFrac_dC[numComp]{};
1034 
1035  // sum contributions to component accumulation from each phase
1036  for( integer ip = 0; ip < m_numPhases; ++ip )
1037  {
1038  real64 const phaseAmount = stack.volume * phaseVolFrac[ip] * phaseDens[ip];
1039  real64 const phaseAmount_n = stack.volume * phaseVolFrac_n[ip] * phaseDens_n[ip];
1040 
1041  dPhaseAmount[FLUID_PROP_COFFSET::dP]=stack.volume * ( dPhaseVolFrac[ip][Deriv::dP] * phaseDens[ip]
1042  + phaseVolFrac[ip] * dPhaseDens[ip][Deriv::dP] );
1043 
1044  // assemble density dependence
1045  applyChainRule( numComp, dCompFrac_dCompDens, dPhaseDens[ip], dPhaseAmount_dC, Deriv::dC );
1046  applyChainRule( numComp, dCompFrac_dCompDens, dPhaseDens[ip], &dPhaseAmount[FLUID_PROP_COFFSET::dC], Deriv::dC );
1047  for( integer jc = 0; jc < numComp; ++jc )
1048  {
1049  dPhaseAmount_dC[jc] = dPhaseAmount_dC[jc] * phaseVolFrac[ip]
1050  + phaseDens[ip] * dPhaseVolFrac[ip][Deriv::dC+jc];
1051  dPhaseAmount_dC[jc] *= stack.volume;
1052  dPhaseAmount[FLUID_PROP_COFFSET::dC+jc] = dPhaseAmount[FLUID_PROP_COFFSET::dC+jc] * phaseVolFrac[ip]
1053  + phaseDens[ip] * dPhaseVolFrac[ip][Deriv::dC+jc];
1054  dPhaseAmount[FLUID_PROP_COFFSET::dC+jc] *= stack.volume;
1055  }
1056  // ic - index of component whose conservation equation is assembled
1057  // (i.e. row number in local matrix)
1058  for( integer ic = 0; ic < numComp; ++ic )
1059  {
1060  real64 const phaseCompAmount = phaseAmount * phaseCompFrac[ip][ic];
1061  real64 const phaseCompAmount_n = phaseAmount_n * phaseCompFrac_n[ip][ic];
1062 
1063  real64 const dPhaseCompAmount_dP = dPhaseAmount[FLUID_PROP_COFFSET::dP] * phaseCompFrac[ip][ic]
1064  + phaseAmount * dPhaseCompFrac[ip][ic][Deriv::dP];
1065 
1066  stack.localResidual[ic] += phaseCompAmount - phaseCompAmount_n;
1067  stack.localJacobian[ic][0] += dPhaseCompAmount_dP;
1068 
1069  // jc - index of component w.r.t. whose compositional var the derivative is being taken
1070  // (i.e. col number in local matrix)
1071 
1072  // assemble phase composition dependence
1073  applyChainRule( numComp, dCompFrac_dCompDens, dPhaseCompFrac[ip][ic], dPhaseCompFrac_dC, Deriv::dC );
1074  for( integer jc = 0; jc < numComp; ++jc )
1075  {
1076  real64 const dPhaseCompAmount_dC = dPhaseCompFrac_dC[jc] * phaseAmount
1077  + phaseCompFrac[ip][ic] * dPhaseAmount[FLUID_PROP_COFFSET::dC+jc];
1078 
1079  stack.localJacobian[ic][jc + 1] += dPhaseCompAmount_dC;
1080  }
1081  }
1082  if constexpr ( IS_THERMAL )
1083  {
1084  dPhaseAmount[FLUID_PROP_COFFSET::dT] = stack.volume * (dPhaseVolFrac[ip][Deriv::dT] * phaseDens[ip] + phaseVolFrac[ip] * dPhaseDens[ip][Deriv::dT] );
1085  for( integer ic = 0; ic < numComp; ++ic )
1086  {
1087  // assemble the derivatives of the component mass balance equations with respect to temperature
1088  stack.localJacobian[ic][numComp+1] += dPhaseAmount[FLUID_PROP_COFFSET::dT] * phaseCompFrac[ip][ic]
1089  + phaseAmount * dPhaseCompFrac[ip][ic][Deriv::dT];
1090  }
1091  }
1092  // call the lambda in the phase loop to allow the reuse of the phase amounts and their derivatives
1093  // possible use: assemble accumulation term of the energy equation for this phase
1094  phaseAmountKernelOp( ip, phaseAmount, phaseAmount_n, dPhaseAmount );
1095 
1096  }
1097 
1098  // check zero diagonal (works only in debug)
1099  /*
1100  for( integer ic = 0; ic < numComp; ++ic )
1101  {
1102  GEOS_ASSERT_MSG ( LvArray::math::abs( stack.localJacobian[ic][ic] ) > minDensForDivision,
1103  GEOS_FMT( "Zero diagonal in Jacobian: equation {}, value = {}", ic, stack.localJacobian[ic][ic] ) );
1104  }
1105  */
1106  }
1107 
1108 
1119  StackVariables & stack ) const
1120  {
1121  using Deriv = constitutive::multifluid::DerivativeOffset;
1122 
1123  arraySlice1d< real64 const, compflow::USD_PHASE - 1 > phaseVolFrac = m_phaseVolFrac[ei];
1124  arraySlice2d< real64 const, compflow::USD_PHASE_DC - 1 > dPhaseVolFrac = m_dPhaseVolFrac[ei];
1125 
1126  real64 oneMinusPhaseVolFracSum = 1.0;
1127 
1128  // sum contributions to component accumulation from each phase
1129 // Note localJacobian stores equation balances in order of component/vol/enerqy
1130  // These are mapped to solver orderings with indicies setup in stack variables
1131  for( integer ip = 0; ip < m_numPhases; ++ip )
1132  {
1133  oneMinusPhaseVolFracSum -= phaseVolFrac[ip];
1134  stack.localJacobian[numComp][0] -= dPhaseVolFrac[ip][Deriv::dP];
1135 
1136  for( integer jc = 0; jc < numComp; ++jc )
1137  {
1138  stack.localJacobian[numComp][jc+1] -= dPhaseVolFrac[ip][Deriv::dC+jc];
1139  }
1140 
1141  if constexpr ( IS_THERMAL)
1142  {
1143  stack.localJacobian[numComp][numComp+1] -= dPhaseVolFrac[ip][Deriv::dT];
1144  }
1145 
1146  }
1147  // scale saturation-based volume balance by pore volume (for better scaling w.r.t. other equations)
1148  stack.localResidual[numComp] = stack.volume * oneMinusPhaseVolFracSum;
1149  for( integer idof = 0; idof < numComp+1+IS_THERMAL; ++idof )
1150  {
1151  stack.localJacobian[numComp][idof] *= stack.volume;
1152  }
1153 
1154  }
1155 
1162  void complete( localIndex const ei, //GEOS_UNUSED_PARAM( ei ),
1163  StackVariables & stack ) const
1164  {
1165  using namespace compositionalMultiphaseUtilities;
1166 
1167  integer const numRows = numComp+1+ IS_THERMAL;
1168 
1169  if constexpr ( IS_THERMAL)
1170  {
1171  if( ei == m_iwelemControl && !m_isProducer )
1172  {
1173  // For top segment energy balance eqn replaced with T(n+1) - T = 0
1174  // No other energy balance derivatives
1175  // Assumption is global index == 0 is top segment with fixed temp BC
1176 
1177  for( integer i=0; i < numComp+1+IS_THERMAL; i++ )
1178  {
1179  stack.localJacobian[numRows-1][i] = 0.0;
1180  }
1181  // constant Temperature
1182  for( integer i=0; i < numComp+1+IS_THERMAL; i++ )
1183  stack.localJacobian[i][numRows-1] = 0.0;
1184  stack.localJacobian[numRows-1][numRows-1] = 1.0;
1185 
1186  stack.localResidual[numRows-1]=0.0;
1187  }
1188  }
1189 
1190  if( m_kernelFlags.isSet( isothermalCompositionalMultiphaseBaseKernels::KernelFlags::TotalMassEquation ) )
1191  {
1192  // apply equation/variable change transformation to the component mass balance equations
1193  real64 work[numComp + 1 + IS_THERMAL]{};
1194  shiftRowsAheadByOneAndReplaceFirstRowWithColumnSum( numComp, numComp+1+ IS_THERMAL, stack.localJacobian, work );
1195  shiftElementsAheadByOneAndReplaceFirstElementWithSum( numComp, stack.localResidual );
1196  }
1197 
1198  // add contribution to residual and jacobian into:
1199  // - the component mass balance equations (i = 0 to i = numComp-1)
1200  // - the volume balance equations (i = numComp)
1201  // note that numDof includes derivatives wrt temperature if this class is derived in ThermalKernels
1202 
1203  for( integer i = 0; i < numRows; ++i )
1204  {
1205  m_localRhs[stack.eqnRowIndices[i]] += stack.localResidual[i];
1206  m_localMatrix.addToRow< serialAtomic >( stack.eqnRowIndices[i],
1207  stack.dofColIndices,
1208  stack.localJacobian[i],
1209  numComp+1+ IS_THERMAL );
1210  }
1211 
1212  }
1213 
1221  template< typename POLICY, typename KERNEL_TYPE >
1222  static void
1223  launch( localIndex const numElems,
1224  KERNEL_TYPE const & kernelComponent )
1225  {
1227 
1228  forAll< POLICY >( numElems, [=] GEOS_HOST_DEVICE ( localIndex const ei )
1229  {
1230  if( kernelComponent.elemGhostRank( ei ) >= 0 )
1231  {
1232  return;
1233  }
1234 
1235  typename KERNEL_TYPE::StackVariables stack;
1236 
1237  kernelComponent.setup( ei, stack );
1238  kernelComponent.computeAccumulation( ei, stack );
1239  kernelComponent.computeVolumeBalance( ei, stack );
1240  kernelComponent.complete( ei, stack );
1241  } );
1242  }
1243 
1244 protected:
1245 
1248 
1251 
1254 
1257 
1260 
1263 
1266 
1269  arrayView2d< real64 const > const m_porosity;
1270  arrayView2d< real64 const > const m_dPoro_dPres;
1271 
1274 
1279 
1284 
1289 
1290  // Views on component densities
1293 
1298 
1299  BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > const m_kernelFlags;
1300 };
1301 
1302 
1307 {
1308 public:
1321  template< typename POLICY >
1322  static void
1323  createAndLaunch( localIndex const numComps,
1324  localIndex const numPhases,
1325  integer const isProducer,
1326  globalIndex const rankOffset,
1327  BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > kernelFlags,
1328  string const dofKey,
1329  WellElementSubRegion const & subRegion,
1330  constitutive::MultiFluidBase const & fluid,
1331  CRSMatrixView< real64, globalIndex const > const & localMatrix,
1332  arrayView1d< real64 > const & localRhs )
1333  {
1334  geos::internal::kernelLaunchSelectorCompThermSwitch( numComps, 0, [&]( auto NC, auto IS_THERMAL )
1335  {
1336  localIndex constexpr NUM_COMP = NC();
1337 
1338  integer constexpr istherm = IS_THERMAL();
1339 
1341  kernel( numPhases, isProducer, rankOffset, dofKey, subRegion, fluid, localMatrix, localRhs, kernelFlags );
1343  launch< POLICY, ElementBasedAssemblyKernel< NUM_COMP, istherm > >( subRegion.size(), kernel );
1344  } );
1345  }
1346 };
1355 template< integer NC, integer IS_THERMAL >
1357 {
1358 public:
1359 
1363 
1364  using FLUID_PROP_COFFSET = constitutive::multifluid::DerivativeOffsetC< NC, IS_THERMAL >;
1367 
1368  using CP_Deriv = constitutive::multifluid::DerivativeOffsetC< NC, IS_THERMAL >;
1370  static constexpr integer numComp = NC;
1371 
1373  static constexpr integer numDof = WJ_COFFSET::nDer;
1374 
1376  static constexpr integer numEqn = NC;
1377 
1378  static constexpr integer maxNumElems = 2;
1379  static constexpr integer maxStencilSize = 2;
1395  globalIndex const rankOffset,
1396  string const wellDofKey,
1397  WellControls const & wellControls,
1398  WellElementSubRegion const & subRegion,
1399  CRSMatrixView< real64, globalIndex const > const & localMatrix,
1400  arrayView1d< real64 > const & localRhs,
1401  BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > kernelFlags )
1402  :
1403  m_dt( dt ),
1404  m_rankOffset( rankOffset ),
1405  m_wellElemDofNumber ( subRegion.getReference< array1d< globalIndex > >( wellDofKey ) ),
1406  m_nextWellElemIndex ( subRegion.getReference< array1d< localIndex > >( WellElementSubRegion::viewKeyStruct::nextWellElementIndexString()) ),
1407  m_connRate ( subRegion.getField< fields::well::mixtureConnectionRate >() ),
1408  m_wellElemCompFrac ( subRegion.getField< fields::well::globalCompFraction >() ),
1409  m_dWellElemCompFrac_dCompDens ( subRegion.getField< fields::well::dGlobalCompFraction_dGlobalCompDensity >() ),
1410  m_localMatrix( localMatrix ),
1411  m_localRhs ( localRhs ),
1412  m_useTotalMassEquation ( kernelFlags.isSet( isothermalCompositionalMultiphaseBaseKernels::KernelFlags::TotalMassEquation ) ),
1413  m_isProducer ( wellControls.isProducer() ),
1414  m_injection ( wellControls.getInjectionStream() )
1415  {}
1416 
1418  {
1419 public:
1420 
1428  : stencilSize( size ),
1429  numConnectedElems( 2 ),
1430  dofColIndices( size * numDof )
1431  {}
1432 
1433  // Stencil information
1434  localIndex const stencilSize;
1437 
1438 
1439  // edge indexes
1440  localIndex iwelemUp;
1441  localIndex iwelemNext;
1442  localIndex iwelemCurrent;
1443  globalIndex offsetUp;
1444  globalIndex offsetCurrent;
1445  globalIndex offsetNext;
1446  // Local degrees of freedom and local residual/jacobian
1447 
1450 
1457  };
1458 
1465  inline
1466  void setup( localIndex const iconn,
1467  StackVariables & stack ) const
1468  {
1469  stack.numConnectedElems=2;
1470  if( m_nextWellElemIndex[iconn] <0 )
1471  {
1472  stack.numConnectedElems = 1;
1473  }
1474  stack.localFlux.resize( stack.numConnectedElems*numEqn );
1475  stack.localFluxJacobian.resize( stack.numConnectedElems * numEqn, stack.stencilSize * numDof );
1476  stack.localFluxJacobian_dQ.resize( stack.numConnectedElems * numEqn, 1 );
1477 
1478  }
1479 
1486  inline
1487  void complete( localIndex const iconn,
1488  StackVariables & stack ) const
1489  {
1490  GEOS_UNUSED_VAR( iconn );
1491  using namespace compositionalMultiphaseUtilities;
1492  if( stack.numConnectedElems ==1 )
1493  {
1494  // Setup Jacobian global row indicies
1495  // equations for COMPONENT + ENERGY balances
1496  globalIndex oneSidedEqnRowIndices[numEqn]{};
1497  for( integer ic = 0; ic < NC; ++ic )
1498  {
1499  oneSidedEqnRowIndices[ic] = stack.offsetUp + WJ_ROFFSET::MASSBAL + ic - m_rankOffset;
1500  }
1501 
1502  // Setup Jacobian global col indicies ( Mapping from local jac order to well jac order)
1503  globalIndex oneSidedDofColIndices_dPresCompTempUp[CP_Deriv::nDer]{};
1504  globalIndex oneSidedDofColIndices_dRate = stack.offsetCurrent + WJ_COFFSET::dQ;
1505  // Note localFluxJacobian cols are stored using CP_Deriv order (dP dC or dP dT dC)
1506  int ioff=0;
1507  oneSidedDofColIndices_dPresCompTempUp[ioff++] = stack.offsetUp + WJ_COFFSET::dP;
1508 
1509  if constexpr ( IS_THERMAL )
1510  {
1511  oneSidedDofColIndices_dPresCompTempUp[ioff++] = stack.offsetUp + WJ_COFFSET::dT;
1512  }
1513  for( integer jdof = 0; jdof < NC; ++jdof )
1514  {
1515  oneSidedDofColIndices_dPresCompTempUp[ioff++] = stack.offsetUp + WJ_COFFSET::dC+ jdof;
1516  }
1517  if( m_useTotalMassEquation > 0 )
1518  {
1519  // Apply equation/variable change transformation(s)
1520  real64 work[CP_Deriv::nDer]{};
1521  shiftRowsAheadByOneAndReplaceFirstRowWithColumnSum( numEqn, 1, stack.localFluxJacobian_dQ, work );
1522  shiftRowsAheadByOneAndReplaceFirstRowWithColumnSum( numEqn, CP_Deriv::nDer, stack.localFluxJacobian, work );
1523  shiftElementsAheadByOneAndReplaceFirstElementWithSum( numEqn, stack.localFlux );
1524  }
1525  for( integer i = 0; i < numEqn; ++i )
1526  {
1527  if( oneSidedEqnRowIndices[i] >= 0 && oneSidedEqnRowIndices[i] < m_localMatrix.numRows() )
1528  {
1529  m_localMatrix.addToRow< parallelDeviceAtomic >( oneSidedEqnRowIndices[i],
1530  &oneSidedDofColIndices_dRate,
1531  stack.localFluxJacobian_dQ[i],
1532  1 );
1533  m_localMatrix.addToRowBinarySearchUnsorted< parallelDeviceAtomic >( oneSidedEqnRowIndices[i],
1534  oneSidedDofColIndices_dPresCompTempUp,
1535  stack.localFluxJacobian[i],
1536  CP_Deriv::nDer );
1537  RAJA::atomicAdd( parallelDeviceAtomic{}, &m_localRhs[oneSidedEqnRowIndices[i]], stack.localFlux[i] );
1538  }
1539  }
1540  }
1541  else
1542  {
1543  // Setup Jacobian global row indicies
1544  // equations for COMPONENT + ENERGY balances
1545  globalIndex eqnRowIndices[2*numEqn]{};
1546 
1547  for( integer ic = 0; ic < NC; ++ic )
1548  {
1549  // mass balance equations for all components
1550  eqnRowIndices[TAG::NEXT *numEqn+ic] = stack.offsetNext + WJ_ROFFSET::MASSBAL + ic - m_rankOffset;
1551  eqnRowIndices[TAG::CURRENT *numEqn+ic] = stack.offsetCurrent + WJ_ROFFSET::MASSBAL + ic - m_rankOffset;
1552  }
1553 
1554  // Setup Jacobian global col indicies ( Mapping from local jac order to well jac order)
1555  globalIndex dofColIndices_dPresCompUp[CP_Deriv::nDer]{};
1556  globalIndex dofColIndices_dRate = stack.offsetCurrent + WJ_COFFSET::dQ;
1557 
1558  int ioff=0;
1559  // Indice storage order reflects local jac col storage order CP::Deriv order P T DENS
1560  dofColIndices_dPresCompUp[ioff++] = stack.offsetUp + WJ_COFFSET::dP;
1561 
1562  if constexpr ( IS_THERMAL )
1563  {
1564  dofColIndices_dPresCompUp[ioff++] = stack.offsetUp + WJ_COFFSET::dT;
1565  }
1566  for( integer jdof = 0; jdof < NC; ++jdof )
1567  {
1568  dofColIndices_dPresCompUp[ioff++] = stack.offsetUp + WJ_COFFSET::dC+ jdof;
1569  }
1570 
1571 
1572  if( m_useTotalMassEquation > 0 )
1573  {
1574  // Apply equation/variable change transformation(s)
1575  real64 work[CP_Deriv::nDer]{};
1576  shiftBlockRowsAheadByOneAndReplaceFirstRowWithColumnSum( numEqn, numEqn, 1, 2, stack.localFluxJacobian_dQ, work );
1577  shiftBlockRowsAheadByOneAndReplaceFirstRowWithColumnSum( numEqn, numEqn, CP_Deriv::nDer, 2, stack.localFluxJacobian, work );
1578  shiftBlockElementsAheadByOneAndReplaceFirstElementWithSum( numEqn, numEqn, 2, stack.localFlux );
1579  }
1580  // Note this updates diag and offdiag
1581  for( integer i = 0; i < 2*NC; ++i )
1582  {
1583  if( eqnRowIndices[i] >= 0 && eqnRowIndices[i] < m_localMatrix.numRows() )
1584  {
1585  m_localMatrix.addToRow< parallelDeviceAtomic >( eqnRowIndices[i],
1586  &dofColIndices_dRate,
1587  stack.localFluxJacobian_dQ[i],
1588  1 );
1589  m_localMatrix.addToRowBinarySearchUnsorted< parallelDeviceAtomic >( eqnRowIndices[i],
1590  dofColIndices_dPresCompUp,
1591  stack.localFluxJacobian[i],
1592  CP_Deriv::nDer );
1593  RAJA::atomicAdd( parallelDeviceAtomic{}, &m_localRhs[eqnRowIndices[i]], stack.localFlux[i] );
1594 
1595  }
1596  }
1597  }
1598  }
1599 
1601  inline
1602  void
1603  computeExit( real64 const & dt,
1604  real64 const ( &compFlux )[NC ],
1605  StackVariables & stack,
1606  real64 ( & dCompFlux)[NC][numDof] ) const
1607  {
1608  for( integer ic = 0; ic < NC; ++ic )
1609  {
1610  stack.localFlux[ic] = -dt * compFlux[ic];
1611  // derivative with respect to rate
1612  stack.localFluxJacobian_dQ[ic][0] = -dt * dCompFlux[ic][WJ_COFFSET::dQ];
1613  // derivative with respect to upstream pressure
1614  stack.localFluxJacobian[ic][CP_Deriv::dP] = -dt * dCompFlux[ic][WJ_COFFSET::dP];
1615  // derivatives with respect to upstream component densities
1616  for( integer jdof = 0; jdof < NC; ++jdof )
1617  {
1618  stack.localFluxJacobian[ic][CP_Deriv::dC+jdof] = -dt * dCompFlux[ic][WJ_COFFSET::dC+jdof];
1619  }
1620  if constexpr ( IS_THERMAL )
1621  {
1622  stack.localFluxJacobian[ic][CP_Deriv::dT] = -dt * dCompFlux[ic][WJ_COFFSET::dT];
1623  }
1624  }
1625  }
1626 
1628  inline
1629  void
1630  compute( real64 const & dt,
1631  real64 const ( &compFlux )[NC ],
1632  StackVariables & stack,
1633  real64 ( & dCompFlux)[(NC )][numDof] ) const
1634  {
1635  // flux terms
1636  for( integer ic = 0; ic < NC; ++ic )
1637  {
1638  stack.localFlux[TAG::NEXT * NC +ic] = dt * compFlux[ic];
1639  stack.localFlux[TAG::CURRENT * NC +ic] = -dt * compFlux[ic];
1640  // derivative with respect to rate
1641  stack.localFluxJacobian_dQ[TAG::NEXT * NC+ ic][0] = dt * dCompFlux[ic][WJ_COFFSET::dQ];
1642  stack.localFluxJacobian_dQ[TAG::CURRENT * NC + +ic][0] = -dt * dCompFlux[ic][WJ_COFFSET::dQ];
1643 
1644  // derivative with respect to upstream pressure
1645  stack.localFluxJacobian[TAG::NEXT * NC +ic][CP_Deriv::dP] = dt * dCompFlux[ic][WJ_COFFSET::dP];
1646  stack.localFluxJacobian[TAG::CURRENT * NC+ ic][CP_Deriv::dP] = -dt * dCompFlux[ic][WJ_COFFSET::dP];
1647 
1648  if constexpr ( IS_THERMAL )
1649  {
1650  stack.localFluxJacobian[TAG::NEXT * NC +ic][CP_Deriv::dT] = dt * dCompFlux[ic][WJ_COFFSET::dT];
1651  stack.localFluxJacobian[TAG::CURRENT * NC +ic][CP_Deriv::dT] = -dt * dCompFlux[ic][WJ_COFFSET::dT];
1652  }
1653 
1654  // derivatives with respect to upstream component densities
1655  for( integer jdof = 0; jdof < NC; ++jdof )
1656  {
1657  stack.localFluxJacobian[TAG::NEXT * NC +ic][CP_Deriv::dC+jdof] = dt * dCompFlux[ic][WJ_COFFSET::dC+jdof];
1658  stack.localFluxJacobian[TAG::CURRENT * NC +ic][CP_Deriv::dC+jdof] = -dt * dCompFlux[ic][WJ_COFFSET::dC+jdof];
1659  }
1660  }
1661  }
1662 
1670  template< typename FUNC = NoOpFunc >
1672  inline
1673  void computeFlux( localIndex const iwelem,
1674  StackVariables & stack,
1675  FUNC && compFluxKernelOp = NoOpFunc{} ) const
1676  {
1677 
1678  using namespace compositionalMultiphaseUtilities;
1679 
1680  // create local work arrays
1681  real64 compFracUp[NC]{};
1682  real64 compFlux[NC]{};
1683  real64 dComp[NC][NC];
1684  real64 dCompFlux[NC][numDof]{};
1685  for( integer ic = 0; ic < NC; ++ic )
1686  {
1687  for( integer jc = 0; jc < NC; ++jc )
1688  {
1689  dComp[ic][jc]=0.0;
1690  }
1691  }
1692  // Step 1) decide the upwind well element
1693 
1694  /* currentConnRate < 0 flow from iwelem to iwelemNext
1695  * currentConnRate > 0 flow from iwelemNext to iwelem
1696  * With this convention, currentConnRate < 0 at the last connection for a producer
1697  * currentConnRate > 0 at the last connection for a injector
1698  */
1699 
1700  localIndex const iwelemNext = m_nextWellElemIndex[iwelem];
1701  real64 const currentConnRate = m_connRate[iwelem];
1702  localIndex iwelemUp = -1;
1703 
1704  if( iwelemNext < 0 && !m_isProducer ) // exit connection, injector
1705  {
1706  // we still need to define iwelemUp for Jacobian assembly
1707  iwelemUp = iwelem;
1708 
1709  // just copy the injection stream into compFrac
1710  for( integer ic = 0; ic < NC; ++ic )
1711  {
1712  compFracUp[ic] = m_injection[ic];
1713  for( integer jc = 0; jc < NC; ++jc )
1714  {
1715  dComp[ic][jc] = m_dWellElemCompFrac_dCompDens[iwelemUp][ic][jc];
1716  }
1717  for( integer jc = 0; jc < NC; ++jc )
1718  {
1719  dCompFlux[ic][WJ_COFFSET::dC+jc] = 0.0;
1720  }
1721  }
1722  }
1723  else
1724  {
1725  // first set iwelemUp to the upstream cell
1726  if( ( iwelemNext < 0 && m_isProducer ) // exit connection, producer
1727  || currentConnRate < 0 ) // not an exit connection, iwelem is upstream
1728  {
1729  iwelemUp = iwelem;
1730  }
1731  else // not an exit connection, iwelemNext is upstream
1732  {
1733  iwelemUp = iwelemNext;
1734  }
1735 
1736  // copy the vars of iwelemUp into compFrac
1737  for( integer ic = 0; ic < NC; ++ic )
1738  {
1739  compFracUp[ic] = m_wellElemCompFrac[iwelemUp][ic];
1740  for( integer jc = 0; jc < NC; ++jc )
1741  {
1742  dCompFlux[ic][WJ_COFFSET::dC+jc] = m_dWellElemCompFrac_dCompDens[iwelemUp][ic][jc];
1743  dComp[ic][jc] = m_dWellElemCompFrac_dCompDens[iwelemUp][ic][jc];
1744  }
1745  }
1746  }
1747 
1748  // Step 2) compute upstream transport coefficient
1749 
1750  for( integer ic = 0; ic < NC; ++ic )
1751  {
1752  compFlux[ic] = compFracUp[ic] * currentConnRate;
1753  dCompFlux[ic][WJ_COFFSET::dQ] = compFracUp[ic];
1754  // none of these quantities depend on pressure
1755  dCompFlux[ic][WJ_COFFSET::dP] = 0.0;
1756  if constexpr ( IS_THERMAL )
1757  {
1758  dCompFlux[ic][WJ_COFFSET::dT] = 0.0;
1759  }
1760  for( integer jc = 0; jc < NC; ++jc )
1761  {
1762  dCompFlux[ic][WJ_COFFSET::dC+jc] = dCompFlux[ic][WJ_COFFSET::dC+jc] * currentConnRate;
1763  }
1764  }
1765 
1766  stack.offsetUp = m_wellElemDofNumber[iwelemUp];
1767  stack.iwelemUp = iwelemUp;
1768  stack.offsetCurrent = m_wellElemDofNumber[iwelem];
1769  stack.iwelemCurrent= iwelem;
1770 
1771 
1772  if( iwelemNext < 0 ) // exit connection
1773  {
1774  // for this case, we only need NC mass conservation equations
1775  computeExit ( m_dt,
1776  compFlux,
1777  stack,
1778  dCompFlux );
1779 
1780  }
1781  else // not an exit connection
1782  {
1783  compute( m_dt,
1784  compFlux,
1785  stack,
1786  dCompFlux
1787  );
1788  stack.offsetNext = m_wellElemDofNumber[iwelemNext];
1789  }
1790  stack.iwelemNext = iwelemNext;
1791  compFluxKernelOp( iwelemNext, iwelemUp, currentConnRate, dComp );
1792  }
1793 
1794 
1802  template< typename POLICY, typename KERNEL_TYPE >
1803  static void
1804  launch( localIndex const numElements,
1805  KERNEL_TYPE const & kernelComponent )
1806  {
1808  forAll< POLICY >( numElements, [=] GEOS_HOST_DEVICE ( localIndex const ie )
1809  {
1810  typename KERNEL_TYPE::StackVariables stack( 1 );
1811 
1812  kernelComponent.setup( ie, stack );
1813  kernelComponent.computeFlux( ie, stack );
1814  kernelComponent.complete( ie, stack );
1815  } );
1816  }
1817 
1818 protected:
1820  real64 const m_dt;
1823 
1828 
1831 
1832 
1837 
1842 
1845 
1847  bool const m_isProducer;
1848 
1851 
1852 
1853 };
1854 
1859 {
1860 public:
1861 
1875  template< typename POLICY >
1876  static void
1877  createAndLaunch( integer const numComps,
1878  real64 const dt,
1879  globalIndex const rankOffset,
1880  BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > kernelFlags,
1881  string const dofKey,
1882  WellControls const & wellControls,
1883  WellElementSubRegion const & subRegion,
1884  CRSMatrixView< real64, globalIndex const > const & localMatrix,
1885  arrayView1d< real64 > const & localRhs )
1886  {
1887  isothermalCompositionalMultiphaseBaseKernels::internal::kernelLaunchSelectorCompSwitch( numComps, [&]( auto NC )
1888  {
1889  integer constexpr NUM_COMP = NC();
1890 
1891  using kernelType = FaceBasedAssemblyKernel< NUM_COMP, 0 >;
1892  kernelType kernel( dt, rankOffset, dofKey, wellControls, subRegion, localMatrix, localRhs, kernelFlags );
1893  kernelType::template launch< POLICY >( subRegion.size(), kernel );
1894  } );
1895  }
1896 };
1897 } // end namespace compositionalMultiphaseWellKernels
1898 
1899 } // end namespace geos
1900 
1901 #endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_WELLS_COMPOSITIONALMULTIPHASEWELLKERNELS_HPP
ScalingType
Solution scaling type, used in CompositionalMultiphaseFVM.
#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.
The ObjectManagerBase is the base object of all object managers in the mesh data hierachy.
array1d< integer > const & ghostRank()
Get the ghost information of each object.
GEOS_DECLTYPE_AUTO_RETURN getField() const
Get a view to the field associated with a trait from this ObjectManagerBase.
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.
bool isProducer() const
Is the well a producer?
Control getControl() const
Get the control type for the well.
real64 getTargetPhaseRate(real64 const &currentTime) const
Get the target phase rate.
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.
static void createAndLaunch(localIndex const numComps, localIndex const numPhases, integer const isProducer, globalIndex const rankOffset, BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > kernelFlags, string const dofKey, WellElementSubRegion const &subRegion, constitutive::MultiFluidBase 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 volume balance.
static constexpr integer numEqn
Compute time value for the number of equations mass bal + vol bal + energy bal.
ElementBasedAssemblyKernel(localIndex const numPhases, integer const isProducer, globalIndex const rankOffset, string const dofKey, WellElementSubRegion const &subRegion, constitutive::MultiFluidBase const &fluid, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs, BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > const kernelFlags)
Constructor.
arrayView1d< globalIndex const > const m_dofNumber
View on the dof numbers.
arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > const m_phaseDens_n
Views on the phase densities.
GEOS_HOST_DEVICE void computeAccumulation(localIndex const ei, StackVariables &stack, FUNC &&phaseAmountKernelOp=NoOpFunc{}) const
Compute the local accumulation contributions to the residual and Jacobian.
arrayView4d< real64 const, constitutive::multifluid::USD_PHASE_COMP > const m_phaseCompFrac_n
Views on the phase component fraction.
GEOS_HOST_DEVICE integer elemGhostRank(localIndex const ei) const
Getter for the ghost rank of an element.
arrayView3d< real64 const, compflow::USD_COMP_DC > const m_dCompFrac_dCompDens
Views on the derivatives of comp fractions wrt component density.
arrayView1d< real64 const > const m_volume
View on the element volumes.
GEOS_HOST_DEVICE void complete(localIndex const ei, StackVariables &stack) const
Performs the complete phase for the kernel.
static constexpr integer numComp
Compile time value for the number of components.
static void launch(localIndex const numElems, KERNEL_TYPE const &kernelComponent)
Performs the kernel launch.
arrayView2d< real64 const, compflow::USD_PHASE > const m_phaseVolFrac_n
Views on the phase volume fractions.
static constexpr integer numDof
Number of Dof's set in this kernal - no dQ in accum.
GEOS_HOST_DEVICE void computeVolumeBalance(localIndex const ei, StackVariables &stack) const
Compute the local volume balance contributions to the residual and Jacobian.
CRSMatrixView< real64, globalIndex const > const m_localMatrix
View on the local CRS matrix.
arrayView1d< integer const > const m_elemGhostRank
View on the ghost ranks.
localIndex const m_iwelemControl
Index of the element where the control is enforced.
GEOS_HOST_DEVICE void setup(localIndex const ei, StackVariables &stack) const
Performs the setup phase for the kernel.
static void createAndLaunch(integer const numComps, real64 const dt, globalIndex const rankOffset, BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > kernelFlags, 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.
arrayView1d< globalIndex const > const m_wellElemDofNumber
Reference to the degree-of-freedom numbers.
arrayView1d< real64 const > const m_injection
Injection stream composition.
GEOS_HOST_DEVICE void setup(localIndex const iconn, StackVariables &stack) const
Performs the setup phase for the kernel.
GEOS_HOST_DEVICE void computeFlux(localIndex const iwelem, StackVariables &stack, FUNC &&compFluxKernelOp=NoOpFunc{}) const
Compute the local flux contributions to the residual and Jacobian.
GEOS_HOST_DEVICE void complete(localIndex const iconn, StackVariables &stack) const
Performs the setup phase for the kernel.
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.
arrayView2d< real64 const, compflow::USD_COMP > const m_wellElemCompFrac
Element component fraction.
static void launch(localIndex const numElements, KERNEL_TYPE const &kernelComponent)
Performs the kernel launch.
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, BitFlags< isothermalCompositionalMultiphaseBaseKernels::KernelFlags > kernelFlags)
Constructor for the kernel interface.
CRSMatrixView< real64, globalIndex const > const m_localMatrix
View on the local CRS matrix.
arrayView3d< real64 const, compflow::USD_COMP_DC > const m_dWellElemCompFrac_dCompDens
Element component fraction derivatives.
static void createAndLaunch(integer const numComp, integer const numDof, integer const targetPhaseIndex, globalIndex const rankOffset, string const &dofKey, arrayView1d< real64 const > const &localResidual, WellElementSubRegion const &subRegion, constitutive::MultiFluidBase const &fluid, WellControls const &wellControls, real64 const timeAtEndOfStep, real64 const dt, real64 const minNormalizer, real64(&residualNorm)[1])
Create a new kernel and launch.
virtual GEOS_HOST_DEVICE void computeLinf(localIndex const iwelem, LinfStackVariables &stack) const override
Compute the local values for the Linf norm.
bool const m_isLocallyOwned
Flag indicating whether the well is locally owned or not.
arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > const m_phaseDens_n
View on phase/total density at the previous converged time step.
localIndex const m_iwelemControl
Index of the element where the control is enforced.
virtual GEOS_HOST_DEVICE void computeL2(localIndex const iwelem, L2StackVariables &stack) const override
Compute the local values and normalizer for the L2 norm.
bool const m_isProducer
Flag indicating whether the well is a producer or an injector.
static isothermalCompositionalMultiphaseBaseKernels::SolutionCheckKernel::StackVariables createAndLaunch(integer const allowCompDensChopping, compositionalMultiphaseUtilities::ScalingType const scalingType, real64 const scalingFactor, arrayView1d< real64 const > const pressure, arrayView2d< real64 const, compflow::USD_COMP > const compDens, arrayView1d< real64 > pressureScalingFactor, arrayView1d< real64 > compDensScalingFactor, globalIndex const rankOffset, integer const numComp, string const dofKey, ElementSubRegionBase &subRegion, arrayView1d< real64 const > const localSolution)
Create a new kernel and launch.
static isothermalCompositionalMultiphaseBaseKernels::SolutionScalingKernel::StackVariables createAndLaunch(real64 const maxRelativePresChange, real64 const maxAbsolutePresChange, real64 const maxCompFracChange, real64 const maxRelativeCompDensChange, globalIndex const rankOffset, integer const numComp, string const dofKey, ElementSubRegionBase &subRegion, arrayView1d< real64 const > const localSolution)
Create a new kernel and launch.
static void createAndLaunch(integer const numComp, integer const numPhase, ObjectManagerBase &subRegion, constitutive::MultiFluidBase const &fluid)
Create a new kernel and launch.
Define the interface for the property kernel in charge of computing the total mass density.
GEOS_HOST_DEVICE void compute(localIndex const ei, FUNC &&totalMassDensityKernelOp=NoOpFunc{}) const
Compute the total mass density in an element.
static constexpr integer numPhase
Compile time value for the number of phases.
arrayView3d< real64 const, constitutive::multifluid::USD_PHASE > m_phaseMassDens
Views on phase mass densities.
arrayView2d< real64 const, compflow::USD_PHASE > m_phaseVolFrac
Views on phase volume fractions.
static constexpr integer numComp
Compile time value for the number of components.
TotalMassDensityKernel(ObjectManagerBase &subRegion, constitutive::MultiFluidBase const &fluid)
Constructor.
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 property update kernels.
static constexpr integer numComp
Compile time value for the number of components.
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.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Definition: DataTypes.hpp:180
StackArray< T, 2, MAXSIZE > stackArray2d
Alias for 2D stack array.
Definition: DataTypes.hpp:204
LvArray::CRSMatrixView< T, COL_INDEX, localIndex const, LvArray::ChaiBuffer > CRSMatrixView
Alias for CRS Matrix View.
Definition: DataTypes.hpp:310
GEOS_GLOBALINDEX_TYPE globalIndex
Global index type (for indexing objects across MPI partitions).
Definition: DataTypes.hpp:88
StackArray< T, 1, MAXSIZE > stackArray1d
Alias for 1D stack array.
Definition: DataTypes.hpp:188
ArraySlice< T, 2, USD > arraySlice2d
Alias for 2D array slice.
Definition: DataTypes.hpp:200
ArraySlice< T, 3, USD > arraySlice3d
Alias for 3D array slice.
Definition: DataTypes.hpp:216
ArrayView< T, 5, USD > arrayView5d
Alias for 5D array view.
Definition: DataTypes.hpp:244
double real64
64-bit floating point type.
Definition: DataTypes.hpp:99
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:85
ArraySlice< T, 1, USD > arraySlice1d
Alias for 1D array slice.
Definition: DataTypes.hpp:184
std::int32_t integer
Signed integer type.
Definition: DataTypes.hpp:82
ArrayView< T, 4, USD > arrayView4d
Alias for 4D array view.
Definition: DataTypes.hpp:228
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.
Definition: DataTypes.hpp:196
Array< T, 1 > array1d
Alias for 1D array.
Definition: DataTypes.hpp:176
ArrayView< T, 3, USD > arrayView3d
Alias for 3D array view.
Definition: DataTypes.hpp:212
Kernel variables (dof numbers, jacobian and residual) located on the stack.
real64 localJacobian[numEqn][numDof]
C-array storage for the element local Jacobian matrix (all equations except constraint and momentum)
globalIndex dofIndices[numDof]
Indices of the matrix rows/columns corresponding to the dofs in this element.
real64 localResidual[numEqn]
C-array storage for the element local residual vector (all equations except constraint and momentum)
stackArray2d< real64, maxNumElems *numEqn *maxStencilSize *CP_Deriv::nDer > localFluxJacobian
Storage for the face local Jacobian matrix dC dP dT.
GEOS_HOST_DEVICE StackVariables(localIndex const size)
Constructor for the stack variables.
stackArray2d< real64, maxNumElems *numEqn *maxStencilSize > localFluxJacobian_dQ
Storage for the face local Jacobian matrix dQ only.
stackArray1d< globalIndex, maxNumElems *numDof > dofColIndices
Indices of the matrix rows/columns corresponding to the dofs in this face.
stackArray1d< real64, maxNumElems *numEqn > localFlux
Storage for the face local residual vector (all mass bal equations)
ElementRegionManager::ElementViewConst< VIEWTYPE > ElementViewConst
The type for element-based non-constitutive data parameters. Consists entirely of ArrayView's.