GEOS
BlockOperatorView.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_LINEARALGEBRA_UTILITIES_BLOCKOPERATORVIEW_HPP_
21 #define GEOS_LINEARALGEBRA_UTILITIES_BLOCKOPERATORVIEW_HPP_
22 
23 #include "codingUtilities/SFINAE_Macros.hpp"
26 #include "common/traits.hpp"
28 
29 namespace geos
30 {
31 
41 template< typename VECTOR, typename OPERATOR = LinearOperator< VECTOR > >
42 class BlockOperatorView : public LinearOperator< BlockVectorView< VECTOR > >
43 {
44 
45 public:
46 
49 
51  using Vector = typename Base::Vector;
52 
57 
61  virtual ~BlockOperatorView() override = default;
62 
68 
74 
76 
81 
89  virtual void apply( Vector const & src,
90  Vector & dst ) const override
91  {
92  for( localIndex i = 0; i < numBlockRows(); i++ )
93  {
94  dst.block( i ).zero();
95  VECTOR temp( dst.block( i ) );
96  for( localIndex j = 0; j < numBlockCols(); j++ )
97  {
98  if( m_operators( i, j ) != nullptr )
99  {
100  m_operators( i, j )->apply( src.block( j ), temp );
101  dst.block( i ).axpy( 1.0, temp );
102  }
103  }
104  }
105  }
106 
116  template< typename OP = OPERATOR >
117  std::enable_if_t< traits::VectorBasedTraits< Vector >::template HasMemberFunction_applyTranspose< OP > >
119  BlockVectorView< VECTOR > & dst ) const
120  {
121  for( localIndex j = 0; j < numBlockCols(); j++ )
122  {
123  dst.block( j ).zero();
124  VECTOR temp( dst.block( j ) );
125  for( localIndex i = 0; i < numBlockRows(); i++ )
126  {
127  if( m_operators( j, i ) != nullptr )
128  {
129  m_operators( j, i )->applyTranspose( src.block( i ), temp );
130  dst.block( j ).axpy( 1.0, temp );
131  }
132  }
133  }
134  }
135 
140  virtual globalIndex numGlobalRows() const override
141  {
142  return computeRowSize( []( OPERATOR const & block ) { return block.numGlobalRows(); } );
143  }
144 
149  virtual globalIndex numGlobalCols() const override
150  {
151  return computeColSize( []( OPERATOR const & block ) { return block.numGlobalCols(); } );
152  }
153 
159  virtual localIndex numLocalRows() const override
160  {
161  return computeRowSize( []( OPERATOR const & block ) { return block.numLocalRows(); } );
162  }
163 
169  virtual localIndex numLocalCols() const override
170  {
171  return computeColSize( []( OPERATOR const & block ) { return block.numLocalCols(); } );
172  }
173 
181  virtual MPI_Comm comm() const override
182  {
183  return m_operators( 0, 0 )->comm();
184  }
185 
187 
192 
198  {
199  return m_operators.size( 0 );
200  }
201 
207  {
208  return m_operators.size( 1 );
209  }
210 
217  OPERATOR const & block( localIndex const blockRowIndex, localIndex const blockColIndex ) const
218  {
219  GEOS_LAI_ASSERT( m_operators( blockRowIndex, blockColIndex ) != nullptr );
220  return *m_operators( blockRowIndex, blockColIndex );
221  }
222 
226  OPERATOR & block( localIndex const blockRowIndex, localIndex const blockColIndex )
227  {
228  GEOS_LAI_ASSERT( m_operators( blockRowIndex, blockColIndex ) != nullptr );
229  return *m_operators( blockRowIndex, blockColIndex );
230  }
231 
235  OPERATOR const & operator()( localIndex const blockRowIndex, localIndex const blockColIndex = 0 ) const
236  {
237  return block( blockRowIndex, blockColIndex );
238  }
239 
243  OPERATOR & operator()( localIndex const blockRowIndex, localIndex const blockColIndex = 0 )
244  {
245  return block( blockRowIndex, blockColIndex );
246  }
247 
249 
250 protected:
251 
257  BlockOperatorView( localIndex const nRows, localIndex const nCols )
258  : m_operators( nRows, nCols )
259  {
260  GEOS_LAI_ASSERT_GT( nRows, 0 );
261  GEOS_LAI_ASSERT_GT( nCols, 0 );
262  }
263 
269 
275 
282  void setPointer( localIndex const blockRowIndex, localIndex const blockColIndex, OPERATOR * op )
283  {
284  GEOS_LAI_ASSERT_GE( blockRowIndex, 0 );
285  GEOS_LAI_ASSERT_GT( numBlockRows(), blockRowIndex );
286  GEOS_LAI_ASSERT_GE( blockColIndex, 0 );
287  GEOS_LAI_ASSERT_GT( numBlockCols(), blockColIndex );
288  m_operators( blockRowIndex, blockColIndex ) = op;
289  }
290 
291 private:
292 
293  template< typename FUNC >
294  auto computeRowSize( FUNC func ) const -> decltype( func( std::declval< OPERATOR const >() ) );
295 
296  template< typename FUNC >
297  auto computeColSize( FUNC func ) const -> decltype( func( std::declval< OPERATOR const >() ) );
298 
300  array2d< OPERATOR * > m_operators;
301 };
302 
303 template< typename VECTOR, typename OPERATOR >
304 template< typename FUNC >
305 auto BlockOperatorView< VECTOR, OPERATOR >::computeRowSize( FUNC func ) const -> decltype( func( std::declval< OPERATOR const >() ) )
306 {
307  using sizeType = decltype( func( std::declval< OPERATOR const >() ) );
308  sizeType rowSize = 0;
309  for( localIndex i = 0; i < numBlockRows(); ++i )
310  {
311  for( localIndex j = 0; j < numBlockCols(); ++j )
312  {
313  if( m_operators( i, j ) != nullptr )
314  {
315  rowSize += func( block( i, j ) );
316  break;
317  }
318  }
319  }
320  return rowSize;
321 }
322 
323 template< typename VECTOR, typename OPERATOR >
324 template< typename FUNC >
325 auto BlockOperatorView< VECTOR, OPERATOR >::computeColSize( FUNC func ) const -> decltype( func( std::declval< OPERATOR const >() ) )
326 {
327  using sizeType = decltype( func( std::declval< OPERATOR const >() ) );
328  sizeType colSize = 0;
329  for( localIndex j = 0; j < numBlockCols(); j++ )
330  {
331  for( localIndex i = 0; i < numBlockRows(); ++i )
332  {
333  if( m_operators( i, j ) != nullptr )
334  {
335  colSize += func( block( i, j ) );
336  break;
337  }
338  }
339  }
340  return colSize;
341 }
342 
343 }// end geos namespace
344 
345 
346 #endif /*GEOS_LINEARALGEBRA_UTILITIES_BLOCKOPERATORVIEW_HPP_*/
Abstract view of a block operator.
BlockOperatorView & operator=(BlockOperatorView &&)=delete
Deleted move assignment.
virtual globalIndex numGlobalCols() const override
Get the number of global columns.
virtual globalIndex numGlobalRows() const override
Get the number of global rows.
virtual MPI_Comm comm() const override
Get the MPI communicator the matrix was created with.
OPERATOR const & operator()(localIndex const blockRowIndex, localIndex const blockColIndex=0) const
Get the operator corresponding to a sub-block.
BlockOperatorView(BlockOperatorView< VECTOR, OPERATOR > &&x)=default
Move constructor.
localIndex numBlockCols() const
Get number of block columns.
virtual void apply(Vector const &src, Vector &dst) const override
Apply operator to a vector.
virtual localIndex numLocalCols() const override
Get the number of local columns.
localIndex numBlockRows() const
Get number of block rows.
typename Base::Vector Vector
Alias for vector type.
BlockOperatorView(localIndex const nRows, localIndex const nCols)
Create an operator with given number of block rows and columns.
OPERATOR & operator()(localIndex const blockRowIndex, localIndex const blockColIndex=0)
Get the operator corresponding to a sub-block.
std::enable_if_t< traits::VectorBasedTraits< Vector >::template HasMemberFunction_applyTranspose< OP > > applyTranspose(BlockVectorView< VECTOR > const &src, BlockVectorView< VECTOR > &dst) const
Apply the transpose of block operator to a block vector.
BlockOperatorView(BlockOperatorView< VECTOR, OPERATOR > const &x)=default
Copy constructor.
BlockOperatorView & operator=(BlockOperatorView const &)=delete
Deleted copy assignment.
void setPointer(localIndex const blockRowIndex, localIndex const blockColIndex, OPERATOR *op)
Set/replace a pointer to a block.
virtual ~BlockOperatorView() override=default
Destructor.
virtual localIndex numLocalRows() const override
Get the number of local rows.
OPERATOR const & block(localIndex const blockRowIndex, localIndex const blockColIndex) const
Get the operator corresponding to a sub-block.
OPERATOR & block(localIndex const blockRowIndex, localIndex const blockColIndex)
Get the operator corresponding to a sub-block.
Abstract view of a block vector.
VECTOR const & block(localIndex const blockIndex) const
Get a reference to the vector corresponding to block blockRowIndex.
Abstract base class for linear operators.
BlockVectorView< VECTOR > Vector
Alias for template parameter.
#define GEOS_LAI_ASSERT_GE(lhs, rhs)
Definition: common.hpp:70
#define GEOS_LAI_ASSERT_GT(lhs, rhs)
Definition: common.hpp:63
#define GEOS_LAI_ASSERT(expr)
Definition: common.hpp:35
Array< T, 2, PERMUTATION > array2d
Alias for 2D array.
Definition: DataTypes.hpp:192
GEOS_GLOBALINDEX_TYPE globalIndex
Global index type (for indexing objects across MPI partitions).
Definition: DataTypes.hpp:88
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:85