CppNoddy  0.92
Loading...
Searching...
No Matches
IBVPLinear.cpp
Go to the documentation of this file.
1/// \file IBVPLinear.cpp
2/// \ingroup Tests
3/// \ingroup IBVP_double
4/// Solving the linear equation
5/// \f[ - u_x - u_t + u_{yy} = ( ( 1 - y^2 )( x + t ) - 2 ) e^{-xt}\,, \f]
6/// subject to \f$ u(x=0,y,t) = 1-y^2 \f$ \f$ u(x,t=0,y) = 1 - y^2 \f$
7/// and \f$ f(x, y = \pm 1,t ) = 0 \f$.
8/// The solution is computed over a range of \f$ t \f$ for \f$ (x,y) \in [0,10]\times [-1,1] \f$
9/// and the maximum deviation away from the exact solution \f$ u = (1-y^2) e^{-xt} \f$ is found.
10/// The test fails if this deviation is larger than a set tolerance \f$ \tau \f$.
11/// The example is solved using the PDE_double_IBVP for problems that are
12/// parabolic in 2 coordinates \f$ (x,t) \f$ with a BVP in \f$ y \f$.
13
14#include <IBVP_double_bundle.h>
15
16#include "../Utils_Fill.h"
17
18enum { U, Ud };
19
20namespace CppNoddy
21{
22 namespace Example
23 {
24
25 // A source term rigged up to give a nice exact solution
26 double source( const double& x, const double& y, const double& t )
27 {
28 return - 2 * std::exp( -x*t ) + ( 1 - y * y ) * ( x + t ) * std::exp( -x*t );
29 }
30
31 class diffusion_double : public Equation_3matrix<double>
32 {
33 public:
34 /// The problem is 2nd order and real
36
37 /// Define a nonlinear advection diffusion problem
39 {
40 // The system
41 f[ U ] = z[ Ud ];
42 f[ Ud ] = source( coord(2), coord(0), coord(1) );
43 }
44
45 /// Provide the exact Jacobian rather than using finite-differences
47 {
48 jac( 0, Ud ) = 1.0;
49 }
50
52 {
54 }
55
56 /// Define the unsteady terms by providing the mass matrix
58 {
59 // eqn 1 variable 0
60 m( 1, 0 ) = -1.0;
61 }
62
64 {
65 // eqn 1 variable 0
66 m( 1, 0 ) = -1.0;
67 }
68
69
71 {
72 // constant matrix
73 }
75 {
76 // constant matrix
77 }
79 {
80 // constant matrix
81 }
82
83 };
84
85 // BOUNDARY CONDITIONS
86 class dd_BC : public Residual_with_coords<double>
87 {
88 public:
89 // 1 constraint, 2nd order system, 2 coordinates (x & t)
90 dd_BC() : Residual_with_coords<double> ( 1, 2, 2 ) {}
91
93 {
94 b[ 0 ] = z[ U ];
95 }
96 };
97
98 } // end Test namespace
99} // end CppNoddy namespace
100
101using namespace CppNoddy;
102using namespace std;
103
104int main()
105{
106 cout << "\n";
107 cout << "=== double_IBVP: linear diffusive problem ===========\n";
108 cout << "\n";
109
110 // instantiate the problem
112 Example::dd_BC BC_bottom;
113 Example::dd_BC BC_top;
114
115 // domain definition
116 double top = 1.0;
117 double bottom = -1.0;
118 double left = 0.0;
119 double right = 10.0;
120 // number of (spatial) nodal points
121 unsigned ny = 301;
122 unsigned nx = 301;
123 // time and time step
124 double t_end = 1.0;
125 double dt = 0.01;
126
127 // construct our IBVP
128 PDE_double_IBVP<double> diffusion( &problem,
129 Utility::uniform_node_vector( left, right, nx ),
130 Utility::uniform_node_vector( bottom, top, ny ),
131 &BC_bottom, &BC_top );
132
133 // initial conditions
134 for ( unsigned i = 0; i < nx; ++i )
135 {
136 for ( unsigned j = 0; j < ny; ++j )
137 {
138 double y = diffusion.solution().coord( i, j ).second;
139 diffusion.solution()( i, j, U ) = ( 1.0 - y * y );
140 diffusion.solution()( i, j, Ud ) = - 2 * y ;
141 }
142 }
143
144 double max_error( 0.0 );
145 do
146 {
147 diffusion.update_previous_solution();
148 diffusion.step2( dt );
149 for ( unsigned i = 0; i < nx; ++i )
150 {
151 for ( unsigned j = 0; j < ny; ++j )
152 {
153 double x = diffusion.solution().coord( i, j ).first;
154 double y = diffusion.solution().coord( i, j ).second;
155 double exact_u = ( 1 - y * y ) * exp( - x * diffusion.t() );
156 max_error = max( max_error, abs( exact_u - diffusion.solution()( i, j, U ) ) );
157 }
158 }
159 }
160 while ( diffusion.t() < t_end );
161
162 const double tol( 1.e-4 );
163 // check the BL transpiration vs the known solution
164 if ( max_error > tol )
165 {
166 cout << "\033[1;31;48m * FAILED \033[0m\n";
167 cout << " Difference = " << max_error << "\n";
168 return 1;
169 }
170 else
171 {
172 cout << "\033[1;32;48m * PASSED \033[0m\n";
173 return 0;
174 }
175
176}
@ f
Definition: BVPBerman.cpp:15
@ U
Definition: BVPKarman.cpp:20
@ Ud
Definition: BVPKarman.cpp:20
@ U
Definition: IBVPLinear.cpp:18
@ Ud
Definition: IBVPLinear.cpp:18
int main()
Definition: IBVPLinear.cpp:104
A shorter bundled include file for double 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
Definition: IBVPLinear.cpp:92
void get_jacobian_of_matrix1_mult_vector(const DenseVector< double > &state, const DenseVector< double > &vec, DenseMatrix< double > &h) const
Definition: IBVPLinear.cpp:74
void get_jacobian_of_matrix2_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...
Definition: IBVPLinear.cpp:78
void jacobian(const DenseVector< double > &z, DenseMatrix< double > &jac) const
Provide the exact Jacobian rather than using finite-differences.
Definition: IBVPLinear.cpp:46
void get_jacobian_of_matrix0_mult_vector(const DenseVector< double > &state, const DenseVector< double > &vec, DenseMatrix< double > &h) const
Definition: IBVPLinear.cpp:70
void residual_fn(const DenseVector< double > &z, DenseVector< double > &f) const
Define a nonlinear advection diffusion problem.
Definition: IBVPLinear.cpp:38
void matrix1(const DenseVector< double > &z, DenseMatrix< double > &m) const
Define the unsteady terms by providing the mass matrix.
Definition: IBVPLinear.cpp:57
void matrix2(const DenseVector< double > &z, DenseMatrix< double > &m) const
Define the matrix for the current state vector.
Definition: IBVPLinear.cpp:63
diffusion_double()
The problem is 2nd order and real.
Definition: IBVPLinear.cpp:35
void matrix0(const DenseVector< double > &z, DenseMatrix< double > &m) const
Definition: IBVPLinear.cpp:51
A templated object for real/complex vector system of unsteady equations.
void update_previous_solution()
Copy the current solution to the previous solution.
double & t()
Return a reference to the current value of the 'timelike' coordinate.
void step2(const double &dt)
A Crank-Nicolson 'time' stepper.
TwoD_Node_Mesh< _Type > & solution()
A base class to be inherited by objects that define residuals.
_Xtype & coord(const unsigned &i)
General handle access to the coordinates.
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...
void fill_identity(CppNoddy::Sequential_Matrix_base< _Type > &A)
Fill diagonal with unit values.
Definition: Utils_Fill.h:22

© 2012

R.E. Hewitt