CppNoddy  0.92
Loading...
Searching...
No Matches
IBVPDiffusion.cpp
Go to the documentation of this file.
1/// \file IBVPDiffusion.cpp
2/// \ingroup Tests
3/// \ingroup IBVP
4/// Solving the heat diffusion equation
5/// \f[ f_t = f_{yy} \f]
6/// subject to \f$ f(0) = 0 \f$ and \f$ f(1) = 0 \f$
7/// with initial condition \f$ f(y,t=0) = y(1-y) \f$.
8/// The solution is computed over a range of \f$ t \f$
9/// and the maximum deviation away from the analytical solution is found.
10/// The test fails if this deviation is larger than a set tolerance \f$ \tau \f$.
11/// The analytical solution is the Fourier series:
12/// \f[ f(y,t) = \sum_{n=1,3,...}^M \frac{8}{n^3\pi^3} \sin ( n\pi y) \exp{ -n^2\pi^2 t } \f]
13/// The series is truncated at the \f$ M \f$-th term, in such a way that the
14/// first neglected term is of magnitude \f$ < \tau /10 \f$.
15
16#include <IBVP_bundle.h>
17
18// enumerate the system variables
19enum { f, fd };
20
21namespace CppNoddy
22{
23 namespace Example
24 {
25 class Diff_equation : public Equation_2matrix<double>
26 {
27 public:
28
29 /// The problem is 2nd order and real
30 Diff_equation() : Equation_2matrix<double> ( 2 ) {}
31
32 /// Define the equation
34 {
35 g[ f ] = z[ fd ];
36 g[ fd ] = 0.0;
37 }
38
39 /// Define the (BVP) deriv by providing the identity matrix
41 {
42 m( 0, 0 ) = 1.0;
43 m( 1, 1 ) = 1.0;
44 }
45
46 /// To speed things up we'll overload this to say the mass matrix is constant
48 {
49 // blank definition leads to a zero result
50 }
51
52 /// Define the unsteady terms by providing the mass matrix
54 {
55 m( 1, 0 ) = -1.0;
56 }
57
58 /// To speed things up we'll overload this to say the mass matrix is constant
60 {
61 // blank definition leads to a zero result
62 }
63
64 };
65
66 class Diff_both_BC : public Residual_with_coords<double>
67 {
68 public:
69 // 1 BC and 2 unknowns + 1 time coordinate
70 Diff_both_BC() : Residual_with_coords<double> ( 1, 2, 1 ) {}
71
73 {
74 b[ 0 ] = z[ f ];
75 }
76 };
77 } // end Example namespace
78} // end CppNoddy namespace
79
80using namespace CppNoddy;
81using namespace std;
82
83int main()
84{
85 cout << "\n";
86 cout << "=== IBVP: An unsteady diffusion eqn =================\n";
87 cout << "\n";
88
89 // Diffusion equation
91 // boundary conditions
93
94 // domain definition
95 double left = 0.0;
96 double right = 1.0;
97 // number of (spatial) nodal points
98 unsigned ny = 201;
99 // time step
100 double dt = 0.005;
101 // number of time steps
102 unsigned max_steps = ( unsigned ) ( 3.0 / dt );
103 // test tolerance
104 double tol = 1.e-4;
105
106 // construct our IBVP
107 PDE_IBVP<double> heat( &problem, Utility::uniform_node_vector( left, right, ny ), &BC_both, &BC_both );
108
109 for ( unsigned i = 0; i < ny; ++i )
110 {
111 double y = heat.solution().coord( i );
112 heat.solution()( i, f ) = y * ( 1 - y );
113 heat.solution()( i, fd ) = 1 - 2 * y;
114 }
115
116 // maximum difference between numerical and series solution at centre point
117 double max_diff( 0.0 );
118 // time step
119 for ( unsigned i = 1; i < max_steps; ++i )
120 {
121 // take a time step
122 try
123 {
124 heat.step2( dt );
125 }
126 catch (const std::runtime_error &error )
127 {
128 cout << " \033[1;31;48m * FAILED THROUGH EXCEPTION BEING RAISED \033[0m\n";
129 return 1;
130 }
131
132 // evaluate analytical Fourier series solution at y = 0.5
133 unsigned mid = ( ny - 1 ) / 2;
134 double y = left + mid * ( right - left ) / ( ny - 1 );
135 double u( 0.0 );
136 int en( -1 );
137 double correction( 0.0 );
138 do
139 {
140 en += 2;
141 correction = 8 / ( std::pow( en * M_PI, 3 ) )
142 * std::exp( -std::pow( en * M_PI, 2 ) * heat.coord() ) * std::sin( en * M_PI * y );
143 u += correction;
144 }
145 while ( std::abs( correction ) > tol / 10. );
146 // examine the difference between the numerical and series solutions
147 max_diff = std::max( max_diff, std::abs( u - heat.solution()( mid, f ) ) );
148 }
149
150 bool failed = true;
151 if ( abs( max_diff ) < tol )
152 {
153 failed = false;
154 }
155
156 if ( failed )
157 {
158 cout << "\033[1;31;48m * FAILED \033[0m\n";
159 return 1;
160 }
161 else
162 {
163 cout << "\033[1;32;48m * PASSED \033[0m\n";
164 return 0;
165 }
166
167}
@ fd
Definition: BVPBerman.cpp:15
@ f
Definition: BVPBerman.cpp:15
@ fd
@ f
int main()
A shorter bundled include file for initial boundary 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 PDE_double_IBVP class.
void residual_fn(const DenseVector< double > &z, DenseVector< double > &b) const
Diff_equation()
The problem is 2nd order and real.
void get_jacobian_of_matrix0_mult_vector(const DenseVector< double > &state, const DenseVector< double > &vec, DenseMatrix< double > &h) const
To speed things up we'll overload this to say the mass matrix is constant.
void get_jacobian_of_matrix1_mult_vector(const DenseVector< double > &state, const DenseVector< double > &vec, DenseMatrix< double > &h) const
To speed things up we'll overload this to say the mass matrix is constant.
void matrix0(const DenseVector< double > &z, DenseMatrix< double > &m) const
Define the (BVP) deriv by providing the identity matrix.
void matrix1(const DenseVector< double > &z, DenseMatrix< double > &m) const
Define the unsteady terms by providing the mass matrix.
void residual_fn(const DenseVector< double > &z, DenseVector< double > &g) const
Define the equation.
A templated object for real/complex vector system of unsteady equations.
Definition: PDE_IBVP.h:37
void step2(const double &dt)
A Crank-Nicolson 'time' stepper.
Definition: PDE_IBVP.cpp:72
OneD_Node_Mesh< _Type > & solution()
Definition: PDE_IBVP.h:127
double & coord()
Return a reference to the current value of the 'timelike/parabolic' coordinate.
Definition: PDE_IBVP.h:65
A base class to be inherited by objects that define residuals.
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...

© 2012

R.E. Hewitt