22 std::cout <<
"DEBUG: Starting construction of a OneD_TVDLF_Mesh object. \n";
24 unsigned N = X.
size();
27 problem =
" The OneD_TVDLF_Mesh object is trying to construct itself \n";
28 problem +=
" with just one element! \n";
32 std::cout <<
"\nDEBUG: configuration of the black mesh \n";
37 ORDER_OF_SYSTEM = ptr -> get_order();
43 for(std::size_t i = 1; i <= N - 3; ++i) {
48 BLACK_ELTS.push_back(
OneD_TVDLF_Elt(X[N-2], X[N-1], ptr,
true, 1));
51 std::cout <<
"\nDEBUG: configuration of the red mesh \n";
56 RED_ELTS.push_back(
OneD_TVDLF_Elt(X[0], (X[1] + X[0]) / 2, ptr,
true, -1));
58 for(std::size_t i = 1; i <= N - 2; ++i) {
60 RED_ELTS.push_back(
OneD_TVDLF_Elt((X[i-1] + X[i]) / 2, (X[i] + X[i+1]) / 2, ptr));
63 RED_ELTS.push_back(
OneD_TVDLF_Elt((X[N-2] + X[N-1]) / 2, X[N-1], ptr,
true, 1));
66 std::cout <<
"\nDEBUG: linking the two meshes \n";
70 elt_iter er = RED_ELTS.begin();
71 elt_iter eb = BLACK_ELTS.begin();
84 while(er != RED_ELTS.end()) {
85 if(er -> get_external_flag()) {
87 if(er -> get_external_face_i() < 0) {
89 er -> add_contribution(&(*eb), s_left, 1);
93 er -> add_contribution(&(*eb), s_right, -1);
98 er -> add_contribution(&(*eb), s_right, -1);
100 er -> add_contribution(&(*eb), s_left, 1);
106 eb = BLACK_ELTS.begin();
107 er = RED_ELTS.begin();
108 while(eb != BLACK_ELTS.end()) {
109 if(eb -> get_external_flag()) {
111 if(eb -> get_external_face_i() < 0) {
113 eb -> add_contribution(&(*er), s_whole, 0);
115 double s = er -> get_s(eb -> get_x(1.0));
118 eb -> add_contribution(&(*er), s_gen, 1);
122 double s = er -> get_s(eb -> get_x(-1.0));
125 eb -> add_contribution(&(*er), s_gen, -1);
127 eb -> add_contribution(&(*er), s_whole, 0);
132 double s = er -> get_s(eb -> get_x(-1.0));
135 eb -> add_contribution(&(*er), s_gen, -1);
137 s = er -> get_s(eb -> get_x(1.0));
140 eb -> add_contribution(&(*er), s_gen, 1);
146 std::cout <<
"DEBUG: Setting the initial state of the meesh. \n";
149 eb = BLACK_ELTS.begin();
150 while(eb != BLACK_ELTS.end()) {
152 p_Q_INIT(eb -> get_x(0.0), Q);
176 calc_slopes(&BLACK_ELTS);
179 std::cout <<
"DEBUG: Finished construction of a OneD_TVDLF_Mesh object. \n";
188 celt_iter e = BLACK_ELTS.begin();
189 while(e != BLACK_ELTS.end()) {
198 celt_iter e = BLACK_ELTS.begin();
199 while(e != BLACK_ELTS.end()) {
215 return first_dt + second_dt;
220 update(CFL, std::abs(t_end - MESH_TIME));
221 }
while(MESH_TIME < t_end);
229 celt_iter e = BLACK_ELTS.begin();
231 while(e != BLACK_ELTS.end()) {
232 sum += e -> get_Q(0.0) * e -> get_dx();
239 vector_of_elts* elts(get_elts_from_colour(mesh_colour));
241 if(location ==
"centre") {
244 for(std::size_t i = 0; i < X.
size(); ++i) {
247 }
else if(location ==
"face_average") {
250 std::size_t N = X.
size() - 1;
252 for(std::size_t i = 1; i < N; ++i) {
253 soln.
set_nodes_vars(i, ((*elts)[i-1].get_Q(1.0) + (*elts)[i].get_Q(-1.0)) / 2);
258 problem =
" In OneD_TVDLF_Mesh::get_soln you have passed an unrecognised ";
259 problem +=
" location for data output. Use 'centre' or 'face_average'. \n";
266 void OneD_TVDLF_Mesh::calc_slopes(vector_of_elts* elt_vector) {
267 set_boundary_Q(elt_vector);
268 elt_iter e = elt_vector -> begin();
275 while(e != elt_vector -> end()) {
277 right = right_diff(e);
278 slope = minmod(left, right);
279 e -> set_slope(slope);
285 while(e != elt_vector -> end()) {
286 right = right_diff(e);
288 minmod(right, left * 2.),
289 minmod(right * 2., left)
292 e -> set_slope(slope);
298 problem =
" The OneD_TVDLF_Mesh object has an unrecognised 'limiter' identifier. \n";
299 throw ExceptionRuntime(problem);
303 std::vector<OneD_TVDLF_Elt>* OneD_TVDLF_Mesh::get_elts_from_colour(std::string mesh_colour) {
304 vector_of_elts* elts;
305 if(mesh_colour ==
"black") {
307 }
else if(mesh_colour ==
"red") {
311 problem =
" The TwoD_TVDLF_Mesh object has been passed an unrecognised mesh identifier. \n";
312 problem +=
" valid options are 'black' or 'red'.\n";
313 throw ExceptionRuntime(problem);
318 void OneD_TVDLF_Mesh::set_boundary_Q(vector_of_elts* elts) {
320 elt_iter e(elts -> begin());
321 while(e != elts -> end()) {
323 if(e -> get_external_flag()) {
327 if(e -> get_external_face_i() < 0) {
337 DenseVector<double> Qe(e -> get_Q(s));
339 std::vector<bool> inflow = e -> system_ptr -> edge_values(face, e -> get_x(s), Qe, MESH_TIME);
340 DenseVector<double> Qm(e -> get_Q(0.0));
342 for(std::size_t i = 0; i < ORDER_OF_SYSTEM; ++i) {
344 if(inflow[ i ] ==
true) {
354 DenseVector<double> OneD_TVDLF_Mesh::left_diff(elt_iter e) {
355 DenseVector<double> diff(ORDER_OF_SYSTEM, 0.0);
356 if(e -> get_external_face_i() < 0) {
358 diff = right_diff(e);
362 DenseVector<double> Qe(e -> get_Q(-1.0));
364 std::vector<bool> inflow = e -> system_ptr -> edge_values(-1, e -> get_x(-1.0), Qe, MESH_TIME);
366 for(std::size_t i = 0; i < ORDER_OF_SYSTEM; ++i) {
368 if(inflow[ i ] ==
true) {
376 diff = (e -> get_Q(0.0) - j -> get_Q(0.0))
377 / (e -> get_x(0.0) - j -> get_x(0.0));
382 DenseVector<double> OneD_TVDLF_Mesh::right_diff(elt_iter e) {
383 DenseVector<double> diff(ORDER_OF_SYSTEM, 0.0);
385 if(e -> get_external_face_i() > 0) {
391 DenseVector<double> Qe(e -> get_Q(1.0));
393 std::vector<bool> inflow = e -> system_ptr -> edge_values(1, e -> get_x(1.0), Qe, MESH_TIME);
394 DenseVector<double> Qm(e -> get_Q(0.0));
396 for(std::size_t i = 0; i < ORDER_OF_SYSTEM; ++i) {
398 if(inflow[ i ] ==
true) {
406 diff = (j -> get_Q(0.0) - e -> get_Q(0.0))
407 / (j -> get_x(0.0) - e -> get_x(0.0));
412 int OneD_TVDLF_Mesh::sgn(
double a) {
422 double OneD_TVDLF_Mesh::minmod(
double a,
double b) {
423 return 0.5 * (sgn(a) + sgn(b))
424 * std::min(std::abs(a), std::abs(b));
427 double OneD_TVDLF_Mesh::maxmod(
double a,
double b) {
428 return 0.5 * (sgn(a) + sgn(b))
429 * std::max(std::abs(a), std::abs(b));
432 DenseVector<double> OneD_TVDLF_Mesh::minmod(DenseVector<double> A, DenseVector<double> B) {
433 DenseVector<double> MM;
434 for(std::size_t i = 0; i <
A.size(); ++i) {
435 MM.push_back(0.5 * (sgn(A[i]) + sgn(B[i]))
436 * std::min(std::abs(A[i]), std::abs(B[i])));
441 DenseVector<double> OneD_TVDLF_Mesh::maxmod(DenseVector<double> A, DenseVector<double> B) {
442 DenseVector<double> MM;
443 for(std::size_t i = 0; i <
A.size(); ++i) {
444 MM.push_back(0.5 * (sgn(A[i]) + sgn(B[i]))
445 * std::max(std::abs(A[i]), std::abs(B[i])));
A specification for a one dimensional mesh object.
Specification of a one dimensional linear element for use in a TVD Lax-Friedrichs scheme.
Specification of an object that represents a one dimensional mesh for TVD LX methods.
An DenseVector class – a dense vector object.
void push_back(const _Type &fill)
A pass-thru definition of push_back.
std::size_t size() const
A pass-thru definition to get the size of the vector.
A generic runtime exception.
A class to represent a one dimensional hyperbolic system of equations.
A one dimensional mesh utility object.
void set_nodes_vars(const std::size_t node, const DenseVector< _Type > &u)
Set the variables stored at A SPECIFIED node.
void update_to(const double &CFL, const double &t_end)
Update all the elements in this mesh to a USER SPECIFIED time step.
const double & get_time() const
Get a const reference to the time value for the current mesh.
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_to_black(const double &CFL, const double &max_dt)
double update_to_red(const double &CFL, const double &max_dt)
~OneD_TVDLF_Mesh()
Empty desctructor.
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.
OneD_TVDLF_Mesh(const DenseVector< double > &X, OneD_Hyperbolic_System *ptr, fn_ptr init_ptr)
Constructor for the Finite Volume Mesh using linear elements.
DenseVector< double > get_mid_node_vector() const
Get the nodal positions in the middle of each element.
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.
DenseVector< double > get_face_pos_vector() const
Get the positions of the element faces.
double A(1.0)
initial hump amplitude
double s
relative rotation rate
A collection of OO numerical routines aimed at simple (typical) applied problems in continuum mechani...