CppNoddy  0.92
Loading...
Searching...
No Matches
HYPAcousticReflection.cpp
Go to the documentation of this file.
1/// \file HYPAcousticReflection.cpp
2/// \ingroup Tests
3/// \ingroup HYP_1D
4/// Solve the constant coefficient linear sound wave problem
5/// \f[ p_t + K u_x = 0 \f]
6/// \f[ \rho u_t + p_x = 0 \f]
7/// for a right-propagating square pulse in a medium
8/// with constant bulk modulus \f$K=1\f$ and density \f$\rho = 1\f$
9/// and reflecting boundary conditions at both sides.
10
11#include <OneD_HYP_bundle.h>
12
13enum { p, u };
14
15namespace CppNoddy
16{
17 namespace Example
18 {
19 /// bulk modulus
20 double K( 2.0 );
21 /// higher density
22 double rho( 2.0 );
23
24 /// Define the system
26 {
27
28 public:
29
30 /// One dimemsional constant coefft acoustic problem
32 {}
33
34 /// Define the vector flux
35 void flux_fn( const double&x, const DenseVector<double> &q, DenseVector<double> &f ) const
36 {
37 f[ p ] = K * q[ u ];
38 f[ u ] = q[ p ] / rho;
39 }
40
41 /// Bound the shock speed
42 double max_charac_speed( const DenseVector<double> &q ) const
43 {
44 // sound speeds
45 double c = sqrt( K / rho );
46 // maximum shock speed
47 return c;
48 }
49
50 /// edge conditions
51 std::vector<bool> edge_values( const int face_index, const double& x, DenseVector<double>& q, const double &t ) const
52 {
53 // reflection condition
54 std::vector<bool> inflow( q.size(), false );
55 q[ u ] = 0.0;
56 inflow[ u ] = true;
57 return inflow;
58 }
59
60 };
61
62 /// Set the initial state of the system
63 void Q_init( const double &x, DenseVector<double> &q )
64 {
65 if ( ( x < 0.5 ) && ( x > -0.5 ) )
66 {
67 q[ p ] = std::exp( -20 * x * x );
68 q[ u ] = q[ p ] / sqrt( K * rho );
69 }
70 else
71 {
72 q[ p ] = q[ u ] = 0.0;
73 }
74 }
75 } //end Example namespace
76
77} //end CppNoddy namespace
78
79
80using namespace CppNoddy;
81using namespace std;
82
83int main()
84{
85 cout << "\n";
86 cout << "=== Hyperbolic: 1D acoustic wave reflection problem =\n";
87 cout << "\n";
88
89 // define the domain/mesh
90 const double left = -3.0;
91 const double right = 3.0;
92 const unsigned N = 800;
93 DenseVector<double> faces_x = Utility::uniform_node_vector( left, right, N );
94
95 // time
96 double t = 0;
97 double t_end = 6;
98
99 // hyperbolic problem
100 Example::Acoustic_1d_ref conservative_problem;
101 OneD_TVDLF_Mesh Acoustic_mesh( faces_x, &conservative_problem, Example::Q_init );
102 Acoustic_mesh.set_limiter( 1 );
103
104 // output
105 double I1 = Acoustic_mesh.integrate()[0];
106 int loop_counter( 0 );
107 int file_counter( 1 );
108
109 std::string dirname("./DATA");
110 mkdir( dirname.c_str(), S_IRWXU );
111 std::string filename_stub;
112 filename_stub = "./DATA/HYP_acoustic_ref";
113 TrackerFile my_file( 5 );
114 OneD_Node_Mesh<double> soln = Acoustic_mesh.get_soln();
115 my_file.push_ptr( &soln, "mesh" );
116
117 do
118 {
119 if ( loop_counter % 10 == 0 )
120 {
121 my_file.set_filename( filename_stub + Utility::stringify( file_counter ) + ".dat" );
122 soln = Acoustic_mesh.get_soln();
123 my_file.update();
124 file_counter += 1;
125 }
126 // take a step
127 t += Acoustic_mesh.update( 0.49, t_end - t );
128 ++loop_counter;
129 }
130 while ( ( t < t_end ) && ( loop_counter < 1100 ) );
131
132 double I2 = Acoustic_mesh.integrate()[0];
133 // compute the pressure difference after the pressure pulse
134 // has returned to its original position
135 soln = Acoustic_mesh.get_soln();
136 my_file.update();
137 double diff = 0.0;
138 for ( std::size_t i = 0; i < soln.get_nnodes(); ++i )
139 {
140 // get the initial condition
141 DenseVector<double> q( 2, 0.0 );
142 Example::Q_init( soln.coord( i ), q );
143 // difference between initial and final state
144 diff = std::max( diff, q[0] - soln( i, 0 ) );
145 }
146 // check the maximum difference in the reflected pulse & the
147 // integral of the pressure over the mesh
148 if ( ( diff > 1.e-2 ) || ( std::abs( I1 - I2 ) > 1.e-8 ) )
149 {
150 cout << "\033[1;31;48m * FAILED \033[0m\n";
151 cout << "difference in the reflected wave = " << diff << "\n";
152 cout << "difference in the integral = " << std::abs( I1 - I2 ) << "\n";
153 return 1;
154 }
155 else
156 {
157 cout << "\033[1;32;48m * PASSED \033[0m\n";
158 return 0;
159 }
160
161} // 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
Acoustic_1d_ref()
One dimemsional constant coefft acoustic problem.
std::vector< bool > edge_values(const int face_index, const double &x, DenseVector< double > &q, const double &t) const
edge conditions
double max_charac_speed(const DenseVector< double > &q) const
Bound the shock speed.
void flux_fn(const double &x, const DenseVector< double > &q, DenseVector< double > &f) const
Define the vector flux.
A class to represent a one dimensional hyperbolic system of equations.
A one dimensional mesh utility object.
const _Xtype & coord(const std::size_t &node) const
Access a nodal position.
std::size_t get_nnodes() const
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 set_filename(std::string filename)
Definition: TrackerFile.cpp:70
void Q_init(const double &x, DenseVector< double > &q)
Set the initial state of the system.
double K(4.0)
bulk modulus
std::string stringify(const int &val)
Return an integer value as a string - useful for file naming.
Definition: Utility.cpp:193
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