GEOSX
Arnoldi.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_SOLVERS_ARNOLDI_HPP_
20 #define GEOSX_LINEARALGEBRA_SOLVERS_ARNOLDI_HPP_
21 
25 
26 namespace geosx
27 {
28 
32 template< typename MATRIX, typename VECTOR >
33 class NormalOperator : public LinearOperator< VECTOR >
34 {
35 public:
36 
42  void set( MATRIX const & matrix, MPI_Comm const comm )
43  {
44  m_matrix = &matrix;
45  m_comm = comm;
46  }
47 
52  globalIndex numGlobalRows() const override
53  {
54  return m_matrix->numGlobalRows();
55  }
56 
61  globalIndex numGlobalCols() const override
62  {
63  return m_matrix->numGlobalCols();
64  }
65 
71  {
72  return m_matrix->numLocalRows();
73  }
74 
79  MPI_Comm const & getComm() const
80  {
81  return m_comm;
82  }
83 
89  void apply( VECTOR const & x, VECTOR & y ) const override
90  {
91  m_matrix->gemv( 1.0, x, 0.0, y, false );
92  m_matrix->gemv( 1.0, y, 0.0, y, true );
93  }
94 
95 private:
96 
98  MATRIX const * m_matrix;
99 
101  MPI_Comm m_comm;
102 };
103 
110 template< typename Operator >
111 real64 ArnoldiLargestEigenvalue( Operator const & op, localIndex const m = 4 )
112 {
113  using Vector = typename Operator::Vector;
114 
115  localIndex const numGlobalRows = LvArray::integerConversion< localIndex >( op.numGlobalRows() );
116  localIndex const numLocalRows = op.numLocalRows();
117  localIndex const mInternal = ( m > numGlobalRows ) ? numGlobalRows : m;
118 
119  // Initialize data structure (Hessenberg matrix and Krylov subspace)
120  array2d< real64, MatrixLayout::ROW_MAJOR_PERM > H( mInternal+1, mInternal );
121  array1d< Vector > V( mInternal+1 );
122 
123  // Initial unitary vector
124  V[0].createWithLocalSize( numLocalRows, op.getComm() );
125  V[0].set( 1.0 / sqrt( static_cast< real64 >( numGlobalRows ) ) );
126 
127  for( localIndex j = 0; j < mInternal; ++j )
128  {
129  // Apply operator
130  V[j+1].createWithLocalSize( numLocalRows, op.getComm() );
131  op.apply( V[j], V[j+1] );
132  // Arnoldi process
133  for( localIndex i = 0; i <= j; ++i )
134  {
135  H( i, j ) = V[i].dot( V[j+1] );
136  V[j+1].axpy( -H( i, j ), V[i] );
137  }
138  H( j+1, j ) = V[j+1].norm2();
139  V[j+1].scale( 1.0 / H( j+1, j ) );
140  }
141 
142  // Disregard the last entry and make the matrix square
143  // Note: this is ok since we are using ROW_MAJOR_PERM
144  H.resize( mInternal, mInternal );
145 
146  // Compute the eigenvalues
147  array1d< std::complex< real64 > > lambda( mInternal );
148  BlasLapackLA::matrixEigenvalues( H, lambda );
149 
150  // Find the largest eigenvalues
151  real64 lambdaMax = 0.0;
152  for( localIndex i = 0; i < mInternal; ++i )
153  {
154  lambdaMax = ( std::abs( lambda[i] ) > lambdaMax ) ? std::abs( lambda[i] ) : lambdaMax;
155  }
156 
157  return lambdaMax;
158 }
159 
160 } // namespace geosx
161 
162 #endif //GEOSX_LINEARALGEBRA_SOLVERS_ARNOLDI_HPP_
localIndex numLocalRows() const
Returns the local number of rows.
Definition: Arnoldi.hpp:70
long long int globalIndex
Global index type (for indexing objects across MPI partitions).
Definition: DataTypes.hpp:128
NormalOperator Simple class to apply the operator A^T * A to a vector.
Definition: Arnoldi.hpp:33
float sqrt(float const x)
Definition: math.hpp:121
MPI_Comm const & getComm() const
Returns the communicator.
Definition: Arnoldi.hpp:79
double real64
64-bit floating point type.
Definition: DataTypes.hpp:136
real64 ArnoldiLargestEigenvalue(Operator const &op, localIndex const m=4)
Function implementing the Arnoldi scheme to compute the largest eigenvalue.
Definition: Arnoldi.hpp:111
void apply(VECTOR const &x, VECTOR &y) const override
Applies the matrix and its transpose to a vector.
Definition: Arnoldi.hpp:89
globalIndex numGlobalRows() const override
Returns the global number of rows.
Definition: Arnoldi.hpp:52
float abs(float const x)
Definition: math.hpp:81
static void matrixEigenvalues(MatRowMajor< real64 const > const &A, Vec< std::complex< real64 > > const &lambda)
Computes the eigenvalues of A.
void resize(int const numDims, DIMS_TYPE const *const dims)
Resize the dimensions of the Array to match the given dimensions.
Definition: Array.hpp:277
std::ptrdiff_t localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:125
Abstract base class for linear operators.
VECTOR Vector
Alias for template parameter.
globalIndex numGlobalCols() const override
Returns the global number of columns.
Definition: Arnoldi.hpp:61
This class provides a fixed dimensional resizeable array interface in addition to an interface simila...
Definition: Array.hpp:55