GEOS
ResidualNormKernel.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_COMPOSITIONAL_RESIDUALNORMKERNEL_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_RESIDUALNORMKERNEL_HPP
22 
24 
25 namespace geos
26 {
27 
28 namespace isothermalCompositionalMultiphaseBaseKernels
29 {
30 
31 /******************************** ResidualNormKernel ********************************/
32 
37 {
38 public:
39 
42  using Base::m_rankOffset;
44  using Base::m_dofNumber;
45 
46  ResidualNormKernel( globalIndex const rankOffset,
47  arrayView1d< real64 const > const & localResidual,
48  arrayView1d< globalIndex const > const & dofNumber,
50  integer const numComponents,
51  ElementSubRegionBase const & subRegion,
52  constitutive::MultiFluidBase const & fluid,
53  constitutive::CoupledSolidBase const & solid,
54  real64 const minNormalizer )
55  : Base( rankOffset,
56  localResidual,
57  dofNumber,
58  ghostRank,
59  minNormalizer ),
60  m_numComponents( numComponents ),
61  m_volume( subRegion.getElementVolume() ),
62  m_porosity_n( solid.getPorosity_n() ),
63  m_totalDens_n( fluid.totalDensity_n() )
64  {}
65 
67  virtual void computeLinf( localIndex const ei,
68  LinfStackVariables & stack ) const override
69  {
70  // this should never be zero if the simulation is set up correctly, but we never know
71  real64 const massNormalizer = LvArray::math::max( m_minNormalizer, m_totalDens_n[ei][0] * m_porosity_n[ei][0] * m_volume[ei] );
72  real64 const volumeNormalizer = LvArray::math::max( m_minNormalizer, m_porosity_n[ei][0] * m_volume[ei] );
73 
74  // step 1: mass residuals
75 
76  for( integer idof = 0; idof < m_numComponents; ++idof )
77  {
78  real64 const valMass = LvArray::math::abs( m_localResidual[stack.localRow + idof] ) / massNormalizer;
79  if( valMass > stack.localValue[0] )
80  {
81  stack.localValue[0] = valMass;
82  }
83  }
84 
85  // step 2: volume residual
86 
87  real64 const valVol = LvArray::math::abs( m_localResidual[stack.localRow + m_numComponents] ) / volumeNormalizer;
88  if( valVol > stack.localValue[1] )
89  {
90  stack.localValue[1] = valVol;
91  }
92  }
93 
95  virtual void computeL2( localIndex const ei,
96  L2StackVariables & stack ) const override
97  {
98  // note: for the L2 norm, we bundle the volume and mass residuals/normalizers
99 
100  real64 const massNormalizer = LvArray::math::max( m_minNormalizer, m_totalDens_n[ei][0] * m_porosity_n[ei][0] * m_volume[ei] );
101 
102  // step 1: mass residuals
103 
104  for( integer idof = 0; idof < m_numComponents; ++idof )
105  {
106  stack.localValue[0] += m_localResidual[stack.localRow + idof] * m_localResidual[stack.localRow + idof];
107  stack.localNormalizer[0] += massNormalizer;
108  }
109 
110  // step 2: volume residual
111 
112  real64 const val = m_localResidual[stack.localRow + m_numComponents] * m_totalDens_n[ei][0]; // we need a mass here, hence the
113  // multiplication
114  stack.localValue[1] += val * val;
115  stack.localNormalizer[1] += massNormalizer;
116  }
117 
118 
119 protected:
120 
123 
126 
129 
132 
133 };
134 
139 {
140 public:
141 
156  template< typename POLICY >
157  static void
159  integer const numComps,
160  globalIndex const rankOffset,
161  string const dofKey,
162  arrayView1d< real64 const > const & localResidual,
163  ElementSubRegionBase const & subRegion,
164  constitutive::MultiFluidBase const & fluid,
165  constitutive::CoupledSolidBase const & solid,
166  real64 const minNormalizer,
167  real64 (& residualNorm)[2],
168  real64 (& residualNormalizer)[2] )
169  {
170  arrayView1d< globalIndex const > const dofNumber = subRegion.getReference< array1d< globalIndex > >( dofKey );
171  arrayView1d< integer const > const ghostRank = subRegion.ghostRank();
172 
173  ResidualNormKernel kernel( rankOffset, localResidual, dofNumber, ghostRank, numComps, subRegion, fluid, solid, minNormalizer );
174  if( normType == physicsSolverBaseKernels::NormType::Linf )
175  {
176  ResidualNormKernel::launchLinf< POLICY >( subRegion.size(), kernel, residualNorm );
177  }
178  else // L2 norm
179  {
180  ResidualNormKernel::launchL2< POLICY >( subRegion.size(), kernel, residualNorm, residualNormalizer );
181  }
182  }
183 
184 };
185 
186 } // namespace isothermalCompositionalMultiphaseBaseKernels
187 
188 } // namespace geos
189 
190 
191 #endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_COMPOSITIONAL_RESIDUALNORMKERNEL_HPP
#define GEOS_HOST_DEVICE
Marks a host-device function.
Definition: GeosxMacros.hpp:49
NormType
Type of norm used to check convergence TODO: find a way to put this inside the class.
arrayView1d< real64 const > getElementVolume() const
Get the volume of each element in this subregion.
array1d< integer > const & ghostRank()
Get the ghost information of each object.
GEOS_DECLTYPE_AUTO_RETURN getReference(LOOKUP_TYPE const &lookup) const
Look up a wrapper and get reference to wrapped object.
Definition: Group.hpp:1273
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(physicsSolverBaseKernels::NormType const normType, integer const numComps, globalIndex const rankOffset, string const dofKey, arrayView1d< real64 const > const &localResidual, ElementSubRegionBase const &subRegion, constitutive::MultiFluidBase const &fluid, constitutive::CoupledSolidBase const &solid, real64 const minNormalizer, real64(&residualNorm)[2], real64(&residualNormalizer)[2])
Create a new kernel and launch.
arrayView1d< real64 const > const m_volume
View on the volume.
arrayView2d< real64 const > const m_porosity_n
View on porosity at the previous converged time step.
arrayView2d< real64 const, constitutive::multifluid::USD_FLUID > const m_totalDens_n
View on total mass/molar density at the previous converged time step.
virtual GEOS_HOST_DEVICE void computeL2(localIndex const ei, L2StackVariables &stack) const override
Compute the local values and normalizer for the L2 norm.
virtual GEOS_HOST_DEVICE void computeLinf(localIndex const ei, LinfStackVariables &stack) const override
Compute the local values for the Linf norm.
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
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
Array< T, 1 > array1d
Alias for 1D array.
Definition: DataTypes.hpp:176