GEOSX
BlockOperatorView.hpp
Go to the documentation of this file.
1 /*
2  * ------------------------------------------------------------------------------------------------------------
3  * SPDX-License-Identifier: LGPL-2.1-only
4  *
5  * Copyright (c) 2018-2020 Lawrence Livermore National Security LLC
6  * Copyright (c) 2018-2020 The Board of Trustees of the Leland Stanford Junior University
7  * Copyright (c) 2018-2020 TotalEnergies
8  * Copyright (c) 2019- GEOSX Contributors
9  * All rights reserved
10  *
11  * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
12  * ------------------------------------------------------------------------------------------------------------
13  */
14 
19 #ifndef GEOS_LINEARALGEBRA_UTILITIES_BLOCKOPERATORVIEW_HPP_
20 #define GEOS_LINEARALGEBRA_UTILITIES_BLOCKOPERATORVIEW_HPP_
21 
22 #include "codingUtilities/SFINAE_Macros.hpp"
25 #include "common/traits.hpp"
27 
28 namespace geos
29 {
30 
40 template< typename VECTOR, typename OPERATOR = LinearOperator< VECTOR > >
41 class BlockOperatorView : public LinearOperator< BlockVectorView< VECTOR > >
42 {
43 
44 public:
45 
48 
50  using Vector = typename Base::Vector;
51 
56 
60  virtual ~BlockOperatorView() override = default;
61 
67 
73 
75 
80 
88  virtual void apply( Vector const & src,
89  Vector & dst ) const override
90  {
91  for( localIndex i = 0; i < numBlockRows(); i++ )
92  {
93  dst.block( i ).zero();
94  VECTOR temp( dst.block( i ) );
95  for( localIndex j = 0; j < numBlockCols(); j++ )
96  {
97  if( m_operators( i, j ) != nullptr )
98  {
99  m_operators( i, j )->apply( src.block( j ), temp );
100  dst.block( i ).axpy( 1.0, temp );
101  }
102  }
103  }
104  }
105 
115  template< typename OP = OPERATOR >
116  std::enable_if_t< traits::VectorBasedTraits< Vector >::template HasMemberFunction_applyTranspose< OP > >
118  BlockVectorView< VECTOR > & dst ) const
119  {
120  for( localIndex j = 0; j < numBlockCols(); j++ )
121  {
122  dst.block( j ).zero();
123  VECTOR temp( dst.block( j ) );
124  for( localIndex i = 0; i < numBlockRows(); i++ )
125  {
126  if( m_operators( j, i ) != nullptr )
127  {
128  m_operators( j, i )->applyTranspose( src.block( i ), temp );
129  dst.block( j ).axpy( 1.0, temp );
130  }
131  }
132  }
133  }
134 
139  virtual globalIndex numGlobalRows() const override
140  {
141  return computeRowSize( []( OPERATOR const & block ) { return block.numGlobalRows(); } );
142  }
143 
148  virtual globalIndex numGlobalCols() const override
149  {
150  return computeColSize( []( OPERATOR const & block ) { return block.numGlobalCols(); } );
151  }
152 
158  virtual localIndex numLocalRows() const override
159  {
160  return computeRowSize( []( OPERATOR const & block ) { return block.numLocalRows(); } );
161  }
162 
168  virtual localIndex numLocalCols() const override
169  {
170  return computeColSize( []( OPERATOR const & block ) { return block.numLocalCols(); } );
171  }
172 
180  virtual MPI_Comm comm() const override
181  {
182  return m_operators( 0, 0 )->comm();
183  }
184 
186 
191 
197  {
198  return m_operators.size( 0 );
199  }
200 
206  {
207  return m_operators.size( 1 );
208  }
209 
216  OPERATOR const & block( localIndex const blockRowIndex, localIndex const blockColIndex ) const
217  {
218  GEOS_LAI_ASSERT( m_operators( blockRowIndex, blockColIndex ) != nullptr );
219  return *m_operators( blockRowIndex, blockColIndex );
220  }
221 
225  OPERATOR & block( localIndex const blockRowIndex, localIndex const blockColIndex )
226  {
227  GEOS_LAI_ASSERT( m_operators( blockRowIndex, blockColIndex ) != nullptr );
228  return *m_operators( blockRowIndex, blockColIndex );
229  }
230 
234  OPERATOR const & operator()( localIndex const blockRowIndex, localIndex const blockColIndex = 0 ) const
235  {
236  return block( blockRowIndex, blockColIndex );
237  }
238 
242  OPERATOR & operator()( localIndex const blockRowIndex, localIndex const blockColIndex = 0 )
243  {
244  return block( blockRowIndex, blockColIndex );
245  }
246 
248 
249 protected:
250 
256  BlockOperatorView( localIndex const nRows, localIndex const nCols )
257  : m_operators( nRows, nCols )
258  {
259  GEOS_LAI_ASSERT_GT( nRows, 0 );
260  GEOS_LAI_ASSERT_GT( nCols, 0 );
261  }
262 
268 
274 
281  void setPointer( localIndex const blockRowIndex, localIndex const blockColIndex, OPERATOR * op )
282  {
283  GEOS_LAI_ASSERT_GE( blockRowIndex, 0 );
284  GEOS_LAI_ASSERT_GT( numBlockRows(), blockRowIndex );
285  GEOS_LAI_ASSERT_GE( blockColIndex, 0 );
286  GEOS_LAI_ASSERT_GT( numBlockCols(), blockColIndex );
287  m_operators( blockRowIndex, blockColIndex ) = op;
288  }
289 
290 private:
291 
292  template< typename FUNC >
293  auto computeRowSize( FUNC func ) const -> decltype( func( std::declval< OPERATOR const >() ) );
294 
295  template< typename FUNC >
296  auto computeColSize( FUNC func ) const -> decltype( func( std::declval< OPERATOR const >() ) );
297 
299  array2d< OPERATOR * > m_operators;
300 };
301 
302 template< typename VECTOR, typename OPERATOR >
303 template< typename FUNC >
304 auto BlockOperatorView< VECTOR, OPERATOR >::computeRowSize( FUNC func ) const -> decltype( func( std::declval< OPERATOR const >() ) )
305 {
306  using sizeType = decltype( func( std::declval< OPERATOR const >() ) );
307  sizeType rowSize = 0;
308  for( localIndex i = 0; i < numBlockRows(); ++i )
309  {
310  for( localIndex j = 0; j < numBlockCols(); ++j )
311  {
312  if( m_operators( i, j ) != nullptr )
313  {
314  rowSize += func( block( i, j ) );
315  break;
316  }
317  }
318  }
319  return rowSize;
320 }
321 
322 template< typename VECTOR, typename OPERATOR >
323 template< typename FUNC >
324 auto BlockOperatorView< VECTOR, OPERATOR >::computeColSize( FUNC func ) const -> decltype( func( std::declval< OPERATOR const >() ) )
325 {
326  using sizeType = decltype( func( std::declval< OPERATOR const >() ) );
327  sizeType colSize = 0;
328  for( localIndex j = 0; j < numBlockCols(); j++ )
329  {
330  for( localIndex i = 0; i < numBlockRows(); ++i )
331  {
332  if( m_operators( i, j ) != nullptr )
333  {
334  colSize += func( block( i, j ) );
335  break;
336  }
337  }
338  }
339  return colSize;
340 }
341 
342 }// end geosx namespace
343 
344 
345 #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:68
#define GEOS_LAI_ASSERT_GT(lhs, rhs)
Definition: common.hpp:61
#define GEOS_LAI_ASSERT(expr)
Definition: common.hpp:33
Array< T, 2, PERMUTATION > array2d
Alias for 2D array.
Definition: DataTypes.hpp:232
GEOSX_GLOBALINDEX_TYPE globalIndex
Global index type (for indexing objects across MPI partitions).
Definition: DataTypes.hpp:128
GEOSX_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:125