DNDSR 0.1.0.dev1+gcd065ad
Distributed Numeric Data Structure for CFV
Loading...
Searching...
No Matches
test_ODE.cpp File Reference

Unit tests for ODE time integrators in Solver/ODE.hpp. More...

#include "doctest.h"
#include "Solver/ODE.hpp"
#include <cmath>
#include <iostream>
#include <iomanip>
Include dependency graph for test_ODE.cpp:

Go to the source code of this file.

Classes

struct  Vec2
 
struct  ConvergenceResult
 

Macros

#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
 

Typedefs

using tODE = ODE::ImplicitDualTimeStep< Vec2, Vec2 >
 

Functions

 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, Vec2ode (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, Vec2ode (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, Vec2ode (1, v2init, v2init)
 

Variables

auto res = measureOrder(ode, 1.0, 20)
 
double e1 = run(100)
 
double e2 = run(200)
 
double order = std::log2(e1 / e2)
 
double err = integrateOscillator(ode, 0.5, 200)
 

Detailed Description

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.

Macro Definition Documentation

◆ DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN

#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN

Definition at line 26 of file test_ODE.cpp.

Typedef Documentation

◆ tODE

Definition at line 63 of file test_ODE.cpp.

Function Documentation

◆ integrateOscillator()

return integrateOscillator ( ode  ,
1.  0,
N   
)

◆ ode() [1/3]

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 ( ,
v2init  ,
v2init   
)

◆ ode() [2/3]

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 ( ,
v2init  ,
v2init  ,
 
)
Here is the caller graph for this function:

◆ ode() [3/3]

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 ( ,
v2init  ,
v2init  ,
 
)

◆ 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 >()

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<< "[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 >()

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<< "[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 >()

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<< "[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 >()

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   
)

◆ TEST_CASE() [1/2]

TEST_CASE ( "ImplicitEuler: 1st-order on oscillator"  )

Definition at line 183 of file test_ODE.cpp.

Here is the call graph for this function:

◆ TEST_CASE() [2/2]

TEST_CASE ( "SSPRK3: 3rd-order on oscillator"  )

Definition at line 173 of file test_ODE.cpp.

Here is the call graph for this function:

Variable Documentation

◆ e1

double e1 = run(100)

Definition at line 255 of file test_ODE.cpp.

◆ e2

double e2 = run(200)

Definition at line 256 of file test_ODE.cpp.

◆ err

double err = integrateOscillator(ode, 0.5, 200)

Definition at line 307 of file test_ODE.cpp.

◆ order

double order = std::log2(e1 / e2)

Definition at line 257 of file test_ODE.cpp.

◆ res

auto res = measureOrder(ode, 1.0, 20)

Definition at line 196 of file test_ODE.cpp.