CppNoddy  0.92
All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Modules Pages
EVPHarmonic_lapack.cpp
Go to the documentation of this file.
1/// \file EVPHarmonic_lapack.cpp
2/// \ingroup Tests
3/// \ingroup EVP
4/// Solves the harmonic equation
5/// \f[ f''(x) + \lambda f(x) = 0 \f]
6/// as an eigenvalue problem for \f$ \lambda \f$ over the unit domain
7/// with homogeneous boundary conditions for \f$ f(x) \f$, returning
8/// any eigenvalue(s) with absolute value less than 10. The resulting
9/// eigenvalues should approach \f$ m^2 \pi^2 \f$ as \f$n \to \infty \f$ with
10/// \f$ O(\Delta^2)\f$ corrections where \f$ \Delta = 1/(n-1) \f$ and \f$ n \f$ is the number
11/// of nodal points in the FD representation; a 2nd order
12/// central difference representation of
13/// \f[ f''(x_i) + \lambda f(x_i) = \frac{ f_{i-1} - 2f_i + f_{i+1} }{ \Delta^2 } + \lambda f_i + O(\Delta^2) \f]
14/// is used. The matrix problem is solved for all eigenvalues within a specified distance
15/// of the origin of the comlplex plane by calling the LAPACK generalised eigenvalue routine.
16
17#include <Utility.h>
18#include <EVP_bundle.h>
19
20#include "../Utils_Fill.h"
21
22using namespace CppNoddy;
23using namespace std;
24
25int main()
26{
27 cout << "\n";
28 cout << "=== EVP: Harmonic equation solved using LAPACK =====\n";
29 cout << "=== with a manually assembled matrix problem.\n";
30 cout << "\n";
31
32 cout.precision( 12 );
33 cout << " Number of nodal points : Leading eigenvalue error : Total CPU time taken (ms) \n";
34 bool failed = false;
35 size_t N = 4;
36 // a vector for the eigenvalues
38 Timer timer;
39 for ( int i = 2; i < 11; ++i )
40 {
41 N = ( size_t ) ( std::pow( 2., i ) );
42 const double delta = 1. / ( N - 1 );
43 const double delta2 = delta * delta;
44 // matrix problem
45 DenseMatrix<double> a( N, N, 0.0 );
46 // Finite difference representation of f''(x)
47 // here it's a a tri-diagonal system
48 Utils_Fill::fill_band(a,-1, 1.0/delta2);
49 Utils_Fill::fill_band(a, 0,-2.0/delta2);
50 Utils_Fill::fill_band(a, 1, 1.0/delta2);
51 // overwrite with boundary conditions at f(0) = f(1) = 0
52 a( 0, 0 ) = 1.0;
53 a( 0, 1 ) = 0.0;
54 a( N - 1, N - 1 ) = 1.0;
55 a( N - 1, N - 2 ) = 0.0;
56 // not a generalised problem - but we'll apply that routine anyway
57 // b is the RHS matrix, so it's -I
58 DenseMatrix<double> b( N, N, 0.0 );
60 b.scale( -1.0 );
61 b( 0, 0 ) = 0.0;
62 b( N - 1, N - 1 ) = 0.0;
63 // a vector for the eigenvectors - although we won't use them
64 DenseMatrix<D_complex> eigenvectors;
65
66 DenseLinearEigenSystem<double> system( &a, &b );
67 system.set_calc_eigenvectors( true );
68
69 timer.start();
70 try
71 {
72 system.eigensolve();
73 }
74 catch (const std::runtime_error &error )
75 {
76 cout << " \033[1;31;48m * FAILED THROUGH EXCEPTION BEING RAISED \033[0m\n";
77 return 1;
78 }
79 system.tag_eigenvalues_disc( + 1, 10. );
80 lambdas = system.get_tagged_eigenvalues();
81 eigenvectors = system.get_tagged_eigenvectors();
82 cout << " " << N << " : " << lambdas[ 0 ].real() - M_PI * M_PI
83 << " : " << timer.get_time() << "\n";
84 timer.stop();
85 }
86
87 const double tol = 1.e-4;
88 if ( abs( lambdas[ 0 ].real() - M_PI * M_PI ) > tol )
89 failed = true;
90
91 if ( failed )
92 {
93 cout << "\033[1;31;48m * FAILED \033[0m\n";
94 cout << " Final error = " << abs( lambdas[ 0 ].real() - M_PI * M_PI ) << "\n";
95 return 1;
96 }
97
98 cout << "\033[1;32;48m * PASSED \033[0m\n";
99 return 0;
100}
int main()
A shorter bundled include file for ODE_EVP and general eigenvalue problems.
A spec for a collection of utility functions.
A linear Nth-order generalised eigensystem class.
void tag_eigenvalues_disc(const int &val, const double &radius)
Tag those eigenvalues that are within a disc centred at a point in the complex plane.
DenseVector< D_complex > get_tagged_eigenvalues() const
Get the the tagged eigenvalues.
void eigensolve()
Solve the matrix linear eigensystem.
DenseMatrix< D_complex > get_tagged_eigenvectors() const
Get the the tagged eigenvectors.
A matrix class that constructs a DENSE matrix as a row major std::vector of DenseVectors.
Definition: DenseMatrix.h:25
void scale(const _Type &mult)
Scale all matrix elements by a scalar.
An DenseVector class – a dense vector object.
Definition: DenseVector.h:34
void set_calc_eigenvectors(bool flag)
Compute the eigenvectors in any eigenvalue computation.
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
A collection of OO numerical routines aimed at simple (typical) applied problems in continuum mechani...
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

© 2012

R.E. Hewitt