CppNoddy  0.92
Loading...
Searching...
No Matches
ArcShootFalknerSkan.cpp
Go to the documentation of this file.
1/// \file ArcShootFalknerSkan.cpp
2/// \ingroup Tests
3/// \ingroup Arclength
4/// \ingroup BVP
5/// Arc-length continue the Falkner-Skan equation
6/// \f[ f'''(y) + f(y) f''(y) + \beta \left ( 1 - f'(y)^2 \right )= 0\,, \f]
7/// for varying values of the
8/// Hartree parameter \f$ \beta \f$ -- around the well known limit point. The boundary conditions are
9/// \f$ f(0)=f'(0)=0 \f$ and \f$ f'(\infty) = 1 \f$. We start from the Blasius solution,
10/// then arc-length continue to find the limit point at \f$ \beta \approx -0.19 \f$.
11///
12/// Using Runge-Kutta to solve a BVP is not a great method, but here it's used to
13/// demo the arc-length continuation for scalar problems.
14
15#include <cassert>
16
17#include <IVP_bundle.h>
18#include <Newton_bundle.h>
19
20namespace CppNoddy
21{
22 namespace Example
23 {
24 /// Define the Falkner-Skan equation
25 class FS_eqn : public Equation<double>
26 {
27 public:
28 /// The FSE is a 3rd order ODE
29 FS_eqn() : Equation<double>( 3 ) {}
30
31 /// We implement the equation as 3 first-order real ODEs.
33 {
34 f[ 0 ] = z[ 1 ];
35 f[ 1 ] = z[ 2 ];
36 f[ 2 ] = -z[ 0 ] * z[ 2 ] - beta * ( 1.0 - z[ 1 ] * z[ 1 ] );
37 }
38
39 /// The Hartree parameter
40 double beta;
41
42 };
43
44 /// Define a residual function using the boundary
45 /// conditions for the Blasius profile.
46 class FS_residual : public Residual<double>
47 {
48 public:
51
52 FS_residual() : Residual<double> ( 1 )
53 {
54 eqn = new FS_eqn;
55 eqn -> beta = 0.0; // init the Hartree parameter
56 ode = new ODE_IVP<double> ( eqn, 0.0, 20.0, 2000 );
57 }
58
60 {
61 delete ode;
62 delete eqn;
63 }
64
65 /// implement a residual function.
67 {
68 DenseVector<double> u( 3, 0.0 ); // 3 variables of FS problem
69 u[ 0 ] = 0.0; // f = 0
70 u[ 1 ] = 0.0; // f' = 0
71 u[ 2 ] = z[ 0 ]; // f'' = unknown
72 // shoot the ODE
73 u = ode -> shoot4( u );
74 // return the residual of f'(infty) = 1 condition
75 f[ 0 ] = u[ 1 ] - 1.;
76 }
77 };
78 } // end Example namespace
79} // end CppNoddy namespace
80
81
82using namespace CppNoddy;
83using namespace std;
84
85int main()
86{
87 cout << "\n";
88 cout << "=== ARC: arc-length continuation of the FS equation =\n";
89 cout << "\n";
90
91 // the residual function to be satisfied
93
94 // initial conditions
95 problem.eqn -> beta = -0.11;
96 DenseVector<double> stress( 1, 0.4 );
97 // Scalar Newton iteration problem
98 Newton<double> newton( &problem );
99
100 newton.set_monitor_det( true );
101 // initialise a state for arc length continuation
102 newton.init_arc( stress, &problem.eqn -> beta, -0.01, 0.1 );
103
104 // output for the data
105 std::string dirname("./DATA");
106 mkdir( dirname.c_str(), S_IRWXU );
107 TrackerFile my_file( "./DATA/FSarc_path.dat" );
108 my_file.push_ptr( &problem.eqn -> beta, "Hartree parameter" );
109 my_file.push_ptr( &stress, "Shear stress at the wall" );
110 my_file.header();
111
112 // seek out the limit point in an ad hoc way
113 double approx_limit_point = 0.0;
114 do
115 {
116 double last_beta = problem.eqn -> beta;
117 try
118 {
119 try
120 {
121 newton.arclength_solve( stress );
122 //cout << problem.eqn -> beta << " " << stress[0] << "\n";
123 }
124 catch ( const std::runtime_error &error )
125 {
126 cout << " \033[1;31;48m * FAILED THROUGH EXCEPTION BEING RAISED \033[0m\n";
127 return 1;
128 }
129 }
130 catch ( const ExceptionBifurcation &bifn )
131 {
132 cout << " Bifurcation detected between beta = " << last_beta
133 << " and beta = " << problem.eqn -> beta << "\n";
134 cout << " Continuing further.\n";
135 newton.set_monitor_det( false );
136 approx_limit_point = 0.5 * ( problem.eqn -> beta + last_beta );
137 }
138 my_file.update();
139 }
140 while ( problem.eqn -> beta < -0.1 );
141
142 if ( abs( approx_limit_point + 0.1988 ) > 0.0005 )
143 {
144 cout << "\033[1;31;48m * FAILED \033[0m\n";
145 return 1;
146 }
147 else
148 {
149 cout << "\033[1;32;48m * PASSED \033[0m\n";
150 return 0;
151 }
152}
int main()
@ f
Definition: BVPBerman.cpp:15
A shorter bundled include file for initial-value problems.
A shorter bundled include file for Newton iteration problems.
void init_arc(DenseVector< _Type > x, _Type *p, const double &length, const double &max_length)
Initialise the class ready for arc-length continuation.
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 Falkner-Skan equation.
FS_eqn()
The FSE is a 3rd order ODE.
double beta
The Hartree parameter.
void residual_fn(const DenseVector< double > &z, DenseVector< double > &f) const
We implement the equation as 3 first-order real ODEs.
Define a residual function using the boundary conditions for the Blasius profile.
void residual_fn(const DenseVector< double > &z, DenseVector< double > &f) const
implement a residual function.
A vector NEWTON iteration class.
Definition: Newton.h:25
void set_monitor_det(bool flag)
If set then the system will monitor the sign of determinant of the Jacobian matrix and cause an Excep...
Definition: Newton.h:47
void arclength_solve(DenseVector< _Type > &x)
Arc-length solve the system.
Definition: Newton.cpp:98
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...

© 2012

R.E. Hewitt