CppNoddy  0.92
Loading...
Searching...
No Matches
EVPOrrSommerfeld_lapack.cpp
Go to the documentation of this file.
1/// \file EVPOrrSommerfeld_lapack.cpp
2/// \ingroup Tests
3/// \ingroup EVP
4/// Solves the following linear eigenvalue problem for values \f$ c \f$
5/// that satisfy :
6/// \f[ \phi''(y) - \alpha^2 \phi(y) - \psi(y) = 0\,, \f]
7/// \f[ \psi''(y) - \alpha^2 \psi(y) - i \alpha Re \left \{ ( U(y) - c ) \psi(y) - U''(y) \phi \right \} = 0\,, \f]
8/// subject to \f$ \phi(\pm 1) = \phi'(\pm 1) = 0 \f$ where
9/// \f$ \alpha = 1.02 \f$, \f$ Re = 5772.2 \f$ and \f$ U(y) = 1 - y^2 \f$.
10/// The matrix problem is constructed manually in this case, using second-order
11/// finite differences.
12/// These values approximately correspond to the first neutral temporal mode
13/// in plane Poiseuille flow, therefore the test to be satisfied is that an eigenvalue
14/// exists with \f$ \Im ( c ) \approx 0 \f$.
15
16#include <EVP_bundle.h>
17
18using namespace CppNoddy;
19using namespace std;
20
21int main()
22{
23 cout << "\n";
24 cout << "=== EVP: Temporal spectra of the Orr-Sommerfeld eqn =\n";
25 cout << "=== with a matrix problem assembled by hand.\n";
26 cout << "\n";
27
28
29 // discretise with these many nodal points
30 const std::size_t nodes( 301 );
31 // we'll solve as TWO second order problems
32 const std::size_t N( 2 * nodes );
33 // domain boundaries
34 const double left = -1.0;
35 const double right = 1.0;
36 // spatial step for a uniform mesh
37 const double d = ( right - left ) / ( nodes - 1 );
38
39 // matrices for the EVP, initialised with zeroes
40 DenseMatrix<D_complex> a( N, N, 0.0 );
41 DenseMatrix<D_complex> b( N, N, 0.0 );
42
43 // streamwise wavenumber and Reynolds number
44 const double alpha ( 1.02 );
45 const double Re ( 5772.2 );
46 const D_complex I( 0.0, 1.0 );
47
48 // boundary conditions at the left boundary
49 a( 0, 0 ) = 1.0; // phi( left ) = 0
50 a( 1, 0 ) = -1.5 / d; // phi'( left ) = 0
51 a( 1, 2 ) = 2.0 / d;
52 a( 1, 4 ) = -0.5 / d;
53 // fill the interior nodes
54 for ( std::size_t i = 1; i <= nodes - 2; ++i )
55 {
56 // position in the channel
57 const double y = left + i * d;
58 // Poiseuille flow profile
59 const double U = ( 1.0 - y * y );
60 const double Udd = -2.0;
61
62 // the first quation at the i'th nodal point
63 std::size_t row = 2 * i;
64 a( row, row ) = -2.0 / ( d * d ) - alpha * alpha;
65 a( row, row - 2 ) = 1.0 / ( d * d );
66 a( row, row + 2 ) = 1.0 / ( d * d );
67 a( row, row + 1 ) = -1.0;
68
69 row += 1;
70 // the second equation at the i'th nodal point
71 a( row, row ) = -2.0 / ( d * d ) - alpha * alpha - I * alpha * Re * U;
72 a( row, row - 2 ) = 1.0 / ( d * d );
73 a( row, row + 2 ) = 1.0 / ( d * d );
74 a( row, row - 1 ) = I * alpha * Re * Udd;
75
76 b( row, row ) = - I * alpha * Re;
77 }
78 // boundary conditions at right boundary
79 a( N - 2, N - 2 ) = 1.5 / d;
80 a( N - 2, N - 4 ) = -2.0 / d;
81 a( N - 2, N - 6 ) = 0.5 / d; // psi'( right ) = 0
82 a( N - 1, N - 2 ) = 1.0; // psi( right ) = 0
83 // a vector for the eigenvalues
85 DenseLinearEigenSystem<D_complex> system( &a, &b );
86
87 try
88 {
89 system.eigensolve();
90 }
91 catch (const std::runtime_error &error )
92 {
93 cout << " \033[1;31;48m * FAILED THROUGH EXCEPTION BEING RAISED \033[0m\n";
94 return 1;
95 }
96 // tag any eigenvalues with imaginary part > -0.1
97 system.set_shift( D_complex( 0.0, -0.1 ) );
98 system.tag_eigenvalues_upper( + 1 );
99 lambdas = system.get_tagged_eigenvalues();
100 //lambdas.dump();
101 double min_growth_rate( lambdas[ 0 ].imag() );
102 // make sure we have a near neutral mode
103 const double tol = 1.e-3;
104
105 std::string dirname("./DATA");
106 mkdir( dirname.c_str(), S_IRWXU );
107 TrackerFile spectrum( "./DATA/spectrum.dat" );
108 spectrum.push_ptr( &lambdas, "evs" );
109 spectrum.update();
110 if ( std::abs( min_growth_rate ) < tol )
111 {
112 cout << "\033[1;32;48m * PASSED \033[0m\n";
113 return 0;
114 }
115
116 cout << "\033[1;31;48m * FAILED \033[0m\n";
117 cout << " Final error = " << min_growth_rate << "\n";
118 return 1;
119}
@ U
Definition: BVPKarman.cpp:20
A shorter bundled include file for ODE_EVP and general eigenvalue problems.
A linear Nth-order generalised eigensystem class.
DenseVector< D_complex > get_tagged_eigenvalues() const
Get the the tagged eigenvalues.
void eigensolve()
Solve the matrix linear eigensystem.
void tag_eigenvalues_upper(const int &val)
Tag those eigenvalues that are in the upper half-plane above a specified point.
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
void set_shift(const D_complex &z)
Set the shift value to be used in tagging.
void push_ptr(double *scalar, std::string desc="")
Definition: TrackerFile.cpp:27
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

© 2012

R.E. Hewitt