GEOS
PhysicsSolverBaseKernels.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_SOLVERBASEKERNELS_HPP
21 #define GEOS_PHYSICSSOLVERS_SOLVERBASEKERNELS_HPP
22 
24 #include "common/DataTypes.hpp"
25 #include "common/MpiWrapper.hpp"
26 
27 namespace geos
28 {
29 
30 namespace physicsSolverBaseKernels
31 {
32 
33 /******************************** ResidualNormKernelBase ********************************/
34 
40 template< integer NUM_NORM >
42 {
43 public:
44 
45 
47  static constexpr integer numNorm = NUM_NORM;
48 
49  ResidualNormKernelBase( globalIndex const rankOffset,
50  arrayView1d< real64 const > const & localResidual,
51  arrayView1d< globalIndex const > const & dofNumber,
53  real64 const minNormalizer ):
54  m_rankOffset( rankOffset ),
55  m_localResidual( localResidual ),
56  m_dofNumber( dofNumber ),
58  m_minNormalizer( minNormalizer )
59  {}
60 
66  {
69 
72  };
73 
79  {
82  };
83 
84 
91  integer ghostRank( localIndex const i ) const
92  { return m_ghostRank( i ); }
93 
100  virtual void setupLinf( localIndex const i,
101  LinfStackVariables & stack ) const
102  {
103  stack.localRow = m_dofNumber[i] - m_rankOffset;
104  }
105 
112  virtual void setupL2( localIndex const i,
113  L2StackVariables & stack ) const
114  {
115  stack.localRow = m_dofNumber[i] - m_rankOffset;
116  }
117 
118 
125  virtual void computeLinf( localIndex const i,
126  LinfStackVariables & stack ) const = 0;
127 
134  virtual void computeL2( localIndex const i,
135  L2StackVariables & stack ) const = 0;
136 
145  template< typename POLICY, typename KERNEL_TYPE >
146  static void
147  launchLinf( localIndex const size,
148  KERNEL_TYPE const & kernelComponent,
149  real64 (& residualNorm)[numNorm] )
150  {
151  RAJA::ReduceMax< ReducePolicy< POLICY >, real64 > localResidualNorm[numNorm]{};
152 
153  forAll< POLICY >( size, [=] GEOS_HOST_DEVICE ( localIndex const i )
154  {
155  if( kernelComponent.ghostRank( i ) >= 0 )
156  {
157  return;
158  }
159 
160  typename KERNEL_TYPE::LinfStackVariables stack;
161  kernelComponent.setupLinf( i, stack );
162  kernelComponent.computeLinf( i, stack );
163 
164  for( integer j = 0; j < numNorm; ++j )
165  {
166  localResidualNorm[j].max( LvArray::math::abs( stack.localValue[j] ) );
167  }
168  } );
169 
170  for( integer j = 0; j < numNorm; ++j )
171  {
172  residualNorm[j] = localResidualNorm[j].get();
173  }
174  }
175 
185  template< typename POLICY, typename KERNEL_TYPE >
186  static void
187  launchL2( localIndex const size,
188  KERNEL_TYPE const & kernelComponent,
189  real64 (& residualNorm)[numNorm],
190  real64 (& residualNormalizer)[numNorm] )
191  {
192  RAJA::ReduceSum< ReducePolicy< POLICY >, real64 > localResidualNorm[numNorm]{};
193  RAJA::ReduceSum< ReducePolicy< POLICY >, real64 > localResidualNormalizer[numNorm]{};
194 
195  forAll< POLICY >( size, [=] GEOS_HOST_DEVICE ( localIndex const i )
196  {
197  if( kernelComponent.ghostRank( i ) >= 0 )
198  {
199  return;
200  }
201 
202  typename KERNEL_TYPE::L2StackVariables stack;
203  kernelComponent.setupL2( i, stack );
204  kernelComponent.computeL2( i, stack );
205 
206  for( integer j = 0; j < numNorm; ++j )
207  {
208  localResidualNorm[j] += stack.localValue[j];
209  localResidualNormalizer[j] += stack.localNormalizer[j];
210  }
211  } );
212 
213  for( integer j = 0; j < numNorm; ++j )
214  {
215  residualNorm[j] = localResidualNorm[j].get();
216  residualNormalizer[j] = localResidualNormalizer[j].get();
217  }
218  }
219 
220 
221 protected:
222 
225 
228 
231 
234 
237 
238 };
239 
245 {
246 public:
247 
248  template< integer NUM_NORM >
249  static void updateLocalNorm( real64 const (&subRegionResidualNorm)[NUM_NORM],
250  array1d< real64 > & localResidualNorm )
251  {
252  for( integer i = 0; i < NUM_NORM; ++i )
253  {
254  if( subRegionResidualNorm[i] > localResidualNorm[i] )
255  {
256  localResidualNorm[i] = subRegionResidualNorm[i];
257  }
258  }
259  }
260 
261  static void computeGlobalNorm( real64 const & localResidualNorm,
262  real64 & globalResidualNorm )
263  {
264  globalResidualNorm = MpiWrapper::max( localResidualNorm );
265  }
266 
267  static void computeGlobalNorm( array1d< real64 > const & localResidualNorm,
268  array1d< real64 > & globalResidualNorm )
269  {
270  MpiWrapper::allReduce( localResidualNorm.data(),
271  globalResidualNorm.data(),
272  localResidualNorm.size(),
274  MPI_COMM_GEOS );
275  }
276 };
277 
283 {
284 public:
285 
286  template< integer NUM_NORM >
287  static void updateLocalNorm( real64 const (&subRegionResidualNorm)[NUM_NORM],
288  real64 const (&subRegionResidualNormalizer)[NUM_NORM],
289  array1d< real64 > & localResidualNorm,
290  array1d< real64 > & localResidualNormalizer )
291  {
292  for( integer i = 0; i < NUM_NORM; ++i )
293  {
294  localResidualNorm[i] += subRegionResidualNorm[i];
295  localResidualNormalizer[i] += subRegionResidualNormalizer[i];
296  }
297  }
298 
299  static void computeGlobalNorm( real64 const & localResidualNorm,
300  real64 const & localResidualNormalizer,
301  real64 & globalResidualNorm )
302  {
303  globalResidualNorm = sqrt( MpiWrapper::sum( localResidualNorm ) ) / sqrt( MpiWrapper::sum( localResidualNormalizer ) );
304  }
305 
306  static void computeGlobalNorm( array1d< real64 > const & localResidualNorm,
307  array1d< real64 > const & localResidualNormalizer,
308  array1d< real64 > & globalResidualNorm )
309  {
310  array1d< real64 > sumLocalResidualNorm( localResidualNorm.size() );
311  array1d< real64 > sumLocalResidualNormalizer( localResidualNormalizer.size() );
312  MpiWrapper::allReduce( localResidualNorm.data(),
313  sumLocalResidualNorm.data(),
314  localResidualNorm.size(),
316  MPI_COMM_GEOS );
317  MpiWrapper::allReduce( localResidualNormalizer.data(),
318  sumLocalResidualNormalizer.data(),
319  localResidualNormalizer.size(),
321  MPI_COMM_GEOS );
322  for( integer i = 0; i < localResidualNorm.size(); ++i )
323  {
324  globalResidualNorm[i] = sqrt( sumLocalResidualNorm[i] ) / sqrt( sumLocalResidualNormalizer[i] );
325  }
326  }
327 
328 };
329 
334 enum class NormType : integer
335 {
336  Linf,
337  L2
338 };
339 
340 ENUM_STRINGS( NormType,
341  "Linfinity",
342  "L2" );
343 
344 
345 } // namespace physicsSolverBaseKernels
346 
347 } // namespace geos
348 
349 #endif //GEOS_PHYSICSSOLVERS_SOLVERBASEKERNELS_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.
Utility class to compute the global L2 residual norm.
Utility class to compute the global Linf residual norm.
Define the base interface for the residual calculations.
arrayView1d< integer const > const m_ghostRank
View on the ghost ranks.
virtual GEOS_HOST_DEVICE void computeL2(localIndex const i, L2StackVariables &stack) const =0
Compute the local values and normalizer for the L2 norm.
real64 const m_minNormalizer
Value used to make sure that normalizers are never zero.
virtual GEOS_HOST_DEVICE void setupLinf(localIndex const i, LinfStackVariables &stack) const
Setup the residual Linf normal calculations.
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.
static void launchLinf(localIndex const size, KERNEL_TYPE const &kernelComponent, real64(&residualNorm)[numNorm])
Performs the kernel launch for the L-\infty norm.
static void launchL2(localIndex const size, KERNEL_TYPE const &kernelComponent, real64(&residualNorm)[numNorm], real64(&residualNormalizer)[numNorm])
Performs the kernel launch for the L2 norm.
virtual GEOS_HOST_DEVICE void setupL2(localIndex const i, L2StackVariables &stack) const
Setup the residual L2 normal calculations.
arrayView1d< real64 const > const m_localResidual
View on the local residual.
static constexpr integer numNorm
Compile time value for the number of norms to compute.
virtual GEOS_HOST_DEVICE void computeLinf(localIndex const i, LinfStackVariables &stack) const =0
Compute the local values for the Linf norm.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Definition: DataTypes.hpp:180
int MPI_COMM_GEOS
Global MPI communicator used by GEOSX.
GEOS_GLOBALINDEX_TYPE globalIndex
Global index type (for indexing objects across MPI partitions).
Definition: DataTypes.hpp:88
ENUM_STRINGS(LinearSolverParameters::SolverType, "direct", "cg", "gmres", "fgmres", "bicgstab", "preconditioner")
Declare strings associated with enumeration values.
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
Array< T, 1 > array1d
Alias for 1D array.
Definition: DataTypes.hpp:176
static MPI_Op getMpiOp(Reduction const op)
Returns an MPI_Op associated with our strongly typed Reduction enum.
Definition: MpiWrapper.hpp:663
static T max(T const &value, MPI_Comm comm=MPI_COMM_GEOS)
Convenience function for a MPI_Allreduce using a MPI_MAX operation.
static int allReduce(T const *sendbuf, T *recvbuf, int count, MPI_Op op, MPI_Comm comm=MPI_COMM_GEOS)
Strongly typed wrapper around MPI_Allreduce.
static T sum(T const &value, MPI_Comm comm=MPI_COMM_GEOS)
Convenience function for a MPI_Allreduce using a MPI_SUM operation.
real64 localNormalizer[numNorm]
Normalizer value for the element/node/face.
localIndex localRow
Index of the local row in the residual vector.
real64 localValue[numNorm]
Normalized residual value for the element/node/face.