GEOS
DirichletFluxComputeKernel.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 Total, S.A
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_SINGLEPHASE_DIRICHLETFLUXCOMPUTEKERNEL_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_DIRICHLETFLUXCOMPUTEKERNEL_HPP
22 
23 #include "common/DataLayouts.hpp"
24 #include "common/DataTypes.hpp"
25 #include "common/GEOS_RAJA_Interface.hpp"
26 #include "constitutive/fluid/singlefluid/SingleFluidBase.hpp"
31 #include "codingUtilities/Utilities.hpp"
32 
33 namespace geos
34 {
35 
36 namespace singlePhaseFVMKernels
37 {
38 
39 /******************************** DirichletFluxComputeKernel ********************************/
40 
46 template< integer NUM_EQN, integer NUM_DOF, typename FLUIDWRAPPER >
47 class DirichletFluxComputeKernel : public FluxComputeKernel< NUM_EQN, NUM_DOF,
48  BoundaryStencilWrapper >
49 {
50 public:
51 
53  using DofNumberAccessor = AbstractBase::DofNumberAccessor;
57  using AbstractBase::m_dt;
61  using AbstractBase::m_gravCoef;
63  using AbstractBase::m_mob;
64  using AbstractBase::m_dMob_dPres;
66  using AbstractBase::m_dDens_dPres;
68  using AbstractBase::m_dPerm_dPres;
71 
72  using Base = singlePhaseFVMKernels::FluxComputeKernel< NUM_EQN, NUM_DOF,
74  using Base::numDof;
75  using Base::numEqn;
77  using Base::m_seri;
78  using Base::m_sesri;
79  using Base::m_sei;
80 
96  FaceManager const & faceManager,
97  BoundaryStencilWrapper const & stencilWrapper,
98  FLUIDWRAPPER const & fluidWrapper,
99  DofNumberAccessor const & dofNumberAccessor,
100  SinglePhaseFlowAccessors const & singlePhaseFlowAccessors,
101  SinglePhaseFluidAccessors const & singlePhaseFluidAccessors,
102  PermeabilityAccessors const & permeabilityAccessors,
103  real64 const & dt,
104  CRSMatrixView< real64, globalIndex const > const & localMatrix,
105  arrayView1d< real64 > const & localRhs )
106  : Base( rankOffset,
107  stencilWrapper,
108  dofNumberAccessor,
109  singlePhaseFlowAccessors,
110  singlePhaseFluidAccessors,
111  permeabilityAccessors,
112  dt,
113  localMatrix,
114  localRhs ),
115  m_facePres( faceManager.getField< fields::flow::facePressure >() ),
116  m_faceGravCoef( faceManager.getField< fields::flow::gravityCoefficient >() ),
117  m_fluidWrapper( fluidWrapper )
118  {}
119 
125  {
126 public:
127 
135  localIndex GEOS_UNUSED_PARAM( numElems ) )
136  {}
137 
140 
143 
146 
149 
150  };
151 
152 
159  void setup( localIndex const iconn,
160  StackVariables & stack ) const
161  {
162  globalIndex const offset =
164 
165  for( integer jdof = 0; jdof < numDof; ++jdof )
166  {
167  stack.dofColIndices[jdof] = offset + jdof;
168  }
169  }
170 
178  template< typename FUNC = NoOpFunc >
180  void computeFlux( localIndex const iconn,
181  StackVariables & stack,
182  FUNC && compFluxKernelOp = NoOpFunc{} ) const
183  {
184  using Order = BoundaryStencil::Order;
185  localIndex constexpr numElems = BoundaryStencil::maxNumPointsInFlux;
186 
187  stackArray1d< real64, numElems > mobility( numElems );
188  stackArray1d< real64, numElems > dMobility_dP( numElems );
189 
190  localIndex const er = m_seri( iconn, Order::ELEM );
191  localIndex const esr = m_sesri( iconn, Order::ELEM );
192  localIndex const ei = m_sei( iconn, Order::ELEM );
193  localIndex const kf = m_sei( iconn, Order::FACE );
194 
195  // Get flow quantities on the elem/face
196  real64 faceDens, faceVisc;
197  constitutive::SingleFluidBaseUpdate::computeValues( m_fluidWrapper, m_facePres[kf], faceDens, faceVisc );
198 
199  mobility[Order::ELEM] = m_mob[er][esr][ei];
200  singlePhaseBaseKernels::MobilityKernel::compute( faceDens, faceVisc, mobility[Order::FACE] );
201 
202  dMobility_dP[Order::ELEM] = m_dMob_dPres[er][esr][ei];
203  dMobility_dP[Order::FACE] = 0.0;
204 
205  // Compute average density
206  real64 const densMean = 0.5 * ( m_dens[er][esr][ei][0] + faceDens );
207  real64 const dDens_dP = 0.5 * m_dDens_dPres[er][esr][ei][0];
208 
209  // Evaluate potential difference
210  real64 const potDif = (m_pres[er][esr][ei] - m_facePres[kf])
211  - densMean * (m_gravCoef[er][esr][ei] - m_faceGravCoef[kf]);
212  real64 const dPotDif_dP = 1.0 - dDens_dP * m_gravCoef[er][esr][ei];
213 
214  real64 dTrans_dPerm[3];
215  m_stencilWrapper.computeWeights( iconn, m_permeability, stack.transmissibility, dTrans_dPerm );
216  real64 const dTrans_dPres = LvArray::tensorOps::AiBi< 3 >( dTrans_dPerm, m_dPerm_dPres[er][esr][ei][0] );
217 
218  real64 const f = stack.transmissibility * potDif;
219  real64 const dF_dP = stack.transmissibility * dPotDif_dP + dTrans_dPres * potDif;
220 
221  // Upwind mobility
222  localIndex const k_up = ( potDif >= 0 ) ? Order::ELEM : Order::FACE;
223  real64 const mobility_up = mobility[k_up];
224  real64 const dMobility_dP_up = dMobility_dP[k_up];
225 
226  // call the lambda in the phase loop to allow the reuse of the fluxes and their derivatives
227  // possible use: assemble the derivatives wrt temperature, and the flux term of the energy equation for this phase
228 
229  compFluxKernelOp( er, esr, ei, kf, f, dF_dP, mobility_up, dMobility_dP_up );
230 
231  // *** end of upwinding
232 
233  // Populate local flux vector and derivatives
234 
235  stack.localFlux[0] = m_dt * mobility[k_up] * f;
236  stack.localFluxJacobian[0][0] = m_dt * ( mobility_up * dF_dP + dMobility_dP_up * f );
237  }
238 
244  template< typename FUNC = NoOpFunc >
246  void complete( localIndex const iconn,
247  StackVariables & stack,
248  FUNC && assemblyKernelOp = NoOpFunc{} ) const
249  {
250  using Order = BoundaryStencil::Order;
251 
252  localIndex const er = m_seri( iconn, Order::ELEM );
253  localIndex const esr = m_sesri( iconn, Order::ELEM );
254  localIndex const ei = m_sei( iconn, Order::ELEM );
255 
256  if( m_ghostRank[er][esr][ei] < 0 )
257  {
258  // Add to global residual/jacobian
259  globalIndex const dofIndex = m_dofNumber[er][esr][ei];
260  localIndex const localRow = LvArray::integerConversion< localIndex >( dofIndex - m_rankOffset );
261 
262  RAJA::atomicAdd( parallelDeviceAtomic{}, &AbstractBase::m_localRhs[localRow], stack.localFlux[0] );
263 
264  AbstractBase::m_localMatrix.addToRowBinarySearchUnsorted< parallelDeviceAtomic >
265  ( localRow,
266  stack.dofColIndices,
267  stack.localFluxJacobian[0],
268  numDof );
269 
270  assemblyKernelOp( localRow );
271  }
272  }
273 
274 protected:
275 
278 
281 
283  FLUIDWRAPPER const m_fluidWrapper;
284 
285 };
286 
287 
292 {
293 public:
294 
309  template< typename POLICY >
310  static void
311  createAndLaunch( globalIndex const rankOffset,
312  string const & dofKey,
313  string const & solverName,
314  FaceManager const & faceManager,
315  ElementRegionManager const & elemManager,
316  BoundaryStencilWrapper const & stencilWrapper,
317  constitutive::SingleFluidBase & fluidBase,
318  real64 const & dt,
319  CRSMatrixView< real64, globalIndex const > const & localMatrix,
320  arrayView1d< real64 > const & localRhs )
321  {
322  constitutiveUpdatePassThru( fluidBase, [&]( auto & fluid )
323  {
324  using FluidType = TYPEOFREF( fluid );
325  typename FluidType::KernelWrapper fluidWrapper = fluid.createKernelWrapper();
326 
327  integer constexpr NUM_DOF = 1;
328  integer constexpr NUM_EQN = 1;
330 
332  elemManager.constructArrayViewAccessor< globalIndex, 1 >( dofKey );
333 
334  dofNumberAccessor.setName( solverName + "/accessors/" + dofKey );
335 
336  typename kernelType::SinglePhaseFlowAccessors singlePhaseFlowAccessors( elemManager, solverName );
337  typename kernelType::SinglePhaseFluidAccessors singlePhaseFluidAccessors( elemManager, solverName );
338  typename kernelType::PermeabilityAccessors permeabilityAccessors( elemManager, solverName );
339 
340  kernelType kernel( rankOffset,
341  faceManager,
342  stencilWrapper,
343  fluidWrapper,
344  dofNumberAccessor,
345  singlePhaseFlowAccessors,
346  singlePhaseFluidAccessors,
347  permeabilityAccessors,
348  dt,
349  localMatrix,
350  localRhs );
351 
352  kernelType::template launch< POLICY >( stencilWrapper.size(), kernel );
353  } );
354  }
355 
356 };
357 
358 } // namespace singlePhaseFVMKernels
359 
360 } // namespace geos
361 
362 #endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_DIRICHLETFLUXCOMPUTEKERNEL_HPP
#define GEOS_HOST_DEVICE
Marks a host-device function.
Definition: GeosxMacros.hpp:49
#define GEOS_UNUSED_PARAM(X)
Mark an unused argument and silence compiler warnings.
Definition: GeosxMacros.hpp:72
GEOS_HOST_DEVICE void computeWeights(localIndex const iconn, CoefficientAccessor< arrayView3d< real64 const > > const &coefficient, real64 &weight, real64(&dWeight_dCoef)[3]) const
Compute weights and derivatives w.r.t to the coefficient.
GEOS_HOST_DEVICE GEOS_FORCE_INLINE localIndex size() const
Give the number of stencil entries.
The ElementRegionManager class provides an interface to ObjectManagerBase in order to manage ElementR...
ElementViewAccessor< ArrayView< T const, NDIM, getUSD< PERM > > > constructArrayViewAccessor(string const &name, string const &neighborName=string()) const
This is a function to construct a ElementViewAccessor to access array data registered on the mesh.
array1d< array1d< VIEWTYPE > > ElementViewAccessor
The ElementViewAccessor at the ElementRegionManager level is an array of array of VIEWTYPE.
The FaceManager class provides an interface to ObjectManagerBase in order to manage face data.
Definition: FaceManager.hpp:44
A struct to automatically construct and store element view accessors.
A struct to automatically construct and store element view accessors.
static void createAndLaunch(globalIndex const rankOffset, string const &dofKey, string const &solverName, FaceManager const &faceManager, ElementRegionManager const &elemManager, BoundaryStencilWrapper const &stencilWrapper, constitutive::SingleFluidBase &fluidBase, real64 const &dt, 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 Dirichlet face flux terms.
ElementViewConst< arrayView1d< real64 const > > const m_mob
Views on fluid mobility.
GEOS_HOST_DEVICE void complete(localIndex const iconn, StackVariables &stack, FUNC &&assemblyKernelOp=NoOpFunc{}) const
Performs the complete phase for the kernel.
ElementViewConst< arrayView1d< integer const > > const m_ghostRank
Views on ghost rank numbers and gravity coefficients.
FLUIDWRAPPER const m_fluidWrapper
Reference to the fluid wrapper.
GEOS_HOST_DEVICE void computeFlux(localIndex const iconn, StackVariables &stack, FUNC &&compFluxKernelOp=NoOpFunc{}) const
Compute the local Dirichlet face flux contributions to the residual and Jacobian.
arrayView1d< real64 const > const m_faceGravCoef
View on the face gravity coefficient.
DirichletFluxComputeKernel(globalIndex const rankOffset, FaceManager const &faceManager, BoundaryStencilWrapper const &stencilWrapper, FLUIDWRAPPER const &fluidWrapper, DofNumberAccessor const &dofNumberAccessor, SinglePhaseFlowAccessors const &singlePhaseFlowAccessors, SinglePhaseFluidAccessors const &singlePhaseFluidAccessors, PermeabilityAccessors const &permeabilityAccessors, real64 const &dt, CRSMatrixView< real64, globalIndex const > const &localMatrix, arrayView1d< real64 > const &localRhs)
Constructor for the kernel interface.
ElementViewConst< arrayView1d< globalIndex const > > const m_dofNumber
Views on dof numbers.
ElementViewConst< arrayView1d< real64 const > > const m_pres
Views on pressure.
ElementViewConst< arrayView3d< real64 const > > m_permeability
Views on permeability.
ElementViewConst< arrayView2d< real64 const > > const m_dens
Views on fluid density.
GEOS_HOST_DEVICE void setup(localIndex const iconn, StackVariables &stack) const
Performs the setup phase for the kernel.
arrayView1d< real64 const > const m_facePres
Views on face pressure, temperature, and composition.
Base class for FluxComputeKernel that holds all data not dependent on template parameters (like stenc...
ElementViewConst< arrayView1d< real64 const > > const m_mob
Views on fluid mobility.
ElementViewConst< arrayView1d< integer const > > const m_ghostRank
Views on ghost rank numbers and gravity coefficients.
ElementViewConst< arrayView1d< globalIndex const > > const m_dofNumber
Views on dof numbers.
ElementViewConst< arrayView1d< real64 const > > const m_pres
Views on pressure.
arrayView1d< real64 > const m_localRhs
View on the local RHS.
ElementViewConst< arrayView3d< real64 const > > m_permeability
Views on permeability.
ElementViewConst< arrayView2d< real64 const > > const m_dens
Views on fluid density.
globalIndex const m_rankOffset
Offset for my MPI rank.
CRSMatrixView< real64, globalIndex const > const m_localMatrix
View on the local CRS matrix.
Define the interface for the assembly kernel in charge of flux terms.
static constexpr integer numEqn
Compute time value for the number of equations.
STENCILWRAPPER::IndexContainerViewConstType const m_seri
Connection to element maps.
static constexpr integer numDof
Compute time value for the number of degrees of freedom.
BoundaryStencilWrapper const m_stencilWrapper
Reference to the stencil wrapper.
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
StackArray< T, 1, MAXSIZE > stackArray1d
Alias for 1D stack array.
Definition: DataTypes.hpp:188
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
Defines the order of element/face in the stencil.
static constexpr localIndex ELEM
Order of element index in stencil.
static constexpr localIndex maxNumPointsInFlux
Maximum number of points the flux.
Definition: StencilBase.hpp:59
Kernel variables (dof numbers, jacobian and residual) located on the stack.
real64 localFluxJacobian[numEqn][numDof]
Storage for the face local Jacobian.
GEOS_HOST_DEVICE StackVariables(localIndex const GEOS_UNUSED_PARAM(size), localIndex GEOS_UNUSED_PARAM(numElems))
Constructor for the stack variables.
globalIndex dofColIndices[numDof]
Indices of the matrix rows/columns corresponding to the dofs in this face.