//
// ---------------------------------------------------------------------
-
+// test Runge-Kutta methods in TimeStepping with a) a polynomial with expected
+// error 0 and b) convergence order for y=exp(t^2)
#include <deal.II/base/time_stepping.h>
#include <deal.II/lac/vector.h>
#include "../tests.h"
-// test Runge-Kutta methods
Vector<double>
f1(double const t, Vector<double> const &y)
{
return values;
}
+
+Vector<double>
+my_rhs_function(double const t, Vector<double> const &y)
+{
+ Vector<double> values(y);
+ for (unsigned int i = 0; i < values.size(); ++i)
+ values[i] = y[i] * 2.0 * t;
+
+ return values;
+}
+
Vector<double>
id_minus_tau_J_inv1(double const t, double const tau, Vector<double> const &y)
{
return t * t * t * t * t;
}
+double
+my_exact_solution(double const t)
+{
+ return std::exp(t * t);
+}
+
void
test(TimeStepping::RungeKutta<Vector<double>> & solver,
std::function<Vector<double>(double const, Vector<double> const &)> f,
deallog << error_norm << std::endl;
}
+
+void
+test_convergence(
+ TimeStepping::RungeKutta<Vector<double>> & solver,
+ std::function<Vector<double>(double const, Vector<double> const &)> f,
+ std::function<Vector<double>(double const,
+ double const,
+ Vector<double> const &)> id_minus_tau_J_inv,
+ std::function<double(double const)> my)
+{
+ std::vector<double> errors;
+ double initial_time = 0.0, final_time = 1.0;
+ unsigned int size = 1;
+ Vector<double> solution(size);
+ Vector<double> exact_solution(size);
+ for (unsigned int i = 0; i < size; ++i)
+ {
+ exact_solution[i] = my(final_time);
+ }
+
+ deallog << "convergence rate" << std::endl;
+ for (unsigned int cycle = 0; cycle < 10; ++cycle)
+ {
+ unsigned int n_time_steps = std::pow(2., static_cast<double>(cycle));
+ double time_step =
+ (final_time - initial_time) / static_cast<double>(n_time_steps);
+ double time = initial_time;
+ for (unsigned int i = 0; i < size; ++i)
+ solution[i] = my(initial_time);
+
+ for (unsigned int i = 0; i < n_time_steps; ++i)
+ time = solver.evolve_one_time_step(
+ f, id_minus_tau_J_inv, time, time_step, solution);
+
+ Vector<double> error(exact_solution);
+ error.sadd(1.0, -1.0, solution);
+ double error_norm = error.l2_norm();
+ errors.push_back(error_norm);
+ if (cycle > 0)
+ deallog << std::log(std::fabs(errors[cycle - 1] / errors[cycle])) /
+ std::log(2.)
+ << std::endl;
+ }
+}
+
int
main()
{
initlog();
-
- deallog << "Forward Euler" << std::endl;
- TimeStepping::ExplicitRungeKutta<Vector<double>> fe(
- TimeStepping::FORWARD_EULER);
- test(fe, f1, id_minus_tau_J_inv1, my1);
-
- deallog << "Runge-Kutta third order" << std::endl;
- TimeStepping::ExplicitRungeKutta<Vector<double>> rk3(
- TimeStepping::RK_THIRD_ORDER);
- test(rk3, f3, id_minus_tau_J_inv3, my3);
-
- deallog << "Runge-Kutta fourth order" << std::endl;
- TimeStepping::ExplicitRungeKutta<Vector<double>> rk4(
- TimeStepping::RK_CLASSIC_FOURTH_ORDER);
- test(rk4, f4, id_minus_tau_J_inv4, my4);
-
- deallog << "Backward Euler" << std::endl;
- TimeStepping::ImplicitRungeKutta<Vector<double>> be(
- TimeStepping::BACKWARD_EULER);
- test(be, f1, id_minus_tau_J_inv1, my1);
-
- deallog << "Implicit midpoint" << std::endl;
- TimeStepping::ImplicitRungeKutta<Vector<double>> im(
- TimeStepping::IMPLICIT_MIDPOINT);
- test(im, f2, id_minus_tau_J_inv2, my2);
-
- deallog << "Crank-Nicolson" << std::endl;
- TimeStepping::ImplicitRungeKutta<Vector<double>> cn(
- TimeStepping::CRANK_NICOLSON);
- test(cn, f2, id_minus_tau_J_inv2, my2);
-
- deallog << "SDIRK" << std::endl;
- TimeStepping::ImplicitRungeKutta<Vector<double>> sdirk(
- TimeStepping::SDIRK_TWO_STAGES);
- test(sdirk, f2, id_minus_tau_J_inv2, my2);
-
- deallog << "Heun-Euler" << std::endl;
- TimeStepping::EmbeddedExplicitRungeKutta<Vector<double>> he(
- TimeStepping::HEUN_EULER);
- test2(he, f2, id_minus_tau_J_inv2, my2);
-
- deallog << "Bogacki-Shampine" << std::endl;
- TimeStepping::EmbeddedExplicitRungeKutta<Vector<double>> bs(
- TimeStepping::BOGACKI_SHAMPINE);
- test2(bs, f3, id_minus_tau_J_inv3, my3);
- bs.free_memory();
-
- deallog << "DOPRI" << std::endl;
- TimeStepping::EmbeddedExplicitRungeKutta<Vector<double>> dopri(
- TimeStepping::DOPRI);
- test2(dopri, f5, id_minus_tau_J_inv5, my5);
- dopri.free_memory();
-
- deallog << "Fehlberg" << std::endl;
- TimeStepping::EmbeddedExplicitRungeKutta<Vector<double>> fehlberg(
- TimeStepping::FEHLBERG);
- test2(fehlberg, f5, id_minus_tau_J_inv5, my5);
-
- deallog << "Cash-Karp" << std::endl;
- TimeStepping::EmbeddedExplicitRungeKutta<Vector<double>> ck(
- TimeStepping::CASH_KARP);
- test2(ck, f5, id_minus_tau_J_inv5, my5);
+ {
+ deallog << "Forward Euler" << std::endl;
+ TimeStepping::ExplicitRungeKutta<Vector<double>> fe(
+ TimeStepping::FORWARD_EULER);
+ test(fe, f1, id_minus_tau_J_inv1, my1);
+
+ deallog << "Runge-Kutta third order" << std::endl;
+ TimeStepping::ExplicitRungeKutta<Vector<double>> rk3(
+ TimeStepping::RK_THIRD_ORDER);
+ test(rk3, f3, id_minus_tau_J_inv3, my3);
+
+ deallog << "Strong Stability Preserving Runge-Kutta third order"
+ << std::endl;
+ TimeStepping::ExplicitRungeKutta<Vector<double>> ssp_rk3(
+ TimeStepping::SSP_THIRD_ORDER);
+ test(ssp_rk3, f3, id_minus_tau_J_inv3, my3);
+
+ deallog << "Runge-Kutta fourth order" << std::endl;
+ TimeStepping::ExplicitRungeKutta<Vector<double>> rk4(
+ TimeStepping::RK_CLASSIC_FOURTH_ORDER);
+ test(rk4, f4, id_minus_tau_J_inv4, my4);
+
+ deallog << "Backward Euler" << std::endl;
+ TimeStepping::ImplicitRungeKutta<Vector<double>> be(
+ TimeStepping::BACKWARD_EULER);
+ test(be, f1, id_minus_tau_J_inv1, my1);
+
+ deallog << "Implicit midpoint" << std::endl;
+ TimeStepping::ImplicitRungeKutta<Vector<double>> im(
+ TimeStepping::IMPLICIT_MIDPOINT);
+ test(im, f2, id_minus_tau_J_inv2, my2);
+
+ deallog << "Crank-Nicolson" << std::endl;
+ TimeStepping::ImplicitRungeKutta<Vector<double>> cn(
+ TimeStepping::CRANK_NICOLSON);
+ test(cn, f2, id_minus_tau_J_inv2, my2);
+
+ deallog << "SDIRK" << std::endl;
+ TimeStepping::ImplicitRungeKutta<Vector<double>> sdirk(
+ TimeStepping::SDIRK_TWO_STAGES);
+ test(sdirk, f2, id_minus_tau_J_inv2, my2);
+
+ deallog << "Heun-Euler" << std::endl;
+ TimeStepping::EmbeddedExplicitRungeKutta<Vector<double>> he(
+ TimeStepping::HEUN_EULER);
+ test2(he, f2, id_minus_tau_J_inv2, my2);
+
+ deallog << "Bogacki-Shampine" << std::endl;
+ TimeStepping::EmbeddedExplicitRungeKutta<Vector<double>> bs(
+ TimeStepping::BOGACKI_SHAMPINE);
+ test2(bs, f3, id_minus_tau_J_inv3, my3);
+ bs.free_memory();
+
+ deallog << "DOPRI" << std::endl;
+ TimeStepping::EmbeddedExplicitRungeKutta<Vector<double>> dopri(
+ TimeStepping::DOPRI);
+ test2(dopri, f5, id_minus_tau_J_inv5, my5);
+ dopri.free_memory();
+
+ deallog << "Fehlberg" << std::endl;
+ TimeStepping::EmbeddedExplicitRungeKutta<Vector<double>> fehlberg(
+ TimeStepping::FEHLBERG);
+ test2(fehlberg, f5, id_minus_tau_J_inv5, my5);
+
+ deallog << "Cash-Karp" << std::endl;
+ TimeStepping::EmbeddedExplicitRungeKutta<Vector<double>> ck(
+ TimeStepping::CASH_KARP);
+ test2(ck, f5, id_minus_tau_J_inv5, my5);
+ }
+
+ {
+ deallog << "Forward Euler first order" << std::endl;
+ TimeStepping::ExplicitRungeKutta<Vector<double>> rk1(
+ TimeStepping::FORWARD_EULER);
+ test_convergence(rk1,
+ my_rhs_function,
+ id_minus_tau_J_inv1,
+ my_exact_solution);
+
+ deallog << "Runge-Kutta third order" << std::endl;
+ TimeStepping::ExplicitRungeKutta<Vector<double>> rk3(
+ TimeStepping::RK_THIRD_ORDER);
+ test_convergence(rk3,
+ my_rhs_function,
+ id_minus_tau_J_inv3,
+ my_exact_solution);
+
+ deallog << "Strong Stability Preserving Runge-Kutta third order"
+ << std::endl;
+ TimeStepping::ExplicitRungeKutta<Vector<double>> ssp_rk3(
+ TimeStepping::SSP_THIRD_ORDER);
+ test_convergence(ssp_rk3,
+ my_rhs_function,
+ id_minus_tau_J_inv3,
+ my_exact_solution);
+
+ deallog << "Runge-Kutta fourth order" << std::endl;
+ TimeStepping::ExplicitRungeKutta<Vector<double>> rk4(
+ TimeStepping::RK_CLASSIC_FOURTH_ORDER);
+ test_convergence(rk4,
+ my_rhs_function,
+ id_minus_tau_J_inv4,
+ my_exact_solution);
+
+ deallog << "Backward Euler first order" << std::endl;
+ TimeStepping::ImplicitRungeKutta<Vector<double>> be(
+ TimeStepping::BACKWARD_EULER);
+ test_convergence(be,
+ my_rhs_function,
+ id_minus_tau_J_inv1,
+ my_exact_solution);
+
+ deallog << "Implicit midpoint second order" << std::endl;
+ TimeStepping::ImplicitRungeKutta<Vector<double>> im(
+ TimeStepping::IMPLICIT_MIDPOINT);
+ test_convergence(im,
+ my_rhs_function,
+ id_minus_tau_J_inv2,
+ my_exact_solution);
+
+ deallog << "Crank-Nicolson second order" << std::endl;
+ TimeStepping::ImplicitRungeKutta<Vector<double>> cn(
+ TimeStepping::CRANK_NICOLSON);
+ test_convergence(cn,
+ my_rhs_function,
+ id_minus_tau_J_inv2,
+ my_exact_solution);
+
+ deallog << "SDIRK second order" << std::endl;
+ TimeStepping::ImplicitRungeKutta<Vector<double>> sdirk(
+ TimeStepping::SDIRK_TWO_STAGES);
+ test_convergence(sdirk,
+ my_rhs_function,
+ id_minus_tau_J_inv2,
+ my_exact_solution);
+ }
return 0;
}