CppNoddy  0.92
Loading...
Searching...
No Matches
HYPNonlinearAdvection.cpp
Go to the documentation of this file.
1/// \file HYPNonlinearAdvection.cpp
2/// \ingroup Tests
3/// \ingroup HYP_1D
4/// Solving the 1D `nonlinear advection equation'
5/// \f[ Q_t + \left ( \frac{Q^2}{2} \right )_x = 0 \quad \mbox{where} \quad Q=Q(x,t) \f] using a TVD Lax-Friedrichs scheme
6/// for \f$ x\in[0,1]\f$. The initial condition is taken to be
7/// \f[ Q(x,0) = \sin( 2\pi x ) \f] The test is simply conservation of \f$ Q \f$ in this case.
8
9#include <OneD_HYP_bundle.h>
10
11namespace CppNoddy
12{
13 namespace Example
14 {
15
16 /// Define the system
18 {
19
20 public:
21
22 /// One dimemsional inviscid Burgers problem
24 {}
25
26 /// Define the vector flux
27 void flux_fn( const double& x, const DenseVector<double> &q, DenseVector<double> &f ) const
28 {
29 f[ 0 ] = q[ 0 ] * q[ 0 ] / 2;
30 }
31
32 /// Bound the shock speed
33 double max_charac_speed( const DenseVector<double> &q ) const
34 {
35 // maximum shock speed
36 return std::abs( q[ 0 ] );
37 }
38
39 ///// edge conditions
40 std::vector<bool> edge_values( const int face_index, const double& x, DenseVector<double>& q, const double &t ) const
41 {
42 std::vector<bool> inflow( q.size(), false );
43 // x doesn't matter since the conditions are fixed
44 if ( face_index == -1 )
45 {
46 q[ 0 ] = 0.0;
47 inflow[ 0 ] = true;
48 }
49 if ( face_index == 1 )
50 {
51 q[ 0 ] = 0.0;
52 inflow[ 0 ] = true;
53 }
54 return inflow;
55 }
56
57 };
58
59 /// Set the initial state of the system
60 void Q_init( const double &x, DenseVector<double> &q )
61 {
62 q[ 0 ] = std::sin( 2 * M_PI * x );
63 }
64 } //end Example namespace
65
66} //end CppNoddy namespace
67
68
69using namespace CppNoddy;
70using namespace std;
71
72int main()
73{
74 cout << "\n";
75 cout << "=== Hyperbolic: 1D nonlinear advection equation ====\n";
76 cout << "\n";
77
78 // define the domain/mesh
79 const double left = 0.0;
80 const double right = 1.0;
81 const unsigned N = 141;
82 DenseVector<double> faces_x = Utility::uniform_node_vector( left, right, N );
83
84 double t = 0.0;
85
86 Example::NlinAdv conservative_problem;
87 OneD_TVDLF_Mesh NlinAdv_mesh( faces_x, &conservative_problem, Example::Q_init );
88 NlinAdv_mesh.set_limiter( 0 );
89
90 double I1 = NlinAdv_mesh.integrate()[0];
91 int loop_counter( 5 );
92
93 std::string dirname("./DATA");
94 mkdir( dirname.c_str(), S_IRWXU );
95 TrackerFile my_file( "./DATA/HYP_NlinAdv.dat" );
96 // first column of the output will always be the time
97 my_file.push_ptr( &t, "time" );
98 OneD_Node_Mesh<double> soln = NlinAdv_mesh.get_soln();
99 my_file.push_ptr( &soln, "mesh" );
100
101 double asym( 0.0 );
102 do
103 {
104 double dt = NlinAdv_mesh.update( 0.475 );
105 t += dt;
106 soln = NlinAdv_mesh.get_soln();
107
108 if ( loop_counter % 10 == 0 )
109 {
110 soln = NlinAdv_mesh.get_soln();
111 my_file.update();
112 my_file.newline();
113 }
114 ++loop_counter;
115 asym = std::max( asym, std::abs( soln.get_interpolated_vars( 0.75 )[0] + soln.get_interpolated_vars( 0.25 )[0] ) );
116 }
117 while ( ( t < 0.4 ) && ( loop_counter < 1000 ) );
118
119 double I2 = NlinAdv_mesh.integrate()[0];
120 soln = NlinAdv_mesh.get_soln();
121 my_file.update();
122 my_file.newline();
123 // problem should be antisymmetric about x = 1/2
124 if ( ( asym > 1.e-10 ) || ( std::abs( I1 - I2 ) > 1.e-8 ) || ( loop_counter >= 1000 ) )
125 {
126 cout << "\033[1;31;48m * FAILED \033[0m\n";
127 cout << "asymmetry = " << asym << "\n";
128 cout << "integral difference = " << I1 - I2 << "\n";
129 cout << "loop counter = " << loop_counter << "\n";
130 return 1;
131 }
132 else
133 {
134 cout << "\033[1;32;48m * PASSED \033[0m\n";
135 return 0;
136 }
137
138} // end of main()
@ f
Definition: BVPBerman.cpp:15
int main()
A shorter bundled include file for hyperbolic problems.
An DenseVector class – a dense vector object.
Definition: DenseVector.h:34
std::size_t size() const
A pass-thru definition to get the size of the vector.
Definition: DenseVector.h:330
void flux_fn(const double &x, const DenseVector< double > &q, DenseVector< double > &f) const
Define the vector flux.
double max_charac_speed(const DenseVector< double > &q) const
Bound the shock speed.
NlinAdv()
One dimemsional inviscid Burgers problem.
std::vector< bool > edge_values(const int face_index, const double &x, DenseVector< double > &q, const double &t) const
Define the edge boundary conditions.
A class to represent a one dimensional hyperbolic system of equations.
A one dimensional mesh utility object.
DenseVector< _Type > get_interpolated_vars(const _Xtype &pos) const
Get the variable data at an interpolated position using a first order scheme.
OneD_Node_Mesh< double > get_soln(std::string location="centre", std::string colour="black")
Get a OneD_Mesh<double> object containing the one dimensional data in the usual format.
double update(const double &CFL, const double &max_dt=std::numeric_limits< long double >::max())
Update all the elements in this mesh to a new time step.
void set_limiter(unsigned id)
Set the limiter type to be applied in the slope values.
DenseVector< double > integrate() const
Integrate the concentration values across the entire mesh.
void push_ptr(double *scalar, std::string desc="")
Definition: TrackerFile.cpp:27
void Q_init(const double &x, DenseVector< double > &q)
Set the initial state of the system.
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