CppNoddy  0.92
Loading...
Searching...
No Matches
BVPHarmonic.cpp
Go to the documentation of this file.
1/// \file BVP_Harmonic.cpp
2/// \ingroup Examples
3/// \ingroup BVP
4/// Solving the Harmonic equation
5/// \f[ f''(z) + f(z) = 0 \f]
6/// subject to \f$ f(0) = 0 \f$ and \f$ f(1) = 1 \f$ (OR \f$ f(i) = 1 \f$)
7/// by applying the ODE_BVP class. We solve for two different cases, the
8/// first is a real BVP along the real axis, the second is a complex BVP
9/// along the imaginary axis.
10
11
12#include <BVP_bundle.h>
13
14#include "../Utils_Fill.h"
15
16// enumerate the variables in the ODE
17enum {f, fd };
18
19namespace CppNoddy
20{
21 namespace Example
22 {
23 /// Define the harmonic equation by inheriting the Equation base class
24 template <typename _Type, typename _Xtype>
25 class Harmonic_equation : public Equation_1matrix<_Type, _Xtype>
26 {
27 public:
28
29 /// The harmonic equation is a 2nd order ODE
30 Harmonic_equation() : Equation_1matrix<_Type, _Xtype>( 2 ) {}
31
32 /// The Berman equation
34 {
35 g[ f ] = z[ fd ];
36 g[ fd ] = - z[ f ];
37 }
38
40 {
42 }
43
44 };
45
46 template <typename _Type>
47 class Harmonic_left_BC : public Residual<_Type>
48 {
49 public:
51
53 {
54 B[ 0 ] = z[ f ];
55 }
56 };
57
58 template <typename _Type>
59 class Harmonic_right_BC : public Residual<_Type>
60 {
61 public:
63
65 {
66 B[ 0 ] = z[ f ] - 1.;
67 }
68 };
69
70
71 } // end Example namespace
72} // end CppNoddy namespace
73
74using namespace CppNoddy;
75using namespace std;
76
77int main()
78{
79 cout << "\n";
80 cout << "=== BVP: finite-difference solution of Harmonic eqn =\n";
81 cout << "\n";
82
84 Example::Harmonic_left_BC <double> real_BC_left;
87 Example::Harmonic_left_BC <D_complex> complex_BC_left;
89
90 double left = 0.0;
91 double right = 1.0;
92 // number of nodal points
93 unsigned N = 21;
94 // a real mesh -- along real axis
95 DenseVector<double> real_nodes( Utility::uniform_node_vector( left, right, N ) );
96 // a complex mesh -- along imaginary axis
97 D_complex eye( 0.0, 1.0 );
98 DenseVector<D_complex> complex_nodes( real_nodes );
99 complex_nodes *= eye;
100 // Example tolerance
101 const double tol = 1.e-4;
102
103 // a real ODE BVP
104 ODE_BVP<double> real_ode( &real_problem, real_nodes, &real_BC_left, &real_BC_right );
105 // a complex ODE BVP solved on a line in the complex plane
106 ODE_BVP<D_complex, D_complex> complex_ode( &complex_problem, complex_nodes, &complex_BC_left, &complex_BC_right );
107 complex_ode.set_monitor_det( false );
108
109 // our initial guess
110 for ( unsigned i = 0; i < N; ++i )
111 {
112 double y = real_ode.solution().coord( i );
113 // set f(y)
114 real_ode.solution()( i, f ) = y;
115 complex_ode.solution()( i, f ) = y;
116 // set f'(y)
117 real_ode.solution()( i, fd ) = 1;
118 complex_ode.solution()( i, fd ) = 1;
119 }
120
121 // solve the problem using 2nd order finite-difference
122 try
123 {
124 real_ode.solve2();
125 complex_ode.solve2();
126 }
127 catch ( const std::runtime_error &error )
128 {
129 cout << " \033[1;31;48m * FAILED THROUGH EXCEPTION BEING RAISED \033[0m\n";
130 return 1;
131 }
132
133 // find the maximum deviation from the analytical solutions of sin(x)/sin(1) and sinh(z)/sinh(1)
134 double real_diff = 0;
135 double complex_diff = 0;
136 for ( unsigned i = 0; i < N; ++i )
137 {
138 real_diff = std::max( std::abs( real_ode.solution()( i, f ) - sin( real_ode.solution().coord( i ) ) / sin( 1 ) ), real_diff );
139 complex_diff = std::max( std::abs( complex_ode.solution()( i, f ) - sin( complex_ode.solution().coord( i ) ) / sin( eye ) ), complex_diff );
140 }
141
142 // validation test
143 if ( real_diff > tol || complex_diff > tol )
144 {
145 cout << "\033[1;31;48m * FAILED \033[0m\n";
146 cout << "Real problem error " << real_diff << "\n";
147 cout << "Complex problem error " << complex_diff << "\n";
148 return 1;
149 }
150 else
151 {
152 cout << "\033[1;32;48m * PASSED \033[0m\n";
153 return 0;
154 }
155}
@ fd
Definition: BVPBerman.cpp:15
@ f
Definition: BVPBerman.cpp:15
@ fd
Definition: BVPHarmonic.cpp:17
@ f
Definition: BVPHarmonic.cpp:17
int main()
Definition: BVPHarmonic.cpp:77
A shorter bundled include file for ODE_BVP and PDE_IBVP codes.
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 IBVP classes (and others).
const DenseMatrix< _Type > & matrix0() const
Return a handle to the matrix.
Define the harmonic equation by inheriting the Equation base class.
Definition: BVPHarmonic.cpp:26
void residual_fn(const DenseVector< _Type > &z, DenseVector< _Type > &g) const
The Berman equation.
Definition: BVPHarmonic.cpp:33
Harmonic_equation()
The harmonic equation is a 2nd order ODE.
Definition: BVPHarmonic.cpp:30
void residual_fn(const DenseVector< _Type > &z, DenseVector< _Type > &B) const
A blank virtual residual function method.
Definition: BVPHarmonic.cpp:52
void residual_fn(const DenseVector< _Type > &z, DenseVector< _Type > &B) const
A blank virtual residual function method.
Definition: BVPHarmonic.cpp:64
A templated object for real/complex vector system of first-order ordinary differential equations.
Definition: ODE_BVP.h:37
void set_monitor_det(bool flag)
Set the flag that determines if the determinant will be monitored The default is to monitor.
Definition: ODE_BVP.h:174
OneD_Node_Mesh< _Type, _Xtype > & solution()
Definition: ODE_BVP.h:187
void solve2()
Formulate and solve the ODE using Newton iteration and a second-order finite difference scheme.
Definition: ODE_BVP.cpp:83
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