12 using namespace dealii;
14 template <
typename StateVector,
typename Number>
18 auto &dst_U = std::get<0>(dst);
19 auto &src_U = std::get<0>(src);
20 dst_U.sadd(s, b, src_U);
22 auto &dst_V = std::get<2>(dst);
23 auto &src_V = std::get<2>(src);
24 dst_V.sadd(s, b, src_V);
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, "
61 if (ParabolicSystem::is_identity)
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_) {
172 ParabolicSystem::is_identity,
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«."));
191 !ParabolicSystem::is_identity,
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_->crank_nicolson_step(temp_[0], t, temp_[2], 2.0 * tau);
546 hyperbolic_module_->prepare_state_vector( temp_[2], t + 1.0 * tau);
547 hyperbolic_module_->template step<0>( temp_[2], {}, {}, temp_[0], tau);
549 hyperbolic_module_->prepare_state_vector(temp_[0], t + 2.0 * tau);
550 hyperbolic_module_->template step<0>(temp_[0], {}, {}, temp_[1], tau);
551 sadd(temp_[1], Number(1.0 / 4.0), Number(3.0 / 4.0), temp_[2]);
553 hyperbolic_module_->prepare_state_vector(temp_[1], t + 1.5 * tau);
554 hyperbolic_module_->template step<0>(temp_[1], {}, {}, temp_[0], tau);
555 sadd(temp_[0], Number(2.0 / 3.0), Number(1.0 / 3.0), temp_[2]);
557 state_vector.swap(temp_[0]);
562 template <
typename Description,
int dim,
typename Number>
564 StateVector &state_vector, Number t, Number tau_max)
569 std::cout <<
"TimeIntegrator<dim, Number>::step_strang_erk_33_cn()"
575 hyperbolic_module_->prepare_state_vector(state_vector, t);
576 Number tau = hyperbolic_module_->template step<0>(
577 state_vector, {}, {}, temp_[0], Number(0.), tau_max / 6.);
579 hyperbolic_module_->prepare_state_vector(temp_[0], t + 1.0 * tau);
580 hyperbolic_module_->template step<1>(
581 temp_[0], {{ state_vector}}, {{Number(-1.)}}, temp_[1], tau);
583 hyperbolic_module_->prepare_state_vector(temp_[1], t + 2.0 * tau);
584 hyperbolic_module_->template step<2>(temp_[1],
585 {{ state_vector, temp_[0]}},
586 {{Number(0.75), Number(-2.)}},
592 parabolic_module_->crank_nicolson_step(temp_[2], t, temp_[3], 6.0 * tau);
596 hyperbolic_module_->prepare_state_vector(temp_[3], t + 3.0 * tau);
597 hyperbolic_module_->template step<0>(
598 temp_[3], {}, {}, temp_[0], tau);
600 hyperbolic_module_->prepare_state_vector(temp_[0], t + 4.0 * tau);
601 hyperbolic_module_->template step<1>(
602 temp_[0], {{ temp_[3]}}, {{Number(-1.)}}, temp_[1], tau);
604 hyperbolic_module_->prepare_state_vector(temp_[1], t + 5.0 * tau);
605 hyperbolic_module_->template step<2>(temp_[1],
606 {{ temp_[3], temp_[0]}},
607 {{Number(0.75), Number(-2.)}},
611 state_vector.swap(temp_[2]);
616 template <
typename Description,
int dim,
typename Number>
618 StateVector &state_vector, Number t, Number tau_max)
623 std::cout <<
"TimeIntegrator<dim, Number>::step_strang_erk_43_cn()"
629 hyperbolic_module_->prepare_state_vector(state_vector, t);
630 Number tau = hyperbolic_module_->template step<0>(
631 state_vector, {}, {}, temp_[0], Number(0.), tau_max / 8.);
633 hyperbolic_module_->prepare_state_vector(temp_[0], t + 1.0 * tau);
634 hyperbolic_module_->template step<1>(
635 temp_[0], {{ state_vector}}, {{Number(-1.)}}, temp_[1], tau);
637 hyperbolic_module_->prepare_state_vector(temp_[1], t + 2.0 * tau);
638 hyperbolic_module_->template step<1>(
639 temp_[1], {{temp_[0]}}, {{Number(-1.)}}, temp_[2], tau);
641 hyperbolic_module_->prepare_state_vector(temp_[2], t + 3.0 * tau);
642 hyperbolic_module_->template step<2>(temp_[2],
643 {{temp_[0], temp_[1]}},
644 {{Number(5. / 3.), Number(-10. / 3.)}},
650 parabolic_module_->crank_nicolson_step(temp_[3], t, temp_[2], 8.0 * tau);
654 hyperbolic_module_->prepare_state_vector(temp_[2], t + 4.0 * tau);
655 hyperbolic_module_->template step<0>(
656 temp_[2], {}, {}, temp_[0], tau);
658 hyperbolic_module_->prepare_state_vector(temp_[0], t + 5.0 * tau);
659 hyperbolic_module_->template step<1>(
660 temp_[0], {{ temp_[2]}}, {{Number(-1.)}}, temp_[1], tau);
662 hyperbolic_module_->prepare_state_vector(temp_[1], t + 6.0 * tau);
663 hyperbolic_module_->template step<1>(
664 temp_[1], {{temp_[0]}}, {{Number(-1.)}}, temp_[2], tau);
666 hyperbolic_module_->prepare_state_vector(temp_[2], t + 7.0 * tau);
667 hyperbolic_module_->template step<2>(temp_[2],
668 {{temp_[0], temp_[1]}},
669 {{Number(5. / 3.), Number(-10. / 3.)}},
673 state_vector.swap(temp_[3]);
677 template <
typename Description,
int dim,
typename Number>
679 StateVector &state_vector, Number t, Number tau_max)
682 std::cout <<
"TimeIntegrator<dim, Number>::step_imex_11()" << std::endl;
686 hyperbolic_module_->prepare_state_vector(state_vector, t);
687 Number tau = hyperbolic_module_->template step<0>(
688 state_vector, {}, {}, temp_[0], Number(0.), tau_max);
691 parabolic_module_->template backward_euler_step<0>(
692 temp_[0], t, {}, {}, temp_[1], 1.0 * tau);
694 state_vector.swap(temp_[1]);
698 template <
typename Description,
int dim,
typename Number>
700 StateVector &state_vector, Number t, Number tau_max)
703 std::cout <<
"TimeIntegrator<dim, Number>::step_imex_22()" << std::endl;
707 hyperbolic_module_->prepare_state_vector(state_vector, t);
708 Number tau = hyperbolic_module_->template step<0>(
709 state_vector, {}, {}, temp_[0], Number(0.), tau_max / 2.);
712 parabolic_module_->template backward_euler_step<0>(
713 temp_[0], t, {}, {}, temp_[1], tau);
716 hyperbolic_module_->prepare_state_vector(temp_[1], t + 1.0 * tau);
717 hyperbolic_module_->template step<1>(
718 temp_[1], {{state_vector}}, {{Number(-1.)}}, temp_[2], tau);
721 parabolic_module_->template backward_euler_step<1>(temp_[2],
728 state_vector.swap(temp_[3]);
732 template <
typename Description,
int dim,
typename Number>
734 StateVector &state_vector, Number t, Number tau_max)
737 std::cout <<
"TimeIntegrator<dim, Number>::step_imex_33()" << std::endl;
742 const Number gamma = 0.5 + 0.5 * std::numbers::inv_sqrt3;
745 hyperbolic_module_->prepare_state_vector(state_vector, t);
746 Number tau = hyperbolic_module_->template step<0>(
747 state_vector, {}, {}, temp_[0], Number(0.), tau_max / 3.);
750 parabolic_module_->template backward_euler_step<1>(
754 {{Number(1. - 3. * gamma)}},
759 hyperbolic_module_->prepare_state_vector(temp_[1], t + 1.0 * tau);
760 hyperbolic_module_->template step<1>(
761 temp_[1], {{state_vector}}, {{Number(-1.)}}, temp_[2], tau);
767 parabolic_module_->template backward_euler_step<2>(
770 {{state_vector, temp_[1]}},
771 {{Number(6. * gamma - 1.), Number(2. - 9 * gamma)}},
776 hyperbolic_module_->prepare_state_vector(temp_[3], t + 2. * tau);
777 hyperbolic_module_->template step<2>(temp_[3],
778 {{state_vector, temp_[1]}},
779 {{Number(0.75), Number(-2.)}},
784 parabolic_module_->template backward_euler_step<3>(
787 {{state_vector, temp_[1], temp_[3]}},
788 {{Number(0.75 - 3. * gamma),
789 Number(6. * gamma - 2.),
790 Number(9. / 4. - 3. * gamma)}},
794 state_vector.swap(temp_[5]);
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)