CppNoddy  0.92
Loading...
Searching...
No Matches
IBVPNonlinearAdvDiffusion.cpp
Go to the documentation of this file.
1/// \file IBVPNonlinearAdvDiffusion.cpp
2/// \ingroup Tests
3/// \ingroup IBVP
4/// Solving the nonlinear advection diffusion equation
5/// \f[ U_{yy} - Re U U_t = S( y, t ) \f]
6/// subject to \f$ U(y=0,t) = 1 \f$ and \f$ U(y=1,t) = 2 \f$
7/// with initial condition
8/// \f$ U(y,t=0) = 1 + y + \epsilon y(1-y) \f$ and
9/// a source term
10/// \f[ S(y,t) = ( 1 + y + \epsilon y(1-y)e^{-t} ) \epsilon y(1-y ) e^{-t} - 2\epsilon e^{-t} / Re \f]
11/// for some constant parameters \f$\epsilon \f$ and \f$ Re \f$.
12/// This source term is chosen to allow an exact solution
13/// \f[ U(y,t) = 1 + y + \epsilon y(1-y) e^{-t} \f]
14/// against which the numerical computation is compared, by computing
15/// the maximum absolute deviation over all spatial and temporal nodes.
16
17#include <IBVP_bundle.h>
18
19enum { U, Ud };
20
21namespace CppNoddy
22{
23 namespace Example
24 {
25
26 // Global parameters
27 // A diffusivity measure
28 double Re;
29 // Amplitude of a kick to the initial profile
30 const double eps( 2.0 );
31 // A source term rigged up to give a nice exact solution
32 double source( const double& y, const double& t )
33 {
34 return ( 1 + y + eps * y * ( 1 - y ) * std::exp( -t ) ) * eps * y * ( 1 - y ) * std::exp( -t )
35 - 2 * eps * std::exp( - t ) / Re;
36 }
37
38 class Nlin_adv_equation : public Equation_2matrix<double>
39 {
40 public:
41
42 /// The problem is 2nd order and real
44
45 /// Define a nonlinear advection diffusion problem
47 {
48 // The system
49 f[ U ] = z[ Ud ];
50 f[ Ud ] = source( coord(0), coord(1) );
51 }
52
53 /// Define the derivative terms by providing the mass matrix -- identity in this case
55 {
56 m(0,0)=1;m(1,1)=1;
57 }
58
60 {
61 /// constant mass matrix, so we'll overlload this as empty to speed things up
62 }
63
64 /// Define the unsteady terms by providing the mass matrix
66 {
67 m( 1, 0 ) = - Re * z[ U ];
68 }
69
71 {
72 h( 1, U ) = - Re * vec[ 0 ];
73 }
74
75 };
76
77 // BOUNDARY CONDITIONS
79 {
80 public:
81 Nlin_adv_left_BC() : Residual_with_coords<double> ( 1, 2, 1 ) {}
82
84 {
85 b[ 0 ] = z[ U ] - 1.0;
86 }
87 };
88
90 {
91 public:
92 Nlin_adv_right_BC() : Residual_with_coords<double> ( 1, 2, 1 ) {}
93
95 {
96 b[ 0 ] = z[ U ] - 2.0;
97 }
98 };
99
100
101 } // end Test namespace
102} // end CppNoddy namespace
103
104using namespace CppNoddy;
105using namespace std;
106
107int main()
108{
109 cout << "\n";
110 cout << "=== IBVP: Nonlinear advection diffusion =============\n";
111 cout << "\n";
112
113 // instantiate the problem
117
118 // domain definition
119 double left = 0.0;
120 double right = 1.0;
121 // number of (spatial) nodal points
122 unsigned ny = 400;
123 // number of time steps
124 unsigned max_steps = 4000;
125 // time step
126 double dt = 1.0 / ( max_steps - 1 );
127
128 // initial rotation frequency
129 Example::Re = 1.0;
130
131 // construct our IBVP
132 PDE_IBVP<double> advection( &problem, Utility::uniform_node_vector( left, right, ny ), &BC_left, &BC_right );
133
134 // initial conditions
135 for ( unsigned i = 0; i < ny; ++i )
136 {
137 double y = advection.solution().coord( i );
138 advection.solution()( i, U ) = 1.0 + y + Example::eps * y * ( 1 - y );
139 advection.solution()( i, Ud ) = 1.0;
140 }
141
142 // set up output details
143 std::string dirname("./DATA");
144 mkdir( dirname.c_str(), S_IRWXU );
145 TrackerFile my_file( "./DATA/IBVP_NlinAdvection.dat" );
146 my_file.push_ptr( &advection.coord(), "time" );
147 my_file.push_ptr( &advection.solution(), "Solution profile" );
148 my_file.header();
149
150 double max_err( 0.0 );
151 // time step
152 for ( unsigned i = 1; i < max_steps; ++i )
153 {
154 // take a time step
155 try
156 {
157 advection.step2( dt );
158 }
159 catch ( const std::runtime_error &error )
160 {
161 cout << " \033[1;31;48m * FAILED THROUGH EXCEPTION BEING RAISED \033[0m\n";
162 return 1;
163 }
164 if ( i % 100 == 0 )
165 {
166 my_file.update();
167 my_file.newline();
168 }
169 // generate the exact solution to compare to
170 for ( unsigned i = 0; i < ny; ++i )
171 {
172 double y = advection.solution().coord( i );
173 const double exact_solution = 1.0 + y + Example::eps * y * ( 1 - y ) * std::exp( -advection.coord() );
174 max_err = std::max( max_err, std::abs( advection.solution()( i, 0 ) - exact_solution ) );
175 }
176 }
177
178 if ( max_err > 1.e-6 )
179 {
180 cout << "\033[1;31;48m * FAILED \033[0m\n";
181 cout.precision( 14 );
182 cout << 1. / ( ny - 1 ) << " " << dt << " " << max_err << "\n";
183 return 1;
184 }
185 else
186 {
187 cout << "\033[1;32;48m * PASSED \033[0m\n";
188 return 0;
189 }
190}
@ f
Definition: BVPBerman.cpp:15
@ U
Definition: BVPKarman.cpp:20
@ Ud
Definition: BVPKarman.cpp:20
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 matrix0(const DenseVector< double > &z, DenseMatrix< double > &m) const
Define the derivative terms by providing the mass matrix – identity in this case.
void residual_fn(const DenseVector< double > &z, DenseVector< double > &f) const
Define a nonlinear advection diffusion problem.
void get_jacobian_of_matrix1_mult_vector(const DenseVector< double > &state, const DenseVector< double > &vec, DenseMatrix< double > &h) const
Return the product of the Jacobian-of-the-matrix and a vector 'vec' when the equation has a given 'st...
void matrix1(const DenseVector< double > &z, DenseMatrix< double > &m) const
Define the unsteady terms by providing the mass matrix.
void get_jacobian_of_matrix0_mult_vector(const DenseVector< double > &state, const DenseVector< double > &vec, DenseMatrix< double > &h) const
Nlin_adv_equation()
The problem is 2nd order and real.
void residual_fn(const DenseVector< double > &z, DenseVector< double > &b) const
void residual_fn(const DenseVector< double > &z, DenseVector< double > &b) const
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.
_Xtype & coord(const unsigned &i)
General handle access to the coordinates.
void push_ptr(double *scalar, std::string desc="")
Definition: TrackerFile.cpp:27
double Re
Globally define the Reynolds number and wavenumber.
const double eps(2.0)
double source(const double &x, const double &y, const double &t)
Definition: IBVPLinear.cpp:26
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