CppNoddy  0.92
Loading...
Searching...
No Matches
BlasiusShooting.cpp
Go to the documentation of this file.
1/// \file BlasiusShooting.cpp
2/// \ingroup Tests
3/// \ingroup BVP
4/// Solving the Blasius equation
5/// \f[ f'''(y) + f(y) f''(y) = 0\,, \f]
6/// with \f$ f(0)=f'(0)=0 \f$ and \f$ f'(\infty) = 1 \f$
7/// via Runge-Kutta and (scalar) Newton iteration.
8///
9/// Solving a BVP via local methods such as these is generally
10/// not a great way of doing things. Actually, in this case
11/// the BVP can formally be converted to an IVP and iteration
12/// can be avoided altogether. Here we check the iteration plus
13/// IVP approach by comparing it with the Cauchy problem formulation.
14
15#include <IVP_bundle.h>
16
17#include "../Utils_Fill.h"
18
19namespace CppNoddy
20{
21 namespace Example
22 {
23 /// Define the Blasius equation by
24 /// inheriting Equation base class.
25 class Blasius_equation : public Equation<double>
26 {
27 public:
28
29 /// Construct a 3rd order real system
30 Blasius_equation( ) : Equation<double>( 3 ) {}
31
32 /// We implement the equation as 3 first-order ODEs.
34 {
35 f[ 0 ] = z[ 1 ];
36 f[ 1 ] = z[ 2 ];
37 f[ 2 ] = -z[ 0 ] * z[ 2 ];
38 }
39
41 {
43 }
44 };
45
46 /// Define a residual function using the boundary
47 /// conditions for the Blasius profile.
48 class Blasius_residual : public Residual<double>
49 {
50 public:
52
53 Blasius_residual() : Residual<double> ( 1 )
54 {
55 // instantiate the Blasius equation as our problem
56 eqn = new Blasius_equation;
57 // instantiate an ODE in [0,20] with a maximum of
58 // 1000 integrator steps, using this problem equation
59 ode = new ODE_IVP<double>( eqn, 0.0, 20.0, 1000 );
60 // let's keep the history of the IVP for output in main
61 }
62
64 {
65 // clean up the created objects
66 delete ode;
67 delete eqn;
68 }
69
70 /// implement a residual function.
71 void residual_fn( const DenseVector<double>& unknown, DenseVector<double>& BC ) const
72 {
73 DenseVector<double> u( 3, 0.0 ); // 3 variables of Blasius problem
74 u[ 0 ] = 0.0; // f = 0
75 u[ 1 ] = 0.0; // f' = 0
76 u[ 2 ] = unknown[ 0 ]; // f'' = unknown
77 // shoot with the RKF method, tolerance of 1.e-9
78 u = ode -> shoot45( u, 1.e-7, 0.01 );
79 // return the residual of f'(infty) = 1 condition
80 BC[ 0 ] = u[ 1 ] - 1.;
81 }
82 private:
84 };
85 } // end Example namespace
86} // end CppNoddy namespace
87
88
89using namespace CppNoddy;
90using namespace std;
91
92int main()
93{
94 cout << "\n";
95 cout << "=== BVP_Shoot: scalar Newton solution of Blasius ====\n";
96 cout << "\n";
97
99 // instantiate a scalar Newton class for the one Blasius residual
100 Newton<double> Blasius( &problem );
101
102 DenseVector<double> stress( 1, 0.0 );
103 stress[ 0 ] = 1.0;
104 try
105 {
106 Blasius.iterate( stress );
107 }
108 catch (const std::runtime_error &error )
109 {
110 cout << " \033[1;31;48m * FAILED THROUGH EXCEPTION BEING RAISED \033[0m\n";
111 return 1;
112 }
113
114 // output the data
115 std::string dirname("./DATA");
116 mkdir( dirname.c_str(), S_IRWXU );
117 TrackerFile my_file( "./DATA/Blasius.dat" );
118 my_file.push_ptr( &( problem.ode -> get_mesh() ) );
119 my_file.update();
120
121 // There is a rescaling that removes any need to iterate
122 // c = f'(infty) when stress = 1 at the plate
123 const double c = 1.65519036023e0;
124 const double answer = 1. / pow( c, 3. / 2. );
125
126 const double tol( 1.e-6 ); // A pass/fail tolerance
127 if ( abs( stress[0] - answer ) > tol )
128 {
129 cout << "\033[1;31;48m * FAILED \033[0m\n";
130 cout.precision( 14 );
131 cout << abs( stress[0] - answer ) << " > " << tol << "\n";
132 return 1;
133 }
134 else
135 {
136 cout << "\033[1;32;48m * PASSED \033[0m\n";
137 return 0;
138 }
139}
@ f
Definition: BVPBerman.cpp:15
int main()
A shorter bundled include file for initial-value problems.
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 BVP/IVP classes.
Definition: Equation.h:22
Define the Blasius equation by inheriting Equation base class.
Blasius_equation()
Construct a 3rd order real system.
void mass(const DenseVector< double > &x, DenseMatrix< double > &m) const
void residual_fn(const DenseVector< double > &z, DenseVector< double > &f) const
We implement the equation as 3 first-order ODEs.
Define a residual function using the boundary conditions for the Blasius profile.
void residual_fn(const DenseVector< double > &unknown, DenseVector< double > &BC) const
implement a residual function.
A vector NEWTON iteration class.
Definition: Newton.h:25
void iterate(DenseVector< _Type > &x)
The Newton iteration method.
Definition: Newton.cpp:35
A templated object for real/complex vector system of first-order ordinary differential equations.
Definition: ODE_IVP.h:20
A base class to be inherited by objects that define residuals.
Definition: Residual.h:15
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...
void fill_identity(CppNoddy::Sequential_Matrix_base< _Type > &A)
Fill diagonal with unit values.
Definition: Utils_Fill.h:22

© 2012

R.E. Hewitt