12 using namespace dealii;
18 template <
typename StateVector,
typename Number>
22 auto &dst_U = std::get<0>(dst);
23 auto &src_U = std::get<0>(src);
24 dst_U.sadd(s, b, src_U);
28 template <
typename Description,
int dim,
typename Number>
30 const MPI_Comm &mpi_communicator,
34 const std::string &subsection )
35 : ParameterAcceptor(subsection)
36 , mpi_communicator_(mpi_communicator)
37 , offline_data_(&offline_data)
38 , hyperbolic_module_(&hyperbolic_module)
39 , parabolic_module_(¶bolic_module)
41 cfl_min_ = Number(0.45);
45 "Minimal admissible relative CFL constant. How this parameter is used "
46 "depends on the chosen CFL recovery strategy");
48 cfl_max_ = Number(0.90);
52 "Maximal admissible relative CFL constant. How this parameter is used "
53 "depends on the chosen CFL recovery strategy");
56 add_parameter(
"cfl recovery strategy",
57 cfl_recovery_strategy_,
58 "CFL/invariant domain violation recovery strategy: none, "
65 add_parameter(
"time stepping scheme",
66 time_stepping_scheme_,
67 "Time stepping scheme: ssprk 22, ssprk 33, erk 11, erk 22, "
68 "erk 33, erk 43, erk "
69 "54, strang ssprk 33 cn, strang erk 33 cn, strang erk 43 cn");
73 template <
typename Description,
int dim,
typename Number>
77 std::cout <<
"TimeIntegrator<dim, Number>::prepare()" << std::endl;
82 switch (time_stepping_scheme_) {
127 for (
auto &it : temp_) {
128 Vectors::reinit_state_vector<Description>(it, *offline_data_);
133 AssertThrow(cfl_min_ > 0., ExcMessage(
"cfl min must be a positive value"));
134 AssertThrow(cfl_max_ >= cfl_min_,
135 ExcMessage(
"cfl max must be greater than or equal to cfl min"));
137 hyperbolic_module_->cfl(cfl_max_);
139 const auto check_whether_timestepping_makes_sense = [&]() {
144 switch (time_stepping_scheme_) {
161 "The selected equation consists of a hyperbolic and nontrivial "
162 "parabolic subsystem and requires an IMEX timestepping "
163 "scheme such as »strang erk 33 cn«."));
174 "The selected equation has a trivial parabolic subsystem and "
175 "should not be run with an IMEX timestepping scheme."));
181 check_whether_timestepping_makes_sense();
182 this->parse_parameters_call_back.connect(
183 check_whether_timestepping_makes_sense);
187 template <
typename Description,
int dim,
typename Number>
193 std::cout <<
"TimeIntegrator<dim, Number>::step()" << std::endl;
196 const auto single_step = [&]() {
197 switch (time_stepping_scheme_) {
199 return step_ssprk_22(state_vector, t);
201 return step_ssprk_33(state_vector, t);
203 return step_erk_11(state_vector, t);
205 return step_erk_22(state_vector, t);
207 return step_erk_33(state_vector, t);
209 return step_erk_43(state_vector, t);
211 return step_erk_54(state_vector, t);
213 return step_strang_ssprk_33_cn(state_vector, t);
215 return step_strang_erk_33_cn(state_vector, t);
217 return step_strang_erk_43_cn(state_vector, t);
219 __builtin_unreachable();
224 hyperbolic_module_->id_violation_strategy_ =
226 parabolic_module_->id_violation_strategy_ =
228 hyperbolic_module_->cfl(cfl_max_);
232 return single_step();
237 dealii::ExcInternalError());
242 hyperbolic_module_->cfl(cfl_min_);
243 return single_step();
246 __builtin_unreachable();
251 template <
typename Description,
int dim,
typename Number>
258 hyperbolic_module_->prepare_state_vector(state_vector, t);
260 hyperbolic_module_->template step<0>(state_vector, {}, {}, temp_[0]);
263 hyperbolic_module_->prepare_state_vector(temp_[0], t + 1.0 * tau);
264 hyperbolic_module_->template step<0>(temp_[0], {}, {}, temp_[1], tau);
267 sadd(temp_[1], Number(1.0 / 2.0), Number(1.0 / 2.0), state_vector);
269 state_vector.swap(temp_[1]);
274 template <
typename Description,
int dim,
typename Number>
281 hyperbolic_module_->prepare_state_vector(state_vector, t);
283 hyperbolic_module_->template step<0>(state_vector, {}, {}, temp_[0]);
286 hyperbolic_module_->prepare_state_vector(temp_[0], t + 1.0 * tau);
287 hyperbolic_module_->template step<0>(temp_[0], {}, {}, temp_[1], tau);
290 sadd(temp_[1], Number(1.0 / 4.0), Number(3.0 / 4.0), state_vector);
293 hyperbolic_module_->prepare_state_vector(temp_[1], t + 0.5 * tau);
294 hyperbolic_module_->template step<0>(temp_[1], {}, {}, temp_[0], tau);
297 sadd(temp_[0], Number(2.0 / 3.0), Number(1.0 / 3.0), state_vector);
299 state_vector.swap(temp_[0]);
304 template <
typename Description,
int dim,
typename Number>
309 std::cout <<
"TimeIntegrator<dim, Number>::step_erk_11()" << std::endl;
313 hyperbolic_module_->prepare_state_vector(state_vector, t);
315 hyperbolic_module_->template step<0>(state_vector, {}, {}, temp_[0]);
317 state_vector.swap(temp_[0]);
322 template <
typename Description,
int dim,
typename Number>
327 std::cout <<
"TimeIntegrator<dim, Number>::step_erk_22()" << std::endl;
331 hyperbolic_module_->prepare_state_vector(state_vector, t);
333 hyperbolic_module_->template step<0>(state_vector, {}, {}, temp_[0]);
336 hyperbolic_module_->prepare_state_vector(temp_[0], t + 1.0 * tau);
337 hyperbolic_module_->template step<1>(
338 temp_[0], {{state_vector}}, {{Number(-1.)}}, temp_[1], tau);
340 state_vector.swap(temp_[1]);
345 template <
typename Description,
int dim,
typename Number>
350 std::cout <<
"TimeIntegrator<dim, Number>::step_erk_33()" << std::endl;
354 hyperbolic_module_->prepare_state_vector(state_vector, t);
356 hyperbolic_module_->template step<0>(state_vector, {}, {}, temp_[0]);
359 hyperbolic_module_->prepare_state_vector(temp_[0], t + 1.0 * tau);
360 hyperbolic_module_->template step<1>(
361 temp_[0], {{state_vector}}, {{Number(-1.)}}, temp_[1], tau);
365 hyperbolic_module_->prepare_state_vector(temp_[1], t + 2.0 * tau);
366 hyperbolic_module_->template step<2>(temp_[1],
367 {{state_vector, temp_[0]}},
368 {{Number(0.75), Number(-2.)}},
372 state_vector.swap(temp_[2]);
377 template <
typename Description,
int dim,
typename Number>
382 std::cout <<
"TimeIntegrator<dim, Number>::step_erk_43()" << std::endl;
386 hyperbolic_module_->prepare_state_vector(state_vector, t);
388 hyperbolic_module_->template step<0>(state_vector, {}, {}, temp_[0]);
391 hyperbolic_module_->prepare_state_vector(temp_[0], t + 1.0 * tau);
392 hyperbolic_module_->template step<1>(
393 temp_[0], {{state_vector}}, {{Number(-1.)}}, temp_[1], tau);
396 hyperbolic_module_->prepare_state_vector(temp_[1], t + 2.0 * tau);
397 hyperbolic_module_->template step<1>(
398 temp_[1], {{temp_[0]}}, {{Number(-1.)}}, temp_[2], tau);
402 hyperbolic_module_->prepare_state_vector(temp_[2], t + 3.0 * tau);
403 hyperbolic_module_->template step<2>(temp_[2],
404 {{temp_[0], temp_[1]}},
405 {{Number(5. / 3.), Number(-10. / 3.)}},
409 state_vector.swap(temp_[3]);
414 template <
typename Description,
int dim,
typename Number>
419 std::cout <<
"TimeIntegrator<dim, Number>::step_erk_54()" << std::endl;
422 constexpr Number c = 0.2;
423 constexpr Number a_21 = +0.2;
424 constexpr Number a_31 = +0.26075582269554909;
425 constexpr Number a_32 = +0.13924417730445096;
426 constexpr Number a_41 = -0.25856517872570289;
427 constexpr Number a_42 = +0.91136274166280729;
428 constexpr Number a_43 = -0.05279756293710430;
429 constexpr Number a_51 = +0.21623276431503774;
430 constexpr Number a_52 = +0.51534223099602405;
431 constexpr Number a_53 = -0.81662794199265554;
432 constexpr Number a_54 = +0.88505294668159373;
433 constexpr Number a_61 = -0.10511678454691901;
434 constexpr Number a_62 = +0.87880047152100838;
435 constexpr Number a_63 = -0.58903404061484477;
436 constexpr Number a_64 = +0.46213380485434047;
440 hyperbolic_module_->prepare_state_vector(state_vector, t);
442 hyperbolic_module_->template step<0>(state_vector, {}, {}, temp_[0]);
445 hyperbolic_module_->prepare_state_vector(temp_[0], t + 1.0 * tau);
446 hyperbolic_module_->template step<1>(
447 temp_[0], {{state_vector}}, {{(a_31 - a_21) / c}}, temp_[1], tau);
450 hyperbolic_module_->prepare_state_vector(temp_[1], t + 2.0 * tau);
451 hyperbolic_module_->template step<2>(
453 {{state_vector, temp_[0]}},
454 {{(a_41 - a_31) / c, (a_42 - a_32) / c}},
459 hyperbolic_module_->prepare_state_vector(temp_[2], t + 3.0 * tau);
460 hyperbolic_module_->template step<3>(
462 {{state_vector, temp_[0], temp_[1]}},
463 {{(a_51 - a_41) / c, (a_52 - a_42) / c, (a_53 - a_43) / c}},
468 hyperbolic_module_->prepare_state_vector(temp_[3], t + 4.0 * tau);
469 hyperbolic_module_->template step<4>(
471 {{state_vector, temp_[0], temp_[1], temp_[2]}},
479 state_vector.swap(temp_[4]);
484 template <
typename Description,
int dim,
typename Number>
491 std::cout <<
"TimeIntegrator<dim, Number>::step_strang_ssprk_33_cn()"
497 hyperbolic_module_->prepare_state_vector( state_vector, t);
498 Number tau = hyperbolic_module_->template step<0>(
499 state_vector, {}, {}, temp_[0]);
501 hyperbolic_module_->prepare_state_vector(temp_[0], t + 1.0 * tau);
502 hyperbolic_module_->template step<0>(temp_[0], {}, {}, temp_[1], tau);
503 sadd(temp_[1], Number(1.0 / 4.0), Number(3.0 / 4.0), state_vector);
505 hyperbolic_module_->prepare_state_vector(temp_[1], t + 0.5 * tau);
506 hyperbolic_module_->template step<0>(temp_[1], {}, {}, temp_[0], tau);
507 sadd(temp_[0], Number(2.0 / 3.0), Number(1.0 / 3.0), state_vector);
511 parabolic_module_->template step<0>(temp_[0], t, {}, {}, temp_[2], tau);
512 sadd(temp_[2], Number(2.), Number(-1.), temp_[0]);
516 hyperbolic_module_->prepare_state_vector( temp_[2], t + 1.0 * tau);
517 hyperbolic_module_->template step<0>( temp_[2], {}, {}, temp_[0], tau);
519 hyperbolic_module_->prepare_state_vector(temp_[0], t + 2.0 * tau);
520 hyperbolic_module_->template step<0>(temp_[0], {}, {}, temp_[1], tau);
521 sadd(temp_[1], Number(1.0 / 4.0), Number(3.0 / 4.0), temp_[2]);
523 hyperbolic_module_->prepare_state_vector(temp_[1], t + 1.5 * tau);
524 hyperbolic_module_->template step<0>(temp_[1], {}, {}, temp_[0], tau);
525 sadd(temp_[0], Number(2.0 / 3.0), Number(1.0 / 3.0), temp_[2]);
527 state_vector.swap(temp_[0]);
532 template <
typename Description,
int dim,
typename Number>
539 std::cout <<
"TimeIntegrator<dim, Number>::step_strang_erk_33_cn()"
545 hyperbolic_module_->prepare_state_vector(state_vector, t);
546 Number tau = hyperbolic_module_->template step<0>(
547 state_vector, {}, {}, temp_[0]);
549 hyperbolic_module_->prepare_state_vector(temp_[0], t + 1.0 * tau);
550 hyperbolic_module_->template step<1>(
551 temp_[0], {{ state_vector}}, {{Number(-1.)}}, temp_[1], tau);
553 hyperbolic_module_->prepare_state_vector(temp_[1], t + 2.0 * tau);
554 hyperbolic_module_->template step<2>(temp_[1],
555 {{ state_vector, temp_[0]}},
556 {{Number(0.75), Number(-2.)}},
562 parabolic_module_->template step<0>(
563 temp_[2], t, {}, {}, temp_[3], 3.0 * tau);
564 sadd(temp_[3], Number(2.), Number(-1.), temp_[2]);
568 hyperbolic_module_->prepare_state_vector(temp_[3], t + 3.0 * tau);
569 hyperbolic_module_->template step<0>(
570 temp_[3], {}, {}, temp_[0], tau);
572 hyperbolic_module_->prepare_state_vector(temp_[0], t + 4.0 * tau);
573 hyperbolic_module_->template step<1>(
574 temp_[0], {{ temp_[3]}}, {{Number(-1.)}}, temp_[1], tau);
576 hyperbolic_module_->prepare_state_vector(temp_[1], t + 5.0 * tau);
577 hyperbolic_module_->template step<2>(temp_[1],
578 {{ temp_[3], temp_[0]}},
579 {{Number(0.75), Number(-2.)}},
583 state_vector.swap(temp_[2]);
588 template <
typename Description,
int dim,
typename Number>
595 std::cout <<
"TimeIntegrator<dim, Number>::step_strang_erk_43_cn()"
601 hyperbolic_module_->prepare_state_vector(state_vector, t);
602 Number tau = hyperbolic_module_->template step<0>(
603 state_vector, {}, {}, temp_[0]);
605 hyperbolic_module_->prepare_state_vector(temp_[0], t + 1.0 * tau);
606 hyperbolic_module_->template step<1>(
607 temp_[0], {{ state_vector}}, {{Number(-1.)}}, temp_[1], tau);
609 hyperbolic_module_->prepare_state_vector(temp_[1], t + 2.0 * tau);
610 hyperbolic_module_->template step<1>(
611 temp_[1], {{temp_[0]}}, {{Number(-1.)}}, temp_[2], tau);
613 hyperbolic_module_->prepare_state_vector(temp_[2], t + 3.0 * tau);
614 hyperbolic_module_->template step<2>(temp_[2],
615 {{temp_[0], temp_[1]}},
616 {{Number(5. / 3.), Number(-10. / 3.)}},
622 parabolic_module_->template step<0>(
623 temp_[3], t, {}, {}, temp_[2], 4.0 * tau);
624 sadd(temp_[2], Number(2.), Number(-1.), temp_[3]);
628 hyperbolic_module_->prepare_state_vector(temp_[2], t + 4.0 * tau);
629 hyperbolic_module_->template step<0>(
630 temp_[2], {}, {}, temp_[0], tau);
632 hyperbolic_module_->prepare_state_vector(temp_[0], t + 5.0 * tau);
633 hyperbolic_module_->template step<1>(
634 temp_[0], {{ temp_[2]}}, {{Number(-1.)}}, temp_[1], tau);
636 hyperbolic_module_->prepare_state_vector(temp_[1], t + 6.0 * tau);
637 hyperbolic_module_->template step<1>(
638 temp_[1], {{temp_[0]}}, {{Number(-1.)}}, temp_[2], tau);
640 hyperbolic_module_->prepare_state_vector(temp_[2], t + 7.0 * tau);
641 hyperbolic_module_->template step<2>(temp_[2],
642 {{temp_[0], temp_[1]}},
643 {{Number(5. / 3.), Number(-10. / 3.)}},
647 state_vector.swap(temp_[3]);
static constexpr bool is_identity
Number step_ssprk_33(StateVector &state_vector, Number t)
TimeIntegrator(const MPI_Comm &mpi_communicator, const OfflineData< dim, Number > &offline_data, const HyperbolicModule< Description, dim, Number > &hyperbolic_module, const ParabolicModule< Description, dim, Number > ¶bolic_module, const std::string &subsection="/TimeIntegrator")
Number step_erk_54(StateVector &state_vector, Number t)
Number step_strang_erk_33_cn(StateVector &state_vector, Number t)
typename View::StateVector StateVector
Number step(StateVector &state_vector, Number t)
Number step_strang_erk_43_cn(StateVector &state_vector, Number t)
Number step_strang_ssprk_33_cn(StateVector &state_vector, Number t)
Number step_ssprk_22(StateVector &state_vector, Number t)
Number step_erk_22(StateVector &state_vector, Number t)
Number step_erk_43(StateVector &state_vector, Number t)
Number step_erk_33(StateVector &state_vector, Number t)
Number step_erk_11(StateVector &state_vector, Number t)
std::tuple< MultiComponentVector< Number, problem_dim >, MultiComponentVector< Number, prec_dim >, BlockVector< Number > > StateVector
void sadd(StateVector &dst, const Number s, const Number b, const StateVector &src)