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_SINGLEPHASE_RESIDUALNORMKERNEL_HPP
21 #define GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_RESIDUALNORMKERNEL_HPP
22 
24 
25 namespace geos
26 {
27 
28 namespace singlePhaseBaseKernels
29 {
30 
31 /******************************** ResidualNormKernel ********************************/
32 
37 {
38 public:
39 
42  using Base::m_rankOffset;
44  using Base::m_dofNumber;
45 
46  IsothermalResidualNormKernel( globalIndex const rankOffset,
47  arrayView1d< real64 const > const & localResidual,
48  arrayView1d< globalIndex const > const & dofNumber,
50  ElementSubRegionBase const & subRegion,
51  real64 const minNormalizer )
52  : Base( rankOffset,
53  localResidual,
54  dofNumber,
55  ghostRank,
56  minNormalizer ),
57  m_mass_n( subRegion.template getField< fields::flow::mass_n >() )
58  {}
59 
61  virtual void computeLinf( localIndex const ei,
62  LinfStackVariables & stack ) const override
63  {
64  real64 const massNormalizer = LvArray::math::max( m_minNormalizer, m_mass_n[ei] );
65  real64 const valMass = LvArray::math::abs( m_localResidual[stack.localRow] ) / massNormalizer;
66  if( valMass > stack.localValue[0] )
67  {
68  stack.localValue[0] = valMass;
69  }
70  }
71 
73  virtual void computeL2( localIndex const ei,
74  L2StackVariables & stack ) const override
75  {
76  real64 const massNormalizer = LvArray::math::max( m_minNormalizer, m_mass_n[ei] );
77  stack.localValue[0] += m_localResidual[stack.localRow] * m_localResidual[stack.localRow];
78  stack.localNormalizer[0] += massNormalizer;
79  }
80 
81 
82 protected:
83 
86 
87 };
88 
93 {
94 public:
95 
98  using Base::m_rankOffset;
100  using Base::m_dofNumber;
101 
102  ThermalResidualNormKernel( globalIndex const rankOffset,
103  arrayView1d< real64 const > const & localResidual,
104  arrayView1d< globalIndex const > const & dofNumber,
106  ElementSubRegionBase const & subRegion,
107  real64 const minNormalizer )
108  : Base( rankOffset,
109  localResidual,
110  dofNumber,
111  ghostRank,
112  minNormalizer ),
113  m_mass_n( subRegion.template getField< fields::flow::mass_n >() ),
114  m_energy_n( subRegion.template getField< fields::flow::energy_n >() )
115  {}
116 
118  void computeMassEnergyNormalizers( localIndex const ei,
119  real64 & massNormalizer,
120  real64 & energyNormalizer ) const
121  {
122  massNormalizer = LvArray::math::max( m_minNormalizer, m_mass_n[ei] );
123  energyNormalizer = LvArray::math::max( m_minNormalizer, LvArray::math::abs( m_energy_n[ei] ) ); // energy can be negative
124  }
125 
127  virtual void computeLinf( localIndex const ei,
128  LinfStackVariables & stack ) const override
129  {
130  real64 massNormalizer = 0.0, energyNormalizer = 0.0;
131  computeMassEnergyNormalizers( ei, massNormalizer, energyNormalizer );
132 
133  // step 1: mass residual
134 
135  real64 const valMass = LvArray::math::abs( m_localResidual[stack.localRow] ) / massNormalizer;
136  if( valMass > stack.localValue[0] )
137  {
138  stack.localValue[0] = valMass;
139  }
140 
141  // step 2: energy residual
142  real64 const valEnergy = LvArray::math::abs( m_localResidual[stack.localRow + 1] ) / energyNormalizer;
143  if( valEnergy > stack.localValue[1] )
144  {
145  stack.localValue[1] = valEnergy;
146  }
147  }
148 
150  virtual void computeL2( localIndex const ei,
151  L2StackVariables & stack ) const override
152  {
153  real64 massNormalizer = 0.0, energyNormalizer = 0.0;
154  computeMassEnergyNormalizers( ei, massNormalizer, energyNormalizer );
155 
156  // step 1: mass residual
157 
158  stack.localValue[0] += m_localResidual[stack.localRow] * m_localResidual[stack.localRow];
159  stack.localNormalizer[0] += massNormalizer;
160 
161  // step 2: energy residual
162 
163  stack.localValue[1] += m_localResidual[stack.localRow + 1] * m_localResidual[stack.localRow + 1];
164  stack.localNormalizer[1] += energyNormalizer;
165  }
166 
167 
168 protected:
169 
172 
175 
176 };
177 
182 {
183 public:
184 
198  template< typename POLICY >
199  static void
201  globalIndex const rankOffset,
202  string const dofKey,
203  arrayView1d< real64 const > const & localResidual,
204  ElementSubRegionBase const & subRegion,
205  real64 const minNormalizer,
206  real64 (& residualNorm)[1],
207  real64 (& residualNormalizer)[1] )
208  {
209  arrayView1d< globalIndex const > const dofNumber = subRegion.getReference< array1d< globalIndex > >( dofKey );
210  arrayView1d< integer const > const ghostRank = subRegion.ghostRank();
211 
212  IsothermalResidualNormKernel kernel( rankOffset, localResidual, dofNumber, ghostRank, subRegion, minNormalizer );
213  if( normType == physicsSolverBaseKernels::NormType::Linf )
214  {
215  IsothermalResidualNormKernel::launchLinf< POLICY >( subRegion.size(), kernel, residualNorm );
216  }
217  else // L2 norm
218  {
219  IsothermalResidualNormKernel::launchL2< POLICY >( subRegion.size(), kernel, residualNorm, residualNormalizer );
220  }
221  }
222 
237  template< typename POLICY >
238  static void
240  globalIndex const rankOffset,
241  string const & dofKey,
242  arrayView1d< real64 const > const & localResidual,
243  ElementSubRegionBase const & subRegion,
244  real64 const minNormalizer,
245  real64 (& residualNorm)[2],
246  real64 (& residualNormalizer)[2] )
247  {
248  arrayView1d< globalIndex const > const dofNumber = subRegion.getReference< array1d< globalIndex > >( dofKey );
249  arrayView1d< integer const > const ghostRank = subRegion.ghostRank();
250 
251  ThermalResidualNormKernel kernel( rankOffset, localResidual, dofNumber, ghostRank, subRegion, minNormalizer );
252  if( normType == physicsSolverBaseKernels::NormType::Linf )
253  {
254  ThermalResidualNormKernel::launchLinf< POLICY >( subRegion.size(), kernel, residualNorm );
255  }
256  else // L2 norm
257  {
258  ThermalResidualNormKernel::launchL2< POLICY >( subRegion.size(), kernel, residualNorm, residualNormalizer );
259  }
260  }
261 
262 };
263 
264 } // namespace singlePhaseBaseKernels
265 
266 } // namespace geos
267 
268 #endif //GEOS_PHYSICSSOLVERS_FLUIDFLOW_SINGLEPHASE_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.
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
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.
virtual GEOS_HOST_DEVICE void computeLinf(localIndex const ei, LinfStackVariables &stack) const override
Compute the local values for the Linf norm.
arrayView1d< real64 const > const m_mass_n
View on mass 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.
static void createAndLaunch(physicsSolverBaseKernels::NormType const normType, globalIndex const rankOffset, string const dofKey, arrayView1d< real64 const > const &localResidual, ElementSubRegionBase const &subRegion, real64 const minNormalizer, real64(&residualNorm)[1], real64(&residualNormalizer)[1])
Create a new kernel and launch (isothermal version)
static void createAndLaunch(physicsSolverBaseKernels::NormType const normType, globalIndex const rankOffset, string const &dofKey, arrayView1d< real64 const > const &localResidual, ElementSubRegionBase const &subRegion, real64 const minNormalizer, real64(&residualNorm)[2], real64(&residualNormalizer)[2])
Create a new kernel and launch (thermal version)
virtual GEOS_HOST_DEVICE void computeL2(localIndex const ei, L2StackVariables &stack) const override
Compute the local values and normalizer for the L2 norm.
arrayView1d< real64 const > const m_mass_n
View on mass at the previous converged time step.
virtual GEOS_HOST_DEVICE void computeLinf(localIndex const ei, LinfStackVariables &stack) const override
Compute the local values for the Linf norm.
arrayView1d< real64 const > const m_energy_n
View on energy at the previous converged time step.
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
Array< T, 1 > array1d
Alias for 1D array.
Definition: DataTypes.hpp:176