GEOS
Arnoldi.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 TotalEnergies
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_ARNOLDI_HPP_
21 #define GEOS_LINEARALGEBRA_UTILITIES_ARNOLDI_HPP_
22 
23 #include "denseLinearAlgebra/interfaces/blaslapack/BlasLapackLA.hpp"
25 
26 namespace geos
27 {
28 
36 template< typename VECTOR >
38 {
39  localIndex const numGlobalRows = LvArray::integerConversion< localIndex >( op.numGlobalRows() );
40  localIndex const numLocalRows = op.numLocalRows();
41  localIndex const mInternal = std::min( numGlobalRows, m );
42 
43  // Initialize data structure (Hessenberg matrix and Krylov subspace)
44  array2d< real64, MatrixLayout::ROW_MAJOR_PERM > H( mInternal+1, mInternal );
45  array1d< VECTOR > V( mInternal + 1 );
46 
47  // Initial unitary vector
48  V[0].create( numLocalRows, op.comm() );
49  V[0].set( 1.0 / sqrt( static_cast< real64 >( numGlobalRows ) ) );
50 
51  for( localIndex j = 0; j < mInternal; ++j )
52  {
53  // Apply operator
54  V[j+1].create( numLocalRows, op.comm() );
55  op.apply( V[j], V[j+1] );
56  // Arnoldi process
57  for( localIndex i = 0; i <= j; ++i )
58  {
59  H( i, j ) = V[i].dot( V[j+1] );
60  V[j+1].axpy( -H( i, j ), V[i] );
61  }
62  H( j+1, j ) = V[j+1].norm2();
63  V[j+1].scale( 1.0 / H( j+1, j ) );
64  }
65 
66  // Disregard the last entry and make the matrix square
67  // Note: this is ok since we are using ROW_MAJOR_PERM
68  H.resize( mInternal, mInternal );
69 
70  // Compute the eigenvalues
71  array1d< std::complex< real64 > > lambda( mInternal );
72  BlasLapackLA::matrixEigenvalues( H, lambda );
73 
74  // Find the largest eigenvalues
75  real64 lambdaMax = 0.0;
76  for( localIndex i = 0; i < mInternal; ++i )
77  {
78  lambdaMax = std::max( std::abs( lambda[i] ), lambdaMax );
79  }
80 
81  return lambdaMax;
82 }
83 
84 } // namespace geos
85 
86 #endif //GEOS_LINEARALGEBRA_UTILITIES_ARNOLDI_HPP_
Abstract base class for linear operators.
virtual globalIndex numGlobalRows() const =0
Get the number of global rows.
virtual localIndex numLocalRows() const =0
Get the number of local rows.
virtual void apply(Vector const &src, Vector &dst) const =0
Apply operator to a vector, dst = this(src).
virtual MPI_Comm comm() const =0
Get the MPI communicator the matrix was created with.
Array< T, 2, PERMUTATION > array2d
Alias for 2D array.
Definition: DataTypes.hpp:192
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
real64 ArnoldiLargestEigenvalue(LinearOperator< VECTOR > const &op, localIndex const m=4)
Function implementing the Arnoldi scheme to compute the largest eigenvalue.
Definition: Arnoldi.hpp:37
Array< T, 1 > array1d
Alias for 1D array.
Definition: DataTypes.hpp:176