26#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
51 double norm()
const {
return std::sqrt(
x *
x +
y *
y); }
54static auto v2init = [](
Vec2 &
v) {
v =
Vec2(0, 0); };
61static const double g_omega = 2.0 *
pi;
68 rhs.
x = -g_omega * u.y;
69 rhs.
y = g_omega * u.x;
75 dTau =
Vec2(1e100, 1e100);
86 double d = 1.0 / dTau.x + 1.0 / dt;
87 double aw =
alpha * g_omega;
88 double det = d * d + aw * aw;
89 xinc.x = (d * rhs.
x - aw * rhs.
y) / det;
90 xinc.y = (aw * rhs.
x + d * rhs.
y) / det;
102static const int g_maxNewton = 50;
103static const double g_newtonTol = 1e-13;
109 Vec2 u(1.0, 0.0), xinc;
112 auto fstop = [&](
int iter,
Vec2 &
res, int) ->
bool
114 double resNorm = std::sqrt(
res.x *
res.x +
res.y *
res.y);
115 return resNorm < g_newtonTol || iter >= g_maxNewton;
118 for (
int step = 0; step <
N; step++)
119 ode.Step(u, xinc, g_frhs, g_fdt, g_fsolve, g_maxNewton, fstop, g_fincrement, dt);
122 double ex = std::cos(g_omega * T);
123 double ey = std::sin(g_omega * T);
124 return std::sqrt((u.
x - ex) * (u.
x - ex) + (u.
y - ey) * (u.
y - ey));
134 double T,
int N_base)
136 double e1 = integrateOscillator(
ode, T, N_base);
137 double e2 = integrateOscillator(
ode, T, 2 * N_base);
138 return {
e1,
e2, std::log2(
e1 /
e2)};
145 auto run = [&](
int N) {
147 return integrateOscillator(
ode, T,
N);
149 double e1 = run(N_base);
150 double e2 = run(2 * N_base);
151 return {
e1,
e2, std::log2(
e1 /
e2)};
156 double T,
int N_base)
158 auto run = [&](
int N) {
160 1, v2init, v2init,
alpha, 0, 0,
161 0.9146, 0.0, mask, 0);
162 return integrateOscillator(
ode, T,
N);
164 double e1 = run(N_base);
165 double e2 = run(2 * N_base);
166 return {
e1,
e2, std::log2(
e1 /
e2)};
176 auto res = measureOrder(
ode, 1.0, 100);
177 std::cout <<
"[SSPRK3] err1=" << std::scientific <<
res.err_coarse
178 <<
" err2=" <<
res.err_fine <<
" order=" << std::fixed <<
res.order << std::endl;
186 auto res = measureOrder(
ode, 1.0, 200);
187 std::cout <<
"[ImplicitEuler] err1=" << std::scientific <<
res.err_coarse
188 <<
" err2=" <<
res.err_fine <<
" order=" << std::fixed <<
res.order << std::endl;
193TEST_CASE(
"SDIRK4 (sc=0): 4th-order on oscillator")
197 std::cout <<
"[SDIRK4-sc0] err1=" << std::scientific <<
res.err_coarse
198 <<
" err2=" <<
res.err_fine <<
" order=" << std::fixed <<
res.order << std::endl;
203TEST_CASE(
"ESDIRK4 (sc=1): 4th-order on oscillator")
205 auto res = measureOrderESDIRK<1>(1.0, 20);
206 std::cout <<
"[ESDIRK4-sc1] err1=" << std::scientific <<
res.err_coarse
207 <<
" err2=" <<
res.err_fine <<
" order=" << std::fixed <<
res.order << std::endl;
212TEST_CASE(
"ESDIRK3 (sc=2): 3rd-order on oscillator")
214 auto res = measureOrderESDIRK<2>(1.0, 40);
215 std::cout <<
"[ESDIRK3-sc2] err1=" << std::scientific <<
res.err_coarse
216 <<
" err2=" <<
res.err_fine <<
" order=" << std::fixed <<
res.order << std::endl;
221TEST_CASE(
"Trapezoid (sc=3): 2nd-order on oscillator")
223 auto res = measureOrderESDIRK<3>(1.0, 40);
224 std::cout <<
"[Trapezoid-sc3] err1=" << std::scientific <<
res.err_coarse
225 <<
" err2=" <<
res.err_fine <<
" order=" << std::fixed <<
res.order << std::endl;
230TEST_CASE(
"ESDIRK2 (sc=4): 2nd-order on oscillator")
232 auto res = measureOrderESDIRK<4>(1.0, 40);
233 std::cout <<
"[ESDIRK2-sc4] err1=" << std::scientific <<
res.err_coarse
234 <<
" err2=" <<
res.err_fine <<
" order=" << std::fixed <<
res.order << std::endl;
239TEST_CASE(
"VBDF k=1: 1st-order on oscillator")
242 auto res = measureOrder(
ode, 1.0, 200);
243 std::cout <<
"[VBDF1] err1=" << std::scientific <<
res.err_coarse
244 <<
" err2=" <<
res.err_fine <<
" order=" << std::fixed <<
res.order << std::endl;
249TEST_CASE(
"VBDF k=2: 2nd-order on oscillator")
251 auto run = [](
int N) {
253 return integrateOscillator(
ode, 1.0,
N);
255 double e1 = run(100);
256 double e2 = run(200);
258 std::cout <<
"[VBDF2] err1=" << std::scientific <<
e1
259 <<
" err2=" <<
e2 <<
" order=" << std::fixed <<
order << std::endl;
271TEST_CASE(
"DITR U2R2 (mask=0, alpha=0.5): 4th-order on oscillator")
274 auto res = measureOrderDITR(0, 0.5, 1.0, 20);
275 std::cout <<
"[DITR-U2R2] err1=" << std::scientific <<
res.err_coarse
276 <<
" err2=" <<
res.err_fine <<
" order=" << std::fixed <<
res.order << std::endl;
281TEST_CASE(
"DITR U2R2 (mask=0, alpha=0.55): 3rd-order on oscillator")
284 auto res = measureOrderDITR(0, 0.55, 1.0, 40);
285 std::cout <<
"[DITR-U2R2-0.55] err1=" << std::scientific <<
res.err_coarse
286 <<
" err2=" <<
res.err_fine <<
" order=" << std::fixed <<
res.order << std::endl;
291TEST_CASE(
"DITR U2R1 (mask=1): 3rd-order L-stable on oscillator")
293 auto res = measureOrderDITR(1, 0.55, 1.0, 40);
294 std::cout <<
"[DITR-U2R1] err1=" << std::scientific <<
res.err_coarse
295 <<
" err2=" <<
res.err_fine <<
" order=" << std::fixed <<
res.order << std::endl;
304TEST_CASE(
"SSPRK3: golden value on oscillator")
307 double err = integrateOscillator(
ode, 0.5, 200);
308 std::cout <<
"[SSPRK3/golden] err=" << std::scientific << std::setprecision(10) <<
err << std::endl;
std::function< void(TDATA &, TDATA &, TDTAU &, int, real, int)> Frhs
std::function< void(TDATA &, TDATA &, TDATA &, TDTAU &, real, real, TDATA &, int, real, int)> Fsolve
std::function< void(TDATA &, TDTAU &, real, int)> Fdt
std::function< void(TDATA &, TDATA &, real, int)> Fincrement
the host side operators are provided as implemented
DNDS_CONSTANT const real pi
π in double precision (matches DNDS_E_PI macro).
double real
Canonical floating-point scalar used throughout DNDSR (double precision).
void operator*=(const Vec2 &o)
void operator*=(double s)
void operator+=(const Vec2 &o)
void addTo(const Vec2 &o, double s)
Vec2 & operator=(const Vec2 &)=default
void setConstant(double s)
Eigen::Matrix< real, 5, 1 > v
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)
TEST_CASE("3D: VFV P2 HQM error < P1 on sinCos3D")