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 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_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"
32 #include "codingUtilities/Utilities.hpp"
33 
34 namespace geos
35 {
36 
37 namespace singlePhaseFVMKernels
38 {
39 
40 /******************************** DirichletFluxComputeKernel ********************************/
41 
47 template< integer NUM_EQN, integer NUM_DOF, typename FLUIDWRAPPER >
49  BoundaryStencilWrapper >
50 {
51 public:
52  using Deriv = constitutive::singlefluid::DerivativeOffset;
54  using DofNumberAccessor = AbstractBase::DofNumberAccessor;
58  using AbstractBase::m_dt;
62  using AbstractBase::m_gravCoef;
64  using AbstractBase::m_mob;
65  using AbstractBase::m_dMob;
67  using AbstractBase::m_dDens;
69  using AbstractBase::m_dPerm_dPres;
72 
73  using Base = singlePhaseFVMKernels::FluxComputeKernel< NUM_EQN, NUM_DOF,
75  using Base::numDof;
76  using Base::numEqn;
78  using Base::m_seri;
79  using Base::m_sesri;
80  using Base::m_sei;
81 
97  FaceManager const & faceManager,
98  BoundaryStencilWrapper const & stencilWrapper,
99  FLUIDWRAPPER const & fluidWrapper,
100  DofNumberAccessor const & dofNumberAccessor,
101  SinglePhaseFlowAccessors const & singlePhaseFlowAccessors,
102  SinglePhaseFluidAccessors const & singlePhaseFluidAccessors,
103  PermeabilityAccessors const & permeabilityAccessors,
104  real64 const & dt,
105  CRSMatrixView< real64, globalIndex const > const & localMatrix,
106  arrayView1d< real64 > const & localRhs )
107  : Base( rankOffset,
108  stencilWrapper,
109  dofNumberAccessor,
110  singlePhaseFlowAccessors,
111  singlePhaseFluidAccessors,
112  permeabilityAccessors,
113  dt,
114  localMatrix,
115  localRhs ),
116  m_facePres( faceManager.getField< fields::flow::facePressure >() ),
117  m_faceGravCoef( faceManager.getField< fields::flow::gravityCoefficient >() ),
118  m_fluidWrapper( fluidWrapper )
119  {}
120 
126  {
127 public:
128 
136  localIndex GEOS_UNUSED_PARAM( numElems ) )
137  {}
138 
141 
144 
147 
150 
151  };
152 
153 
160  void setup( localIndex const iconn,
161  StackVariables & stack ) const
162  {
163  globalIndex const offset =
165 
166  for( integer jdof = 0; jdof < numDof; ++jdof )
167  {
168  stack.dofColIndices[jdof] = offset + jdof;
169  }
170  }
171 
179  template< typename FUNC = NoOpFunc >
181  void computeFlux( localIndex const iconn,
182  StackVariables & stack,
183  FUNC && compFluxKernelOp = NoOpFunc{} ) const
184  {
185  using Order = BoundaryStencil::Order;
186  localIndex constexpr numElems = BoundaryStencil::maxNumPointsInFlux;
187 
188  stackArray1d< real64, numElems > mobility( numElems );
189  stackArray1d< real64, numElems > dMobility_dP( numElems );
190 
191  localIndex const er = m_seri( iconn, Order::ELEM );
192  localIndex const esr = m_sesri( iconn, Order::ELEM );
193  localIndex const ei = m_sei( iconn, Order::ELEM );
194  localIndex const kf = m_sei( iconn, Order::FACE );
195 
196  // Get flow quantities on the elem/face
197  real64 faceDens, faceVisc;
198  constitutive::SingleFluidBaseUpdate::computeValues( m_fluidWrapper, m_facePres[kf], faceDens, faceVisc );
199 
200  mobility[Order::ELEM] = m_mob[er][esr][ei];
201  singlePhaseBaseKernels::MobilityKernel::compute( faceDens, faceVisc, mobility[Order::FACE] );
202 
203  dMobility_dP[Order::ELEM] = m_dMob[er][esr][ei][Deriv::dP];
204  dMobility_dP[Order::FACE] = 0.0;
205 
206  // Compute average density
207  real64 const densMean = 0.5 * ( m_dens[er][esr][ei][0] + faceDens );
208  real64 const dDens_dP = 0.5 * m_dDens[er][esr][ei][0][Deriv::dP];
209 
210  // Evaluate potential difference
211  real64 const potDif = (m_pres[er][esr][ei] - m_facePres[kf])
212  - densMean * (m_gravCoef[er][esr][ei] - m_faceGravCoef[kf]);
213  real64 const dPotDif_dP = 1.0 - dDens_dP * m_gravCoef[er][esr][ei];
214 
215  real64 dTrans_dPerm[3];
216  m_stencilWrapper.computeWeights( iconn, m_permeability, stack.transmissibility, dTrans_dPerm );
217  real64 const dTrans_dPres = LvArray::tensorOps::AiBi< 3 >( dTrans_dPerm, m_dPerm_dPres[er][esr][ei][0] );
218 
219  real64 const f = stack.transmissibility * potDif;
220  real64 const dF_dP = stack.transmissibility * dPotDif_dP + dTrans_dPres * potDif;
221 
222  // Upwind mobility
223  localIndex const k_up = ( potDif >= 0 ) ? Order::ELEM : Order::FACE;
224  real64 const mobility_up = mobility[k_up];
225  real64 const dMobility_dP_up = dMobility_dP[k_up];
226 
227  // Upwind density
228  real64 const dens_up = ( potDif >= 0 ) ? m_dens[er][esr][ei][0] : faceDens;
229  real64 const dDens_dP_up = ( potDif >= 0 ) ? m_dDens[er][esr][ei][0][Deriv::dP] : 0.0;
230 
231  // call the lambda in the phase loop to allow the reuse of the fluxes and their derivatives
232  // possible use: assemble the derivatives wrt temperature, and the flux term of the energy equation for this phase
233 
234  compFluxKernelOp( er, esr, ei, kf, f, dF_dP, mobility_up, dMobility_dP_up, dens_up, dDens_dP_up );
235 
236  // *** end of upwinding
237 
238  // Populate local flux vector and derivatives
239 
240  stack.localFlux[0] = m_dt * mobility[k_up] * f;
241  stack.localFluxJacobian[0][0] = m_dt * ( mobility_up * dF_dP + dMobility_dP_up * f );
242  }
243 
249  template< typename FUNC = NoOpFunc >
251  void complete( localIndex const iconn,
252  StackVariables & stack,
253  FUNC && assemblyKernelOp = NoOpFunc{} ) const
254  {
255  using Order = BoundaryStencil::Order;
256 
257  localIndex const er = m_seri( iconn, Order::ELEM );
258  localIndex const esr = m_sesri( iconn, Order::ELEM );
259  localIndex const ei = m_sei( iconn, Order::ELEM );
260 
261  if( m_ghostRank[er][esr][ei] < 0 )
262  {
263  // Add to global residual/jacobian
264  globalIndex const dofIndex = m_dofNumber[er][esr][ei];
265  localIndex const localRow = LvArray::integerConversion< localIndex >( dofIndex - m_rankOffset );
266 
267  RAJA::atomicAdd( parallelDeviceAtomic{}, &AbstractBase::m_localRhs[localRow], stack.localFlux[0] );
268 
269  AbstractBase::m_localMatrix.addToRowBinarySearchUnsorted< parallelDeviceAtomic >
270  ( localRow,
271  stack.dofColIndices,
272  stack.localFluxJacobian[0],
273  numDof );
274 
275  assemblyKernelOp( localRow );
276  }
277  }
278 
279 protected:
280 
283 
286 
288  FLUIDWRAPPER const m_fluidWrapper;
289 
290 };
291 
292 
297 {
298 public:
299 
314  template< typename POLICY >
315  static void
316  createAndLaunch( globalIndex const rankOffset,
317  string const & dofKey,
318  string const & solverName,
319  FaceManager const & faceManager,
320  ElementRegionManager const & elemManager,
321  BoundaryStencilWrapper const & stencilWrapper,
322  constitutive::SingleFluidBase & fluidBase,
323  real64 const & dt,
324  CRSMatrixView< real64, globalIndex const > const & localMatrix,
325  arrayView1d< real64 > const & localRhs )
326  {
327  constitutiveUpdatePassThru( fluidBase, [&]( auto & fluid )
328  {
329  using FluidType = TYPEOFREF( fluid );
330  typename FluidType::KernelWrapper fluidWrapper = fluid.createKernelWrapper();
331 
332  integer constexpr NUM_DOF = 1;
333  integer constexpr NUM_EQN = 1;
335 
337  elemManager.constructArrayViewAccessor< globalIndex, 1 >( dofKey );
338 
339  dofNumberAccessor.setName( solverName + "/accessors/" + dofKey );
340 
341  typename kernelType::SinglePhaseFlowAccessors singlePhaseFlowAccessors( elemManager, solverName );
342  typename kernelType::SinglePhaseFluidAccessors singlePhaseFluidAccessors( elemManager, solverName );
343  typename kernelType::PermeabilityAccessors permeabilityAccessors( elemManager, solverName );
344 
345  kernelType kernel( rankOffset,
346  faceManager,
347  stencilWrapper,
348  fluidWrapper,
349  dofNumberAccessor,
350  singlePhaseFlowAccessors,
351  singlePhaseFluidAccessors,
352  permeabilityAccessors,
353  dt,
354  localMatrix,
355  localRhs );
356 
357  kernelType::template launch< POLICY >( stencilWrapper.size(), kernel );
358  } );
359  }
360 
361 };
362 
363 } // namespace singlePhaseFVMKernels
364 
365 } // namespace geos
366 
367 #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, constitutive::singlefluid::USD_FLUID > > 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, constitutive::singlefluid::USD_FLUID > > 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:179
GEOS_GLOBALINDEX_TYPE globalIndex
Global index type (for indexing objects across MPI partitions).
Definition: DataTypes.hpp:87
StackArray< T, 1, MAXSIZE > stackArray1d
Alias for 1D stack array.
Definition: DataTypes.hpp:187
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
int integer
Signed integer type.
Definition: DataTypes.hpp:81
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.