CppNoddy  0.92
Loading...
Searching...
No Matches
EVPHarmonicEasy_lapack.cpp
Go to the documentation of this file.
1/// \file EVPHarmonicEasy_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/// the smallest eigenvalue. This is the 'easy' approach, using the
9/// ODE_EVP class which is constructed from an Equation_with_mass object, with
10/// Residual objects for the boundary conditions. The solver then
11/// only needs a pointer to the eigenvalue variable.
12
13#include <EVP_bundle.h>
14#include <Utility.h>
15#include "../Utils_Fill.h"
16
17// enumerate the variables in the ODE
18enum {f, fd };
19
20namespace CppNoddy
21{
22 namespace Example
23 {
24 /// Define the harmonic equation by inheriting the Equation base class
25 class harmonic_equation : public Equation_2matrix<double>
26 {
27 public:
28 /// The harmonic equation is a 2nd order real ODE
30
31 /// The harmonic equation
33 {
34 g[ f ] = z[ fd ];
35 g[ fd ] = 0.0;
36 }
37
38 /// matrix to multiply the BVP coordinate
40 {
42 }
43
44 /// Define the eigenvalue terms by providing the mass matrix
45 /// This defines the term lambda * z[ f ] ;
47 {
48 // eigenvalue multiplies unknown 0 in equation 1
49 m( 1, 0 ) = 1.0;
50 }
51
52 };
53
54 class harmonic_both_BC : public Residual<double>
55 {
56 public:
57 // 1 reisudal and 2 unknowns
58 harmonic_both_BC() : Residual<double> ( 1, 2 ) {}
59
61 {
62 B[ 0 ] = z[ f ];
63 }
64 };
65
66 } // end Example namespace
67} // end CppNoddy namespace
68
69using namespace CppNoddy;
70using namespace std;
71
72int main()
73{
74 cout << "\n";
75 cout << "=== EVP: The harmonic equation done the easy way ====\n";
76 cout << "\n";
77
78 // test pass/fail
79 bool failed( true );
80
81
84 // domain is 0 to 1
85 double left = 0.0;
86 double right = 1.0;
87 // number of nodal points
88 int N = 256;
89 // EV is pi^2 so we'll guess = 10 + 0i
90 D_complex guess( 10.0, 0.0 );
91 // pass/fail tolerance
92 const double tol = 1.e-3;
93
94 cout << " Solving the system using LAPACK:\n";
95 // set up the ode eigenproblem
96 ODE_EVP<double> ode_lapack( &problem, Utility::uniform_node_vector( left, right, N ), &BC_both, &BC_both );
97 ode_lapack.p_eigensystem() -> set_calc_eigenvectors( true );
98 ode_lapack.p_eigensystem() -> set_shift( guess );
99 try
100 {
101 // solve the global eigenvalue
102 ode_lapack.eigensolve();
103 }
104 catch (const std::runtime_error &error )
105 {
106 cout << " \033[1;31;48m * FAILED THROUGH EXCEPTION BEING RAISED \033[0m\n";
107 return 1;
108 }
109 // get the eigenvalues in a disk of radius 1 about the guess
110 ode_lapack.p_eigensystem() -> tag_eigenvalues_disc( + 1, 1. );
111 // get the tagged eigenvalue(s) -- hopefully only 1
112 DenseVector<D_complex> lapack_lambdas = ode_lapack.p_eigensystem() -> get_tagged_eigenvalues();
113 if ( abs( lapack_lambdas[ 0 ].real() - M_PI * M_PI ) < tol )
114 {
115 failed = false;
116 cout << " LAPACK solver works.\n";
117 }
118
119 if ( failed )
120 {
121 cout << "\033[1;31;48m * FAILED \033[0m\n";
122 return 1;
123 }
124
125 cout << "\033[1;32;48m * PASSED \033[0m\n";
126 return 0;
127
128}
@ fd
Definition: BVPBerman.cpp:15
@ f
Definition: BVPBerman.cpp:15
int main()
A shorter bundled include file for ODE_EVP and general eigenvalue problems.
A spec for a collection of utility functions.
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
An equation object base class used in the PDE_double_IBVP class.
void residual_fn(const DenseVector< double > &z, DenseVector< double > &B) const
A blank virtual residual function method.
Define the harmonic equation by inheriting the Equation base class.
void matrix0(const DenseVector< double > &z, DenseMatrix< double > &m) const
matrix to multiply the BVP coordinate
void residual_fn(const DenseVector< double > &z, DenseVector< double > &g) const
The harmonic equation.
void matrix1(const DenseVector< double > &z, DenseMatrix< double > &m) const
Define the eigenvalue terms by providing the mass matrix This defines the term lambda * z[ f ] ;.
harmonic_equation()
The harmonic equation is a 2nd order real ODE.
A templated object for real/complex vector system of first-order ordinary differential equations.
Definition: ODE_EVP.h:35
LinearEigenSystem_base * p_eigensystem()
Allow access to the underlying dense linear eigensystem through a pointer to the private member data.
Definition: ODE_EVP.cpp:53
void eigensolve()
Formulate and solve the global eigenvalue problem for a linear system.
Definition: ODE_EVP.cpp:58
A base class to be inherited by objects that define residuals.
Definition: Residual.h:15
double g(1.0)
gravitational acceleration
DenseVector< double > uniform_node_vector(const double &lower, const double &upper, const std::size_t &N)
Return a DENSE vector with the nodal points of a uniform mesh distributed between the upper/lower bou...
Definition: Utility.cpp:113
A collection of OO numerical routines aimed at simple (typical) applied problems in continuum mechani...
std::complex< double > D_complex
A complex double precision number using std::complex.
Definition: Types.h:98
void fill_identity(CppNoddy::Sequential_Matrix_base< _Type > &A)
Fill diagonal with unit values.
Definition: Utils_Fill.h:22

© 2012

R.E. Hewitt