GEOS
ThermalSinglePhaseWellKernels.hpp
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 NUM_DOF >
49 class ElementBasedAssemblyKernel : public singlePhaseWellKernels::ElementBasedAssemblyKernel< NUM_DOF >
50 {
51 public:
52  using Base = singlePhaseWellKernels::ElementBasedAssemblyKernel< NUM_DOF >;
53  using Base::m_rankOffset;
54  using Base::m_wellElemDofNumber;
55  using Base::m_elemGhostRank;
56  using Base::m_wellElemVolume;
57  using Base::m_wellElemDensity;
58  using Base::m_wellElemDensity_n;
59  using Base::m_dWellElemDensity_dPressure;
60  using Base::m_localMatrix;
61  using Base::m_localRhs;
64 
66  static constexpr integer numDof = NUM_DOF;
67 
69  static constexpr integer numEqn = NUM_DOF;
70 
82  string const dofKey,
83  ElementSubRegionBase const & subRegion,
84  constitutive::SingleFluidBase const & fluid,
86  arrayView1d< real64 > const & localRhs )
87  : Base( rankOffset, dofKey, subRegion, fluid, localMatrix, localRhs ),
88  m_dWellElemDensity_dTemperature( fluid.dDensity_dTemperature() ),
89  m_internalEnergy( fluid.internalEnergy() ),
90  m_internalEnergy_n( fluid.internalEnergy_n() ),
91  m_dInternalEnergy_dPres( fluid.dInternalEnergy_dPressure() ),
92  m_dInternalEnergy_dTemp( fluid.dInternalEnergy_dTemperature() )
93  {}
94 
99  struct StackVariables : public Base::StackVariables
100  {
101 public:
104  : Base::StackVariables()
105  {}
106  using Base::StackVariables::eqnRowIndices;
107  using Base::StackVariables::dofColIndices;
108  using Base::StackVariables::localJacobian;
109  using Base::StackVariables::localResidual;
110  using Base::StackVariables::localRow;
111  using Base::StackVariables::volume;
112  using Base::StackVariables::density;
113  using Base::StackVariables::density_n;
114  using Base::StackVariables::dDensity_dPres;
115 
116  };
123  integer elemGhostRank( localIndex const ei ) const
124  { return m_elemGhostRank( ei ); }
125 
126 
127 
135  template< typename FUNC = NoOpFunc >
137  void computeAccumulation( localIndex const iwelem,
138  StackVariables & stack ) const
139  {
140  Base::computeAccumulation( iwelem, stack, [&]( )
141  {
142 
143  // Step 1: assemble the derivatives of the mass balance equation w.r.t temperature
144  stack.localJacobian[0][numDof-1] = stack.volume * m_dWellElemDensity_dTemperature[iwelem][0];
145 
146  // Step 2: assemble the fluid part of the accumulation term of the energy equation
147  real64 const fluidEnergy = stack.volume * stack.density * m_internalEnergy[iwelem][0];
148  real64 const fluidEnergy_n = stack.volume * stack.density_n * m_internalEnergy_n[iwelem][0];
149 
150  real64 const dFluidEnergy_dP = stack.volume * stack.dDensity_dPres * m_internalEnergy[iwelem][0]
151  + stack.volume * stack.density * m_dInternalEnergy_dPres[iwelem][0];
152 
153 
154  real64 const dFluidEnergy_dT = stack.volume * m_dWellElemDensity_dTemperature[iwelem][0] * m_internalEnergy[iwelem][0]
155  + stack.volume * stack.density * m_dInternalEnergy_dTemp[iwelem][0];
156 
157  // local accumulation
158  stack.localResidual[numEqn-1] = fluidEnergy - fluidEnergy_n;
159 
160  // derivatives w.r.t. pressure and temperature
161  stack.localJacobian[numEqn-1][0] = dFluidEnergy_dP;
162  stack.localJacobian[numEqn-1][numDof-1] = dFluidEnergy_dT;
163  } );
164  }
165 
166 
167 
175  template< typename POLICY, typename KERNEL_TYPE >
176  static void
177  launch( localIndex const numElems,
178  KERNEL_TYPE const & kernelComponent )
179  {
181 
182  forAll< POLICY >( numElems, [=] GEOS_HOST_DEVICE ( localIndex const iwelem )
183  {
184  if( kernelComponent.elemGhostRank( iwelem ) >= 0 )
185  {
186  return;
187  }
188  typename KERNEL_TYPE::StackVariables stack;
189  kernelComponent.setup( iwelem, stack );
190  kernelComponent.computeAccumulation( iwelem, stack );
191  kernelComponent.complete( iwelem, stack );
192 
193  } );
194  }
195 
196 protected:
197 
200 
203  arrayView2d< real64 const > const m_internalEnergy_n;
204  arrayView2d< real64 const > const m_dInternalEnergy_dPres;
205  arrayView2d< real64 const > const m_dInternalEnergy_dTemp;
206 
207 };
208 
209 
214 {
215 public:
226  template< typename POLICY >
227  static void
228  createAndLaunch( globalIndex const rankOffset,
229  string const dofKey,
230  ElementSubRegionBase const & subRegion,
231  constitutive::SingleFluidBase const & fluid,
232  CRSMatrixView< real64, globalIndex const > const & localMatrix,
233  arrayView1d< real64 > const & localRhs )
234  {
235  integer constexpr NUM_DOF = 2;
237  kernel( rankOffset, dofKey, subRegion, fluid, localMatrix, localRhs );
239  launch< POLICY, ElementBasedAssemblyKernel< NUM_DOF > >( subRegion.size(), kernel );
240 
241  }
242 };
243 } // end namespace singlePhaseWellKernels
244 
245 } // end namespace geos
246 
247 #endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_WELLS_SINGLEPHASEWELLKERNELS_HPP
#define GEOS_HOST_DEVICE
Marks a host-device function.
Definition: GeosxMacros.hpp:49
#define GEOS_MARK_FUNCTION
Mark function with both Caliper and NVTX if enabled.
localIndex size() const
Get the "size" of the group, which determines the number of elements in resizable wrappers.
Definition: Group.hpp:1315
static void createAndLaunch(globalIndex const rankOffset, string const dofKey, ElementSubRegionBase 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 volume balance.
static void launch(localIndex const numElems, KERNEL_TYPE const &kernelComponent)
Performs the kernel launch.
ElementBasedAssemblyKernel(globalIndex const rankOffset, string const dofKey, ElementSubRegionBase const &subRegion, constitutive::SingleFluidBase const &fluid, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs)
Constructor.
GEOS_HOST_DEVICE integer elemGhostRank(localIndex const ei) const
Getter for the ghost rank of an element.
GEOS_HOST_DEVICE void computeAccumulation(localIndex const iwelem, StackVariables &stack) const
Compute the local accumulation contributions to the residual and Jacobian.
static constexpr integer numEqn
Compute time value for the number of equations.
static constexpr integer numDof
Compute time value for the number of degrees of freedom.
arrayView2d< real64 const > const m_internalEnergy
Views on fluid internal energy.
arrayView2d< real64 const > const m_dWellElemDensity_dTemperature
View on derivative of fluid density w.r.t temperature.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Definition: DataTypes.hpp:180
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
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
std::int32_t integer
Signed integer type.
Definition: DataTypes.hpp:82
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.
Definition: DataTypes.hpp:196
Kernel variables (dof numbers, jacobian and residual) located on the stack.