CppNoddy  0.92
Loading...
Searching...
No Matches
Functions
EVPHarmonicSparse_slepcd.cpp File Reference

Solves the harmonic equation. More...

#include <Utility.h>
#include <Timer.h>
#include <SparseLinearEigenSystem.h>
#include <SlepcSession.h>
#include "../Utils_Fill.h"

Go to the source code of this file.

Functions

int main (int argc, char *argv[])
 

Detailed Description

Solves the harmonic equation.

\[ f''(x) + \lambda f(x) = 0 \]

as an eigenvalue problem for $ \lambda $ over the unit domain with homogeneous boundary conditions for $ f(x) $, returning any eigenvalue(s) with absolute value less than 10. The resulting eigenvalues should approach $ m^2 \pi^2 $ as $n \to \infty $ with $ O(\Delta^2)$ corrections where $ \Delta = 1/(n-1) $ and $ n $ is the number of nodal points in the FD representation; a 2nd order central difference representation of

\[ f''(x_i) + \lambda f(x_i) = \frac{ f_{i-1} - 2f_i + f_{i+1} }{ \Delta^2 } + \lambda f_i + O(\Delta^2) \]

is used. The matrix problem is solved for a subset of eigenvalues within a specified distance of the origin of the comlplex plane by calling the SLEPc generalised eigenvalue routine.

Definition in file EVPHarmonicSparse_slepcd.cpp.

Function Documentation

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 27 of file EVPHarmonicSparse_slepcd.cpp.

28{
29 SlepcSession::getInstance(argc,argv);
30
31 cout << "\n";
32 cout << "=== EVP: Harmonic equation solved using SLEPc ======\n";
33 cout << "=== with a manually assembled matrix problem.\n";
34 cout << "\n";
35
36 cout.precision( 12 );
37 cout << " Number of nodal points : Leading eigenvalue error : Total CPU time taken (ms) \n";
38 bool failed = false;
39 size_t N = 4;
40 // a vector for the eigenvalues
42 Timer timer;
43 for ( int i = 2; i < 11; ++i )
44 {
45 N = ( size_t ) ( std::pow( 2., i ) );
46 const double delta = 1. / ( N - 1 );
47 const double delta2 = delta * delta;
48 // matrix problem
49 typedef double PETSC_type;
51 // Finite difference representation of f''(x)
52 // here it's a a tri-diagonal system
53 Utils_Fill::fill_band(a, -1, (PETSC_type)(1.0 / delta2));
54 Utils_Fill::fill_band(a, 0, (PETSC_type)(-2.0 / delta2));
55 Utils_Fill::fill_band(a, 1, (PETSC_type)(1.0 / delta2));
56 // overwrite with boundary conditions at f(0) = f(1) = 0
57 a( 0, 0 ) = 1.0;
58 a( 0, 1 ) = 0.0;
59 a( N - 1, N - 1 ) = 1.0;
60 a( N - 1, N - 2 ) = 0.0;
61 // not a generalised problem - but we'll apply that routine anyway
62 // b is the RHS matrix, so it's -I
65 b.scale( -1.0 );
66 b( 0, 0 ) = 0.0;
67 b( N - 1, N - 1 ) = 0.0;
68 // a vector for the eigenvectors - although we won't use them
69 DenseMatrix<D_complex> eigenvectors;
70
71 SparseLinearEigenSystem<PETSC_type> system( &a, &b );
72 system.set_calc_eigenvectors( true );
73 system.set_nev(4);
74 system.set_order( "EPS_TARGET_MAGNITUDE" ); //default
75
76 timer.start();
77 try
78 {
79 system.eigensolve();
80 }
81 catch (const std::runtime_error &error )
82 {
83 cout << " \033[1;31;48m * FAILED THROUGH EXCEPTION BEING RAISED \033[0m\n";
84 return 1;
85 }
86 system.tag_eigenvalues_disc( + 1, 10. );
87 lambdas = system.get_tagged_eigenvalues();
88 eigenvectors = system.get_tagged_eigenvectors();
89 cout << " " << N << " : " << lambdas[ 0 ].real() - M_PI * M_PI
90 << " : " << timer.get_time() << "\n";
91 timer.stop();
92 }
93
94
95 const double tol = 1.e-4;
96 if ( abs( lambdas[ 0 ].real() - M_PI * M_PI ) > tol )
97 failed = true;
98
99 if ( failed )
100 {
101 cout << "\033[1;31;48m * FAILED \033[0m\n";
102 cout << " Final error = " << abs( lambdas[ 0 ].real() - M_PI * M_PI ) << "\n";
103 return 1;
104 }
105
106 cout << "\033[1;32;48m * PASSED \033[0m\n";
107 return 0;
108}
A matrix class that constructs a DENSE matrix as a row major std::vector of DenseVectors.
Definition: DenseMatrix.h:25
An DenseVector class – a dense vector object.
Definition: DenseVector.h:34
A matrix class that constructs a SPARSE matrix as a row major std::vector of SparseVectors.
Definition: SparseMatrix.h:31
A simple CPU-clock-tick timer for timing metods.
Definition: Timer.h:19
double get_time() const
Return the time.
Definition: Timer.cpp:34
void start()
Start the timer & reset stored time to zero.
Definition: Timer.cpp:12
void stop()
Stop the clock & add the current time interval to the previously stored values ready for printing.
Definition: Timer.cpp:17
const double delta(0.5)
DenseVector< double > real(const DenseVector< D_complex > &X)
Return a double DENSE vector containing the real part of a complex DENSE vector.
Definition: Utility.cpp:177
void fill_identity(CppNoddy::Sequential_Matrix_base< _Type > &A)
Fill diagonal with unit values.
Definition: Utils_Fill.h:22
void fill_band(CppNoddy::Sequential_Matrix_base< _Type > &A, const int &offset, const _Type &value)
Fill a diagonal band of a matrix.
Definition: Utils_Fill.h:34

References Utils_Fill::fill_band(), Utils_Fill::fill_identity(), CppNoddy::Timer::get_time(), CppNoddy::SparseMatrix< _Type >::scale(), CppNoddy::Timer::start(), and CppNoddy::Timer::stop().

© 2012

R.E. Hewitt