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>
34 const std::string &subsection )
35 : ParameterAcceptor(subsection)
36 , mpi_ensemble_(mpi_ensemble)
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, "
70 "imex 11, imex 22, imex 33");
74 template <
typename Description,
int dim,
typename Number>
78 std::cout <<
"TimeIntegrator<dim, Number>::prepare()" << std::endl;
83 switch (time_stepping_scheme_) {
140 for (
auto &it : temp_) {
141 Vectors::reinit_state_vector<Description>(it, *offline_data_);
146 AssertThrow(cfl_min_ > 0., ExcMessage(
"cfl min must be a positive value"));
147 AssertThrow(cfl_max_ >= cfl_min_,
148 ExcMessage(
"cfl max must be greater than or equal to cfl min"));
150 hyperbolic_module_->cfl(cfl_max_);
152 const auto check_whether_timestepping_makes_sense = [&]() {
157 switch (time_stepping_scheme_) {
174 "The selected equation consists of a hyperbolic and nontrivial "
175 "parabolic subsystem and requires an IMEX timestepping "
176 "scheme such as »strang erk 33 cn«."));
193 "The selected equation has a trivial parabolic subsystem and "
194 "should not be run with an IMEX timestepping scheme."));
200 check_whether_timestepping_makes_sense();
201 this->parse_parameters_call_back.connect(
202 check_whether_timestepping_makes_sense);
206 template <
typename Description,
int dim,
typename Number>
213 std::cout <<
"TimeIntegrator<dim, Number>::step()" << std::endl;
215 Number tau_max = t_final - t;
217 const auto single_step = [&]() {
218 switch (time_stepping_scheme_) {
220 return step_ssprk_22(state_vector, t, tau_max);
222 return step_ssprk_33(state_vector, t, tau_max);
224 return step_erk_11(state_vector, t, tau_max);
226 return step_erk_22(state_vector, t, tau_max);
228 return step_erk_33(state_vector, t, tau_max);
230 return step_erk_43(state_vector, t, tau_max);
232 return step_erk_54(state_vector, t, tau_max);
234 return step_strang_ssprk_33_cn(state_vector, t, tau_max);
236 return step_strang_erk_33_cn(state_vector, t, tau_max);
238 return step_strang_erk_43_cn(state_vector, t, tau_max);
240 return step_imex_11(state_vector, t, tau_max);
242 return step_imex_22(state_vector, t, tau_max);
244 return step_imex_33(state_vector, t, tau_max);
246 __builtin_unreachable();
251 hyperbolic_module_->id_violation_strategy_ =
253 parabolic_module_->id_violation_strategy_ =
255 hyperbolic_module_->cfl(cfl_max_);
259 return single_step();
264 dealii::ExcInternalError());
269 hyperbolic_module_->cfl(cfl_min_);
270 return single_step();
273 __builtin_unreachable();
278 template <
typename Description,
int dim,
typename Number>
285 hyperbolic_module_->prepare_state_vector(state_vector, t);
286 Number tau = hyperbolic_module_->template step<0>(
287 state_vector, {}, {}, temp_[0], Number(0.), tau_max);
290 hyperbolic_module_->prepare_state_vector(temp_[0], t + 1.0 * tau);
291 hyperbolic_module_->template step<0>(temp_[0], {}, {}, temp_[1], tau);
294 sadd(temp_[1], Number(1.0 / 2.0), Number(1.0 / 2.0), state_vector);
296 state_vector.swap(temp_[1]);
301 template <
typename Description,
int dim,
typename Number>
303 StateVector &state_vector, Number t, Number tau_max)
308 hyperbolic_module_->prepare_state_vector(state_vector, t);
309 Number tau = hyperbolic_module_->template step<0>(
310 state_vector, {}, {}, temp_[0], Number(0.), tau_max);
313 hyperbolic_module_->prepare_state_vector(temp_[0], t + 1.0 * tau);
314 hyperbolic_module_->template step<0>(temp_[0], {}, {}, temp_[1], tau);
317 sadd(temp_[1], Number(1.0 / 4.0), Number(3.0 / 4.0), state_vector);
320 hyperbolic_module_->prepare_state_vector(temp_[1], t + 0.5 * tau);
321 hyperbolic_module_->template step<0>(temp_[1], {}, {}, temp_[0], tau);
324 sadd(temp_[0], Number(2.0 / 3.0), Number(1.0 / 3.0), state_vector);
326 state_vector.swap(temp_[0]);
331 template <
typename Description,
int dim,
typename Number>
333 StateVector &state_vector, Number t, Number tau_max)
336 std::cout <<
"TimeIntegrator<dim, Number>::step_erk_11()" << std::endl;
340 hyperbolic_module_->prepare_state_vector(state_vector, t);
341 Number tau = hyperbolic_module_->template step<0>(
342 state_vector, {}, {}, temp_[0], Number(0.), tau_max);
344 state_vector.swap(temp_[0]);
349 template <
typename Description,
int dim,
typename Number>
354 std::cout <<
"TimeIntegrator<dim, Number>::step_erk_22()" << std::endl;
358 hyperbolic_module_->prepare_state_vector(state_vector, t);
359 Number tau = hyperbolic_module_->template step<0>(
360 state_vector, {}, {}, temp_[0], Number(.0), tau_max / 2.);
363 hyperbolic_module_->prepare_state_vector(temp_[0], t + 1.0 * tau);
364 hyperbolic_module_->template step<1>(
365 temp_[0], {{state_vector}}, {{Number(-1.)}}, temp_[1], tau);
367 state_vector.swap(temp_[1]);
372 template <
typename Description,
int dim,
typename Number>
374 StateVector &state_vector, Number t, Number tau_max)
377 std::cout <<
"TimeIntegrator<dim, Number>::step_erk_33()" << std::endl;
381 hyperbolic_module_->prepare_state_vector(state_vector, t);
382 Number tau = hyperbolic_module_->template step<0>(
383 state_vector, {}, {}, temp_[0], Number(0.), tau_max / 3.);
386 hyperbolic_module_->prepare_state_vector(temp_[0], t + 1.0 * tau);
387 hyperbolic_module_->template step<1>(
388 temp_[0], {{state_vector}}, {{Number(-1.)}}, temp_[1], tau);
394 hyperbolic_module_->prepare_state_vector(temp_[1], t + 2.0 * tau);
395 hyperbolic_module_->template step<2>(temp_[1],
396 {{state_vector, temp_[0]}},
397 {{Number(0.75), Number(-2.)}},
401 state_vector.swap(temp_[2]);
406 template <
typename Description,
int dim,
typename Number>
408 StateVector &state_vector, Number t, Number tau_max)
411 std::cout <<
"TimeIntegrator<dim, Number>::step_erk_43()" << std::endl;
415 hyperbolic_module_->prepare_state_vector(state_vector, t);
416 Number tau = hyperbolic_module_->template step<0>(
417 state_vector, {}, {}, temp_[0], Number(0.), tau_max / 4.);
420 hyperbolic_module_->prepare_state_vector(temp_[0], t + 1.0 * tau);
421 hyperbolic_module_->template step<1>(
422 temp_[0], {{state_vector}}, {{Number(-1.)}}, temp_[1], tau);
425 hyperbolic_module_->prepare_state_vector(temp_[1], t + 2.0 * tau);
426 hyperbolic_module_->template step<1>(
427 temp_[1], {{temp_[0]}}, {{Number(-1.)}}, temp_[2], tau);
433 hyperbolic_module_->prepare_state_vector(temp_[2], t + 3.0 * tau);
434 hyperbolic_module_->template step<2>(temp_[2],
435 {{temp_[0], temp_[1]}},
436 {{Number(5. / 3.), Number(-10. / 3.)}},
440 state_vector.swap(temp_[3]);
445 template <
typename Description,
int dim,
typename Number>
447 StateVector &state_vector, Number t, Number tau_max)
450 std::cout <<
"TimeIntegrator<dim, Number>::step_erk_54()" << std::endl;
453 constexpr Number c = 0.2;
454 constexpr Number a_21 = +0.2;
455 constexpr Number a_31 = +0.26075582269554909;
456 constexpr Number a_32 = +0.13924417730445096;
457 constexpr Number a_41 = -0.25856517872570289;
458 constexpr Number a_42 = +0.91136274166280729;
459 constexpr Number a_43 = -0.05279756293710430;
460 constexpr Number a_51 = +0.21623276431503774;
461 constexpr Number a_52 = +0.51534223099602405;
462 constexpr Number a_53 = -0.81662794199265554;
463 constexpr Number a_54 = +0.88505294668159373;
464 constexpr Number a_61 = -0.10511678454691901;
465 constexpr Number a_62 = +0.87880047152100838;
466 constexpr Number a_63 = -0.58903404061484477;
467 constexpr Number a_64 = +0.46213380485434047;
471 hyperbolic_module_->prepare_state_vector(state_vector, t);
472 Number tau = hyperbolic_module_->template step<0>(
473 state_vector, {}, {}, temp_[0], Number(0.), tau_max / 5.);
476 hyperbolic_module_->prepare_state_vector(temp_[0], t + 1.0 * tau);
477 hyperbolic_module_->template step<1>(
478 temp_[0], {{state_vector}}, {{(a_31 - a_21) / c}}, temp_[1], tau);
481 hyperbolic_module_->prepare_state_vector(temp_[1], t + 2.0 * tau);
482 hyperbolic_module_->template step<2>(
484 {{state_vector, temp_[0]}},
485 {{(a_41 - a_31) / c, (a_42 - a_32) / c}},
490 hyperbolic_module_->prepare_state_vector(temp_[2], t + 3.0 * tau);
491 hyperbolic_module_->template step<3>(
493 {{state_vector, temp_[0], temp_[1]}},
494 {{(a_51 - a_41) / c, (a_52 - a_42) / c, (a_53 - a_43) / c}},
499 hyperbolic_module_->prepare_state_vector(temp_[3], t + 4.0 * tau);
500 hyperbolic_module_->template step<4>(
502 {{state_vector, temp_[0], temp_[1], temp_[2]}},
510 state_vector.swap(temp_[4]);
515 template <
typename Description,
int dim,
typename Number>
517 StateVector &state_vector, Number t, Number tau_max)
522 std::cout <<
"TimeIntegrator<dim, Number>::step_strang_ssprk_33_cn()"
528 hyperbolic_module_->prepare_state_vector( state_vector, t);
529 Number tau = hyperbolic_module_->template step<0>(
530 state_vector, {}, {}, temp_[0], Number(0.0), tau_max / 2.);
532 hyperbolic_module_->prepare_state_vector(temp_[0], t + 1.0 * tau);
533 hyperbolic_module_->template step<0>(temp_[0], {}, {}, temp_[1], tau);
534 sadd(temp_[1], Number(1.0 / 4.0), Number(3.0 / 4.0), state_vector);
536 hyperbolic_module_->prepare_state_vector(temp_[1], t + 0.5 * tau);
537 hyperbolic_module_->template step<0>(temp_[1], {}, {}, temp_[0], tau);
538 sadd(temp_[0], Number(2.0 / 3.0), Number(1.0 / 3.0), state_vector);
542 parabolic_module_->template step<0>(temp_[0], t, {}, {}, temp_[2], tau);
543 sadd(temp_[2], Number(2.), Number(-1.), temp_[0]);
547 hyperbolic_module_->prepare_state_vector( temp_[2], t + 1.0 * tau);
548 hyperbolic_module_->template step<0>( temp_[2], {}, {}, temp_[0], tau);
550 hyperbolic_module_->prepare_state_vector(temp_[0], t + 2.0 * tau);
551 hyperbolic_module_->template step<0>(temp_[0], {}, {}, temp_[1], tau);
552 sadd(temp_[1], Number(1.0 / 4.0), Number(3.0 / 4.0), temp_[2]);
554 hyperbolic_module_->prepare_state_vector(temp_[1], t + 1.5 * tau);
555 hyperbolic_module_->template step<0>(temp_[1], {}, {}, temp_[0], tau);
556 sadd(temp_[0], Number(2.0 / 3.0), Number(1.0 / 3.0), temp_[2]);
558 state_vector.swap(temp_[0]);
563 template <
typename Description,
int dim,
typename Number>
565 StateVector &state_vector, Number t, Number tau_max)
570 std::cout <<
"TimeIntegrator<dim, Number>::step_strang_erk_33_cn()"
576 hyperbolic_module_->prepare_state_vector(state_vector, t);
577 Number tau = hyperbolic_module_->template step<0>(
578 state_vector, {}, {}, temp_[0], Number(0.), tau_max / 6.);
580 hyperbolic_module_->prepare_state_vector(temp_[0], t + 1.0 * tau);
581 hyperbolic_module_->template step<1>(
582 temp_[0], {{ state_vector}}, {{Number(-1.)}}, temp_[1], tau);
584 hyperbolic_module_->prepare_state_vector(temp_[1], t + 2.0 * tau);
585 hyperbolic_module_->template step<2>(temp_[1],
586 {{ state_vector, temp_[0]}},
587 {{Number(0.75), Number(-2.)}},
593 parabolic_module_->template step<0>(
594 temp_[2], t, {}, {}, temp_[3], 3.0 * tau);
595 sadd(temp_[3], Number(2.), Number(-1.), temp_[2]);
599 hyperbolic_module_->prepare_state_vector(temp_[3], t + 3.0 * tau);
600 hyperbolic_module_->template step<0>(
601 temp_[3], {}, {}, temp_[0], tau);
603 hyperbolic_module_->prepare_state_vector(temp_[0], t + 4.0 * tau);
604 hyperbolic_module_->template step<1>(
605 temp_[0], {{ temp_[3]}}, {{Number(-1.)}}, temp_[1], tau);
607 hyperbolic_module_->prepare_state_vector(temp_[1], t + 5.0 * tau);
608 hyperbolic_module_->template step<2>(temp_[1],
609 {{ temp_[3], temp_[0]}},
610 {{Number(0.75), Number(-2.)}},
614 state_vector.swap(temp_[2]);
619 template <
typename Description,
int dim,
typename Number>
621 StateVector &state_vector, Number t, Number tau_max)
626 std::cout <<
"TimeIntegrator<dim, Number>::step_strang_erk_43_cn()"
632 hyperbolic_module_->prepare_state_vector(state_vector, t);
633 Number tau = hyperbolic_module_->template step<0>(
634 state_vector, {}, {}, temp_[0], Number(0.), tau_max / 8.);
636 hyperbolic_module_->prepare_state_vector(temp_[0], t + 1.0 * tau);
637 hyperbolic_module_->template step<1>(
638 temp_[0], {{ state_vector}}, {{Number(-1.)}}, temp_[1], tau);
640 hyperbolic_module_->prepare_state_vector(temp_[1], t + 2.0 * tau);
641 hyperbolic_module_->template step<1>(
642 temp_[1], {{temp_[0]}}, {{Number(-1.)}}, temp_[2], tau);
644 hyperbolic_module_->prepare_state_vector(temp_[2], t + 3.0 * tau);
645 hyperbolic_module_->template step<2>(temp_[2],
646 {{temp_[0], temp_[1]}},
647 {{Number(5. / 3.), Number(-10. / 3.)}},
653 parabolic_module_->template step<0>(
654 temp_[3], t, {}, {}, temp_[2], 4.0 * tau);
655 sadd(temp_[2], Number(2.), Number(-1.), temp_[3]);
659 hyperbolic_module_->prepare_state_vector(temp_[2], t + 4.0 * tau);
660 hyperbolic_module_->template step<0>(
661 temp_[2], {}, {}, temp_[0], tau);
663 hyperbolic_module_->prepare_state_vector(temp_[0], t + 5.0 * tau);
664 hyperbolic_module_->template step<1>(
665 temp_[0], {{ temp_[2]}}, {{Number(-1.)}}, temp_[1], tau);
667 hyperbolic_module_->prepare_state_vector(temp_[1], t + 6.0 * tau);
668 hyperbolic_module_->template step<1>(
669 temp_[1], {{temp_[0]}}, {{Number(-1.)}}, temp_[2], tau);
671 hyperbolic_module_->prepare_state_vector(temp_[2], t + 7.0 * tau);
672 hyperbolic_module_->template step<2>(temp_[2],
673 {{temp_[0], temp_[1]}},
674 {{Number(5. / 3.), Number(-10. / 3.)}},
678 state_vector.swap(temp_[3]);
682 template <
typename Description,
int dim,
typename Number>
684 StateVector &state_vector, Number t, Number tau_max)
687 std::cout <<
"TimeIntegrator<dim, Number>::step_imex_11()" << std::endl;
691 hyperbolic_module_->prepare_state_vector(state_vector, t);
692 Number tau = hyperbolic_module_->template step<0>(
693 state_vector, {}, {}, temp_[0], Number(0.), tau_max);
696 parabolic_module_->template step<0>(
697 temp_[0], t, {}, {}, temp_[1], 1.0 * tau);
699 state_vector.swap(temp_[1]);
703 template <
typename Description,
int dim,
typename Number>
705 StateVector &state_vector, Number t, Number tau_max)
708 std::cout <<
"TimeIntegrator<dim, Number>::step_imex_22()" << std::endl;
712 hyperbolic_module_->prepare_state_vector(state_vector, t);
713 Number tau = hyperbolic_module_->template step<0>(
714 state_vector, {}, {}, temp_[0], Number(0.), tau_max / 2.);
717 parabolic_module_->template step<0>(temp_[0], t, {}, {}, temp_[1], tau);
720 hyperbolic_module_->prepare_state_vector(temp_[1], t + 1.0 * tau);
721 hyperbolic_module_->template step<1>(
722 temp_[1], {{state_vector}}, {{Number(-1.)}}, temp_[2], tau);
725 parabolic_module_->template step<1>(temp_[2],
732 state_vector.swap(temp_[3]);
736 template <
typename Description,
int dim,
typename Number>
738 StateVector &state_vector, Number t, Number tau_max)
741 std::cout <<
"TimeIntegrator<dim, Number>::step_imex_33()" << std::endl;
746 const Number gamma = 0.5 + 0.5 * (1. / std::sqrt(3.));
749 hyperbolic_module_->prepare_state_vector(state_vector, t);
750 Number tau = hyperbolic_module_->template step<0>(
751 state_vector, {}, {}, temp_[0], Number(0.), tau_max / 3.);
754 parabolic_module_->template step<1>(temp_[0],
757 {{Number(1. - 3. * gamma)}},
762 hyperbolic_module_->prepare_state_vector(temp_[1], t + 1.0 * tau);
763 hyperbolic_module_->template step<1>(
764 temp_[1], {{state_vector}}, {{Number(-1.)}}, temp_[2], tau);
770 parabolic_module_->template step<2>(
773 {{state_vector, temp_[1]}},
774 {{Number(6. * gamma - 1.), Number(2. - 9 * gamma)}},
779 hyperbolic_module_->prepare_state_vector(temp_[3], t + 2. * tau);
780 hyperbolic_module_->template step<2>(temp_[3],
781 {{state_vector, temp_[1]}},
782 {{Number(0.75), Number(-2.)}},
787 parabolic_module_->template step<3>(temp_[4],
789 {{state_vector, temp_[1], temp_[3]}},
790 {{Number(0.75 - 3. * gamma),
791 Number(6. * gamma - 2.),
792 Number(9. / 4. - 3. * gamma)}},
796 state_vector.swap(temp_[5]);
static constexpr bool is_identity
Number step_imex_33(StateVector &state_vector, Number t, Number tau_max)
TimeIntegrator(const MPIEnsemble &mpi_ensemble, 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_strang_ssprk_33_cn(StateVector &state_vector, Number t, Number tau_max)
Number step_erk_22(StateVector &state_vector, Number t, Number tau_max)
Number step_imex_11(StateVector &state_vector, Number t, Number tau_max)
Number step_strang_erk_43_cn(StateVector &state_vector, Number t, Number tau_max)
Number step_erk_54(StateVector &state_vector, Number t, Number tau_max)
Number step_erk_33(StateVector &state_vector, Number t, Number tau_max)
Number step_erk_43(StateVector &state_vector, Number t, Number tau_max)
Number step_imex_22(StateVector &state_vector, Number t, Number tau_max)
typename View::StateVector StateVector
Number step_erk_11(StateVector &state_vector, Number t, Number tau_max)
Number step_ssprk_22(StateVector &state_vector, Number t, Number tau_max)
Number step_ssprk_33(StateVector &state_vector, Number t, Number tau_max)
Number step(StateVector &state_vector, Number t, Number t_final=std::numeric_limits< Number >::max())
Number step_strang_erk_33_cn(StateVector &state_vector, Number t, Number tau_max)
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)