TEST(NumLib, TimeSteppingIterationNumberBased1) { std::vector<std::size_t> iter_times_vector = {0, 3, 5, 7}; std::vector<double> multiplier_vector = {2.0, 1.0, 0.5, 0.25}; NumLib::IterationNumberBasedAdaptiveTimeStepping alg(1, 31, 1, 10, 1, iter_times_vector, multiplier_vector); ASSERT_TRUE(alg.next()); // t=2, dt=1 NumLib::TimeStep ts = alg.getTimeStep(); ASSERT_EQ(1u, ts.steps()); ASSERT_EQ(1., ts.previous()); ASSERT_EQ(2., ts.current()); ASSERT_EQ(1., ts.dt()); ASSERT_TRUE(alg.accepted()); ASSERT_TRUE(alg.next()); // t=4, dt=2 // dt*=2 alg.setNIterations(3); ASSERT_TRUE(alg.next()); // t=8, dt=4 ts = alg.getTimeStep(); ASSERT_EQ(3u, ts.steps()); ASSERT_EQ(4., ts.previous()); ASSERT_EQ(8., ts.current()); ASSERT_EQ(4., ts.dt()); ASSERT_TRUE(alg.accepted()); // dt*=1 alg.setNIterations(5); ASSERT_TRUE(alg.next()); // t=12, dt=4 ts = alg.getTimeStep(); ASSERT_EQ(4u, ts.steps()); ASSERT_EQ(8., ts.previous()); ASSERT_EQ(12., ts.current()); ASSERT_EQ(4., ts.dt()); ASSERT_TRUE(alg.accepted()); // dt*=0.5 alg.setNIterations(7); ASSERT_TRUE(alg.next()); // t=14, dt=2 ts = alg.getTimeStep(); ASSERT_EQ(5u, ts.steps()); ASSERT_EQ(12., ts.previous()); ASSERT_EQ(14., ts.current()); ASSERT_EQ(2., ts.dt()); ASSERT_TRUE(alg.accepted()); // dt*=0.25 but dt_min = 1 alg.setNIterations(8); // exceed max ASSERT_TRUE(alg.next()); // t=13, dt=1 ts = alg.getTimeStep(); ASSERT_EQ(5u, ts.steps()); ASSERT_EQ(12., ts.previous()); ASSERT_EQ(13, ts.current()); ASSERT_EQ(1., ts.dt()); ASSERT_FALSE(alg.accepted()); // restart, dt*=1 alg.setNIterations(4); ASSERT_TRUE(alg.next()); // t=14, dt=1 ts = alg.getTimeStep(); ASSERT_EQ(6u, ts.steps()); ASSERT_EQ(13., ts.previous()); ASSERT_EQ(14, ts.current()); ASSERT_EQ(1., ts.dt()); ASSERT_TRUE(alg.accepted()); }
TEST(NumLibTimeStepping, testEvolutionaryPIDcontroller) { const char xml[] = "<time_stepping>" " <type>EvolutionaryPIDcontroller</type>" " <t_initial> 0.0 </t_initial>" " <t_end> 10 </t_end>" " <dt_guess> 0.01 </dt_guess>" " <dt_min> 0.001 </dt_min>" " <dt_max> 1 </dt_max>" " <rel_dt_min> 0.01 </rel_dt_min>" " <rel_dt_max> 5 </rel_dt_max>" " <tol> 1.e-3 </tol>" "</time_stepping>"; auto const PIDStepper = createTestTimeStepper(xml); double solution_error = 0.; int const number_iterations = 0; // 1st step ASSERT_TRUE(PIDStepper->next(solution_error, number_iterations)); NumLib::TimeStep ts = PIDStepper->getTimeStep(); double h_new = 0.01; double t_previous = 0.; ASSERT_EQ(1u, ts.steps()); ASSERT_EQ(t_previous, ts.previous()); ASSERT_EQ(t_previous + h_new, ts.current()); ASSERT_EQ(h_new, ts.dt()); ASSERT_TRUE(PIDStepper->accepted()); t_previous += h_new; // e_n_minus1 is filled. solution_error = 1.0e-4; PIDStepper->next(solution_error, number_iterations); ts = PIDStepper->getTimeStep(); h_new = ts.dt(); ASSERT_EQ(2u, ts.steps()); const double tol = 1.e-16; ASSERT_NEAR(t_previous, ts.previous(), tol); ASSERT_NEAR(t_previous + h_new, ts.current(), tol); ASSERT_TRUE(PIDStepper->accepted()); t_previous += h_new; // e_n_minus2 is filled. solution_error = 0.5e-3; PIDStepper->next(solution_error, number_iterations); ts = PIDStepper->getTimeStep(); h_new = ts.dt(); ASSERT_EQ(3u, ts.steps()); ASSERT_NEAR(t_previous, ts.previous(), tol); ASSERT_NEAR(t_previous + h_new, ts.current(), tol); ASSERT_TRUE(PIDStepper->accepted()); // error > TOL=1.3-3, step rejected and new step size estimated. solution_error = 0.01; PIDStepper->next(solution_error, number_iterations); ts = PIDStepper->getTimeStep(); h_new = ts.dt(); // No change in ts.steps ASSERT_EQ(3u, ts.steps()); // No change in ts.previous(), which is the same as that of the previous // step. ASSERT_NEAR(t_previous, ts.previous(), tol); ASSERT_NEAR(t_previous + h_new, ts.current(), tol); ASSERT_FALSE(PIDStepper->accepted()); t_previous += h_new; // With e_n, e_n_minus1, e_n_minus2 solution_error = 0.4e-3; PIDStepper->next(solution_error, number_iterations); ts = PIDStepper->getTimeStep(); h_new = ts.dt(); ASSERT_EQ(4u, ts.steps()); ASSERT_NEAR(t_previous, ts.previous(), tol); ASSERT_NEAR(t_previous + h_new, ts.current(), tol); ASSERT_TRUE(PIDStepper->accepted()); }