|
| | TEST_CASE ("SSPRK3: 3rd-order on oscillator") |
| |
| | TEST_CASE ("ImplicitEuler: 1st-order on oscillator") |
| |
| | std::cout<< "[SDIRK4-sc0] err1="<< std::scientific<< res.err_coarse<< " err2="<< res.err_fine<< " order="<< std::fixed<< res.order<< std::endl;CHECK(res.order > 3.5);CHECK(res.order< 4.5);}{ auto res=measureOrderESDIRK< 1 > (1.0, 20) |
| |
| | std::cout<< "[ESDIRK4-sc1] err1="<< std::scientific<< res.err_coarse<< " err2="<< res.err_fine<< " order="<< std::fixed<< res.order<< std::endl;CHECK(res.order > 3.5);CHECK(res.order< 5.0);}{ auto res=measureOrderESDIRK< 2 > (1.0, 40) |
| |
| | std::cout<< "[ESDIRK3-sc2] err1="<< std::scientific<< res.err_coarse<< " err2="<< res.err_fine<< " order="<< std::fixed<< res.order<< std::endl;CHECK(res.order > 2.7);CHECK(res.order< 3.5);}{ auto res=measureOrderESDIRK< 3 > (1.0, 40) |
| |
| | std::cout<< "[Trapezoid-sc3] err1="<< std::scientific<< res.err_coarse<< " err2="<< res.err_fine<< " order="<< std::fixed<< res.order<< std::endl;CHECK(res.order > 1.8);CHECK(res.order< 2.5);}{ auto res=measureOrderESDIRK< 4 > (1.0, 40) |
| |
| std::cout<< "[ESDIRK2-sc4] err1="<< std::scientific<< res.err_coarse<< " err2="<< res.err_fine<< " order="<< std::fixed<< res.order<< std::endl;CHECK(res.order > 1.8);CHECK(res.order< 2.5);}TEST_CASE("VBDF k=1: 1st-order on oscillator"){ ODE::ImplicitVBDFDualTimeStep< Vec2, Vec2 > | ode (1, v2init, v2init, 1) |
| |
| std::cout<< "[VBDF1] err1="<< std::scientific<< res.err_coarse<< " err2="<< res.err_fine<< " order="<< std::fixed<< res.order<< std::endl;CHECK(res.order > 0.9);CHECK(res.order< 1.3);}TEST_CASE("VBDF k=2: 2nd-order on oscillator"){ auto run=[](int N) { ODE::ImplicitVBDFDualTimeStep< Vec2, Vec2 > | ode (1, v2init, v2init, 2) |
| |
| return | integrateOscillator (ode, 1.0, N) |
| |
| std::cout<< "[VBDF2] err1="<< std::scientific<< e1<< " err2="<< e2<< " order="<< std::fixed<< order<< std::endl;CHECK(order > 1.8);CHECK(order< 2.5);}{ auto res=measureOrderDITR(0, 0.5, 1.0, 20);std::cout<< "[DITR-U2R2] err1="<< std::scientific<< res.err_coarse<< " err2="<< res.err_fine<< " order="<< std::fixed<< res.order<< std::endl;CHECK(res.order > 3.5);CHECK(res.order< 5.0);}{ auto res=measureOrderDITR(0, 0.55, 1.0, 40);std::cout<< "[DITR-U2R2-0.55] err1="<< std::scientific<< res.err_coarse<< " err2="<< res.err_fine<< " order="<< std::fixed<< res.order<< std::endl;CHECK(res.order > 2.7);CHECK(res.order< 4.0);}{ auto res=measureOrderDITR(1, 0.55, 1.0, 40);std::cout<< "[DITR-U2R1] err1="<< std::scientific<< res.err_coarse<< " err2="<< res.err_fine<< " order="<< std::fixed<< res.order<< std::endl;CHECK(res.order > 2.7);CHECK(res.order< 3.5);}TEST_CASE("SSPRK3: golden value on oscillator"){ ODE::ExplicitSSPRK3TimeStepAsImplicitDualTimeStep< Vec2, Vec2 > | ode (1, v2init, v2init) |
| |
Unit tests for ODE time integrators in Solver/ODE.hpp.
Tests the harmonic oscillator du/dt = A*u, A = [[0,-w],[w,0]], u(0) = [1,0], exact: u(t) = [cos(wt), sin(wt)]. This oscillatory (non-dissipative) problem reveals phase/amplitude errors that decay tests hide.
Verified convergence orders:
- ExplicitSSPRK3: 3rd
- ImplicitEuler: 1st
- SDIRK4 sc=0: 4th
- ESDIRK4 sc=1 (DITR U2R2 form): 4th
- ESDIRK3 sc=2: 3rd
- Trapezoid sc=3: 2nd
- ESDIRK2 sc=4: 2nd
- VBDF k=1: 1st
- VBDF k=2: 2nd
- DITR U2R2 (Hermite3 mask=0): 4th (single-step, FSAL)
- DITR U2R1 (Hermite3 mask=1): 3rd (L-stable)
All tests are serial (no MPI).
Definition in file test_ODE.cpp.