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 Total, S.A
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 GEOSX_LINEARALGEBRA_UTILITIES_BLOCKOPERATORVIEW_HPP_
20 #define GEOSX_LINEARALGEBRA_UTILITIES_BLOCKOPERATORVIEW_HPP_
21 
22 #include "codingUtilities/SFINAE_Macros.hpp"
25 
26 namespace geosx
27 {
28 
38 template< typename VECTOR, typename OPERATOR = LinearOperator< VECTOR > >
39 class BlockOperatorView : public LinearOperator< BlockVectorView< VECTOR > >
40 {
41 
42 public:
43 
46 
48  using Vector = typename Base::Vector;
49 
53 
58  virtual ~BlockOperatorView() override = default;
59 
64  BlockOperatorView & operator=( BlockOperatorView const & ) = delete;
65 
71 
73 
74 private:
75 
76  HAS_MEMBER_FUNCTION( numLocalRows, localIndex, );
77  HAS_MEMBER_FUNCTION( numLocalCols, localIndex, );
78  HAS_MEMBER_FUNCTION_NO_RTYPE( applyTranspose, std::declval< Vector const & >(), std::declval< Vector & >() );
79 
80 public:
81 
85 
94  virtual void apply( Vector const & src,
95  Vector & dst ) const override
96  {
97  for( localIndex i = 0; i < numBlockRows(); i++ )
98  {
99  dst.block( i ).zero();
100  VECTOR temp( dst.block( i ) );
101  for( localIndex j = 0; j < numBlockCols(); j++ )
102  {
103  if( m_operators( i, j ) != nullptr )
104  {
105  m_operators( i, j )->apply( src.block( j ), temp );
106  dst.block( i ).axpy( 1.0, temp );
107  }
108  }
109  }
110  }
111 
121  template< typename OP = OPERATOR >
122  std::enable_if_t< HasMemberFunction_applyTranspose< OP > >
124  BlockVectorView< VECTOR > & dst ) const
125  {
126  for( localIndex j = 0; j < numBlockCols(); j++ )
127  {
128  dst.block( j ).zero();
129  VECTOR temp( dst.block( j ) );
130  for( localIndex i = 0; i < numBlockRows(); i++ )
131  {
132  if( m_operators( j, i ) != nullptr )
133  {
134  m_operators( j, i )->applyTranspose( src.block( i ), temp );
135  dst.block( j ).axpy( 1.0, temp );
136  }
137  }
138  }
139  }
140 
145  virtual globalIndex numGlobalRows() const override
146  {
147  return computeRowSize( []( OPERATOR const & block ) { return block.numGlobalRows(); } );
148  }
149 
154  virtual globalIndex numGlobalCols() const override
155  {
156  return computeColSize( []( OPERATOR const & block ) { return block.numGlobalCols(); } );
157  }
158 
164  template< typename OP = OPERATOR >
165  std::enable_if_t< HasMemberFunction_numLocalRows< OP >, localIndex >
166  numLocalRows() const
167  {
168  return computeRowSize( []( OPERATOR const & block ) { return block.numLocalRows(); } );
169  }
170 
176  template< typename OP = OPERATOR >
177  std::enable_if_t< HasMemberFunction_numLocalCols< OP >, localIndex >
178  numLocalCols() const
179  {
180  return computeColSize( []( OPERATOR const & block ) { return block.numLocalCols(); } );
181  }
182 
184 
188 
195  {
196  return m_operators.size( 0 );
197  }
198 
204  {
205  return m_operators.size( 1 );
206  }
207 
214  OPERATOR const & block( localIndex const blockRowIndex, localIndex const blockColIndex ) const
215  {
216  GEOSX_LAI_ASSERT( m_operators( blockRowIndex, blockColIndex ) != nullptr );
217  return *m_operators( blockRowIndex, blockColIndex );
218  }
219 
223  OPERATOR & block( localIndex const blockRowIndex, localIndex const blockColIndex )
224  {
225  GEOSX_LAI_ASSERT( m_operators( blockRowIndex, blockColIndex ) != nullptr );
226  return *m_operators( blockRowIndex, blockColIndex );
227  }
228 
232  OPERATOR const & operator()( localIndex const blockRowIndex, localIndex const blockColIndex = 0 ) const
233  {
234  return block( blockRowIndex, blockColIndex );
235  }
236 
240  OPERATOR & operator()( localIndex const blockRowIndex, localIndex const blockColIndex = 0 )
241  {
242  return block( blockRowIndex, blockColIndex );
243  }
244 
246 
247 protected:
248 
254  BlockOperatorView( localIndex const nRows, localIndex const nCols )
255  : m_operators( nRows, nCols )
256  {
257  GEOSX_LAI_ASSERT_GT( nRows, 0 );
258  GEOSX_LAI_ASSERT_GT( nCols, 0 );
259  }
260 
266 
272 
279  void setPointer( localIndex const blockRowIndex, localIndex const blockColIndex, OPERATOR * op )
280  {
281  GEOSX_LAI_ASSERT_GE( blockRowIndex, 0 );
282  GEOSX_LAI_ASSERT_GT( numBlockRows(), blockRowIndex );
283  GEOSX_LAI_ASSERT_GE( blockColIndex, 0 );
284  GEOSX_LAI_ASSERT_GT( numBlockCols(), blockColIndex );
285  m_operators( blockRowIndex, blockColIndex ) = op;
286  }
287 
288 private:
289 
290  template< typename FUNC >
291  auto computeRowSize( FUNC func ) const -> decltype( func( std::declval< OPERATOR const >() ) );
292 
293  template< typename FUNC >
294  auto computeColSize( FUNC func ) const -> decltype( func( std::declval< OPERATOR const >() ) );
295 
297  array2d< OPERATOR * > m_operators;
298 };
299 
300 template< typename VECTOR, typename OPERATOR >
301 template< typename FUNC >
302 auto BlockOperatorView< VECTOR, OPERATOR >::computeRowSize( FUNC func ) const -> decltype( func( std::declval< OPERATOR const >() ) )
303 {
304  using sizeType = decltype( func( std::declval< OPERATOR const >() ) );
305  sizeType rowSize = 0;
306  for( localIndex i = 0; i < numBlockRows(); ++i )
307  {
308  for( localIndex j = 0; j < numBlockCols(); ++j )
309  {
310  if( m_operators( i, j ) != nullptr )
311  {
312  rowSize += func( block( i, j ) );
313  break;
314  }
315  }
316  }
317  return rowSize;
318 }
319 
320 template< typename VECTOR, typename OPERATOR >
321 template< typename FUNC >
322 auto BlockOperatorView< VECTOR, OPERATOR >::computeColSize( FUNC func ) const -> decltype( func( std::declval< OPERATOR const >() ) )
323 {
324  using sizeType = decltype( func( std::declval< OPERATOR const >() ) );
325  sizeType colSize = 0;
326  for( localIndex j = 0; j < numBlockCols(); j++ )
327  {
328  for( localIndex i = 0; i < numBlockRows(); ++i )
329  {
330  if( m_operators( i, j ) != nullptr )
331  {
332  colSize += func( block( i, j ) );
333  break;
334  }
335  }
336  }
337  return colSize;
338 }
339 
340 }// end geosx namespace
341 
342 
343 #endif /*GEOSX_LINEARALGEBRA_UTILITIES_BLOCKOPERATORVIEW_HPP_*/
localIndex numBlockRows() const
Get number of block rows.
Abstract view of a block operator.
void setPointer(localIndex const blockRowIndex, localIndex const blockColIndex, OPERATOR *op)
Set/replace a pointer to a block.
long long int globalIndex
Global index type (for indexing objects across MPI partitions).
Definition: DataTypes.hpp:128
OPERATOR & operator()(localIndex const blockRowIndex, localIndex const blockColIndex=0)
Get the operator corresponding to a sub-block.
std::enable_if_t< HasMemberFunction_numLocalRows< OP >, localIndex > numLocalRows() const
Get the number of local rows.
std::enable_if_t< HasMemberFunction_applyTranspose< OP > > applyTranspose(BlockVectorView< VECTOR > const &src, BlockVectorView< VECTOR > &dst) const
Apply the transpose of block operator to a block vector.
OPERATOR const & block(localIndex const blockRowIndex, localIndex const blockColIndex) const
Get the operator corresponding to a sub-block.
OPERATOR const & operator()(localIndex const blockRowIndex, localIndex const blockColIndex=0) const
Get the operator corresponding to a sub-block.
BlockOperatorView(localIndex const nRows, localIndex const nCols)
Create an operator with given number of block rows and columns.
virtual globalIndex numGlobalCols() const override
Get the number of global columns.
virtual void apply(Vector const &src, Vector &dst) const override
Apply operator to a vector.
#define GEOSX_LAI_ASSERT_GT(lhs, rhs)
Definition: common.hpp:61
#define GEOSX_LAI_ASSERT_GE(lhs, rhs)
Definition: common.hpp:68
localIndex numBlockCols() const
Get number of block columns.
std::ptrdiff_t localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:125
VECTOR const & block(localIndex const blockIndex) const
Get a reference to the vector corresponding to block blockRowIndex.
#define GEOSX_LAI_ASSERT(expr)
Definition: common.hpp:33
BlockOperatorView & operator=(BlockOperatorView const &)=delete
Deleted copy assignment.
OPERATOR & block(localIndex const blockRowIndex, localIndex const blockColIndex)
Get the operator corresponding to a sub-block.
Abstract base class for linear operators.
BlockVectorView< VECTOR > Vector
Alias for template parameter.
This class provides a fixed dimensional resizeable array interface in addition to an interface simila...
Definition: Array.hpp:55
virtual ~BlockOperatorView() override=default
Destructor.
std::enable_if_t< HasMemberFunction_numLocalCols< OP >, localIndex > numLocalCols() const
Get the number of local columns.
virtual globalIndex numGlobalRows() const override
Get the number of global rows.