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,
31 std::map<std::string, dealii::Timer> &computing_timer,
35 const std::string &subsection )
36 : ParameterAcceptor(subsection)
37 , mpi_communicator_(mpi_communicator)
38 , computing_timer_(computing_timer)
39 , offline_data_(&offline_data)
40 , hyperbolic_module_(&hyperbolic_module)
41 , parabolic_module_(¶bolic_module)
43 cfl_min_ = Number(0.45);
47 "Minimal admissible relative CFL constant. How this parameter is used "
48 "depends on the chosen CFL recovery strategy");
50 cfl_max_ = Number(0.90);
54 "Maximal admissible relative CFL constant. How this parameter is used "
55 "depends on the chosen CFL recovery strategy");
58 add_parameter(
"cfl recovery strategy",
59 cfl_recovery_strategy_,
60 "CFL/invariant domain violation recovery strategy: none, "
67 add_parameter(
"time stepping scheme",
68 time_stepping_scheme_,
69 "Time stepping scheme: ssprk 22, ssprk 33, erk 11, erk 22, "
70 "erk 33, erk 43, erk "
71 "54, strang ssprk 33 cn, strang erk 33 cn, strang erk 43 cn");
75 template <
typename Description,
int dim,
typename Number>
79 std::cout <<
"TimeIntegrator<dim, Number>::prepare()" << std::endl;
84 switch (time_stepping_scheme_) {
102 temporary_.resize(3);
106 temporary_.resize(4);
110 temporary_.resize(5);
114 temporary_.resize(3);
118 temporary_.resize(4);
122 temporary_.resize(4);
129 const auto &scalar_partitioner = offline_data_->scalar_partitioner();
130 const auto &vector_partitioner = offline_data_->vector_partitioner();
132 for (
auto &it : temporary_) {
133 auto &[U, precomputed, V] = it;
134 U.reinit(vector_partitioner);
135 precomputed.reinit_with_scalar_partitioner(scalar_partitioner);
140 AssertThrow(cfl_min_ > 0., ExcMessage(
"cfl min must be a positive value"));
141 AssertThrow(cfl_max_ >= cfl_min_,
142 ExcMessage(
"cfl max must be greater than or equal to cfl min"));
144 hyperbolic_module_->cfl(cfl_max_);
146 const auto check_whether_timestepping_makes_sense = [&]() {
151 switch (time_stepping_scheme_) {
168 "The selected equation consists of a hyperbolic and nontrivial "
169 "parabolic subsystem and requires an IMEX timestepping "
170 "scheme such as »strang erk 33 cn«."));
181 "The selected equation has a trivial parabolic subsystem and "
182 "should not be run with an IMEX timestepping scheme."));
188 check_whether_timestepping_makes_sense();
189 this->parse_parameters_call_back.connect(
190 check_whether_timestepping_makes_sense);
194 template <
typename Description,
int dim,
typename Number>
200 std::cout <<
"TimeIntegrator<dim, Number>::step()" << std::endl;
203 const auto single_step = [&]() {
204 switch (time_stepping_scheme_) {
206 return step_ssprk_22(state_vector, t);
208 return step_ssprk_33(state_vector, t);
210 return step_erk_11(state_vector, t);
212 return step_erk_22(state_vector, t);
214 return step_erk_33(state_vector, t);
216 return step_erk_43(state_vector, t);
218 return step_erk_54(state_vector, t);
220 return step_strang_ssprk_33_cn(state_vector, t);
222 return step_strang_erk_33_cn(state_vector, t);
224 return step_strang_erk_43_cn(state_vector, t);
226 __builtin_unreachable();
231 hyperbolic_module_->id_violation_strategy_ =
233 parabolic_module_->id_violation_strategy_ =
235 hyperbolic_module_->cfl(cfl_max_);
239 return single_step();
244 dealii::ExcInternalError());
249 hyperbolic_module_->cfl(cfl_min_);
250 return single_step();
253 __builtin_unreachable();
257 template <
typename Description,
int dim,
typename Number>
264 Number tau = hyperbolic_module_->template step<0>(
265 state_vector, {}, {}, temporary_[0]);
266 hyperbolic_module_->apply_boundary_conditions(temporary_[0], t + tau);
269 hyperbolic_module_->template step<0>(
270 temporary_[0], {}, {}, temporary_[1], tau);
271 sadd(temporary_[1], Number(1. / 2.), Number(1. / 2.), state_vector);
272 hyperbolic_module_->apply_boundary_conditions(temporary_[1], t + tau);
274 state_vector.swap(temporary_[1]);
279 template <
typename Description,
int dim,
typename Number>
286 Number tau = hyperbolic_module_->template step<0>(
287 state_vector, {}, {}, temporary_[0]);
288 hyperbolic_module_->apply_boundary_conditions(temporary_[0], t + tau);
291 hyperbolic_module_->template step<0>(
292 temporary_[0], {}, {}, temporary_[1], tau);
293 sadd(temporary_[1], Number(1. / 4.), Number(3. / 4.), state_vector);
294 hyperbolic_module_->apply_boundary_conditions(temporary_[1], t + 0.5 * tau);
297 hyperbolic_module_->template step<0>(
298 temporary_[1], {}, {}, temporary_[0], tau);
299 sadd(temporary_[0], Number(2. / 3.), Number(1. / 3.), state_vector);
300 hyperbolic_module_->apply_boundary_conditions(temporary_[0], t + tau);
302 state_vector.swap(temporary_[0]);
307 template <
typename Description,
int dim,
typename Number>
312 std::cout <<
"TimeIntegrator<dim, Number>::step_erk_11()" << std::endl;
316 Number tau = hyperbolic_module_->template step<0>(
317 state_vector, {}, {}, temporary_[0]);
318 hyperbolic_module_->apply_boundary_conditions(temporary_[0], t + tau);
320 state_vector.swap(temporary_[0]);
325 template <
typename Description,
int dim,
typename Number>
330 std::cout <<
"TimeIntegrator<dim, Number>::step_erk_22()" << std::endl;
334 Number tau = hyperbolic_module_->template step<0>(
335 state_vector, {}, {}, temporary_[0]);
336 hyperbolic_module_->apply_boundary_conditions(temporary_[0], t + tau);
339 hyperbolic_module_->template step<1>(
340 temporary_[0], {{state_vector}}, {{Number(-1.)}}, temporary_[1], tau);
341 hyperbolic_module_->apply_boundary_conditions(temporary_[1], t + 2. * tau);
343 state_vector.swap(temporary_[1]);
348 template <
typename Description,
int dim,
typename Number>
353 std::cout <<
"TimeIntegrator<dim, Number>::step_erk_33()" << std::endl;
357 Number tau = hyperbolic_module_->template step<0>(
358 state_vector, {}, {}, temporary_[0]);
359 hyperbolic_module_->apply_boundary_conditions(temporary_[0], t + tau);
362 hyperbolic_module_->template step<1>(
363 temporary_[0], {{state_vector}}, {{Number(-1.)}}, temporary_[1], tau);
364 hyperbolic_module_->apply_boundary_conditions(temporary_[1], t + 2. * tau);
367 hyperbolic_module_->template step<2>(temporary_[1],
368 {{state_vector, temporary_[0]}},
369 {{Number(0.75), Number(-2.)}},
372 hyperbolic_module_->apply_boundary_conditions(temporary_[2], t + 3. * tau);
374 state_vector.swap(temporary_[2]);
379 template <
typename Description,
int dim,
typename Number>
384 std::cout <<
"TimeIntegrator<dim, Number>::step_erk_43()" << std::endl;
388 Number tau = hyperbolic_module_->template step<0>(
389 state_vector, {}, {}, temporary_[0]);
390 hyperbolic_module_->apply_boundary_conditions(temporary_[0], t + tau);
393 hyperbolic_module_->template step<1>(
394 temporary_[0], {{state_vector}}, {{Number(-1.)}}, temporary_[1], tau);
395 hyperbolic_module_->apply_boundary_conditions(temporary_[1], t + 2. * tau);
398 hyperbolic_module_->template step<1>(
399 temporary_[1], {{temporary_[0]}}, {{Number(-1.)}}, temporary_[2], tau);
400 hyperbolic_module_->apply_boundary_conditions(temporary_[2], t + 3. * tau);
403 hyperbolic_module_->template step<2>(temporary_[2],
404 {{temporary_[0], temporary_[1]}},
405 {{Number(5. / 3.), Number(-10. / 3.)}},
408 hyperbolic_module_->apply_boundary_conditions(temporary_[3], t + 4. * tau);
410 state_vector.swap(temporary_[3]);
415 template <
typename Description,
int dim,
typename Number>
420 std::cout <<
"TimeIntegrator<dim, Number>::step_erk_54()" << std::endl;
423 constexpr Number c = 0.2;
424 constexpr Number a_21 = +0.2;
425 constexpr Number a_31 = +0.26075582269554909;
426 constexpr Number a_32 = +0.13924417730445096;
427 constexpr Number a_41 = -0.25856517872570289;
428 constexpr Number a_42 = +0.91136274166280729;
429 constexpr Number a_43 = -0.05279756293710430;
430 constexpr Number a_51 = +0.21623276431503774;
431 constexpr Number a_52 = +0.51534223099602405;
432 constexpr Number a_53 = -0.81662794199265554;
433 constexpr Number a_54 = +0.88505294668159373;
434 constexpr Number a_61 = -0.10511678454691901;
435 constexpr Number a_62 = +0.87880047152100838;
436 constexpr Number a_63 = -0.58903404061484477;
437 constexpr Number a_64 = +0.46213380485434047;
441 Number tau = hyperbolic_module_->template step<0>(
442 state_vector, {}, {}, temporary_[0]);
443 hyperbolic_module_->apply_boundary_conditions(temporary_[0], t + tau);
446 hyperbolic_module_->template step<1>(temporary_[0],
448 {{(a_31 - a_21) / c}},
451 hyperbolic_module_->apply_boundary_conditions(temporary_[1], t + 2. * tau);
454 hyperbolic_module_->template step<2>(
456 {{state_vector, temporary_[0]}},
457 {{(a_41 - a_31) / c, (a_42 - a_32) / c}},
460 hyperbolic_module_->apply_boundary_conditions(temporary_[2], t + 3. * tau);
463 hyperbolic_module_->template step<3>(
465 {{state_vector, temporary_[0], temporary_[1]}},
466 {{(a_51 - a_41) / c, (a_52 - a_42) / c, (a_53 - a_43) / c}},
469 hyperbolic_module_->apply_boundary_conditions(temporary_[3], t + 4. * tau);
472 hyperbolic_module_->template step<4>(
474 {{state_vector, temporary_[0], temporary_[1], temporary_[2]}},
481 hyperbolic_module_->apply_boundary_conditions(temporary_[4], t + 5. * tau);
483 state_vector.swap(temporary_[4]);
488 template <
typename Description,
int dim,
typename Number>
495 std::cout <<
"TimeIntegrator<dim, Number>::step_strang_ssprk_33_cn()"
501 Number tau = hyperbolic_module_->template step<0>(
502 state_vector, {}, {}, temporary_[0]);
503 hyperbolic_module_->apply_boundary_conditions(temporary_[0], t + tau);
505 hyperbolic_module_->template step<0>(
506 temporary_[0], {}, {}, temporary_[1], tau);
511 hyperbolic_module_->apply_boundary_conditions(temporary_[1], t + 0.5 * tau);
513 hyperbolic_module_->template step<0>(
514 temporary_[1], {}, {}, temporary_[0], tau);
519 hyperbolic_module_->apply_boundary_conditions(temporary_[0], t + tau);
522 parabolic_module_->template step<0>(
523 temporary_[0], t, {}, {}, temporary_[2], tau);
524 sadd(temporary_[2], Number(2.), Number(-1.), temporary_[0]);
528 hyperbolic_module_->template step<0>(
529 temporary_[2], {}, {}, temporary_[0], tau);
530 hyperbolic_module_->apply_boundary_conditions(temporary_[0], t + 2.0 * tau);
532 hyperbolic_module_->template step<0>(
533 temporary_[0], {}, {}, temporary_[1], tau);
538 hyperbolic_module_->apply_boundary_conditions(temporary_[1], t + 1.5 * tau);
540 hyperbolic_module_->template step<0>(
541 temporary_[1], {}, {}, temporary_[0], tau);
546 hyperbolic_module_->apply_boundary_conditions(temporary_[0], t + 2.0 * tau);
548 state_vector.swap(temporary_[0]);
553 template <
typename Description,
int dim,
typename Number>
560 std::cout <<
"TimeIntegrator<dim, Number>::step_strang_erk_33_cn()"
566 Number tau = hyperbolic_module_->template step<0>(
567 state_vector, {}, {}, temporary_[0]);
568 hyperbolic_module_->apply_boundary_conditions(temporary_[0], t + tau);
570 hyperbolic_module_->template step<1>(temporary_[0],
575 hyperbolic_module_->apply_boundary_conditions(temporary_[1], t + 2. * tau);
577 hyperbolic_module_->template step<2>(
579 {{ state_vector, temporary_[0]}},
580 {{Number(0.75), Number(-2.)}},
583 hyperbolic_module_->apply_boundary_conditions(temporary_[2], t + 3. * tau);
586 parabolic_module_->template step<0>(
587 temporary_[2], t, {}, {}, temporary_[3], 3.0 * tau);
588 sadd(temporary_[3], Number(2.), Number(-1.), temporary_[2]);
592 hyperbolic_module_->template step<0>(
593 temporary_[3], {}, {}, temporary_[0], tau);
594 hyperbolic_module_->apply_boundary_conditions(temporary_[0], t + 4. * tau);
596 hyperbolic_module_->template step<1>(temporary_[0],
601 hyperbolic_module_->apply_boundary_conditions(temporary_[1], t + 5. * tau);
603 hyperbolic_module_->template step<2>(
605 {{ temporary_[3], temporary_[0]}},
606 {{Number(0.75), Number(-2.)}},
609 hyperbolic_module_->apply_boundary_conditions(temporary_[2], t + 6. * tau);
611 state_vector.swap(temporary_[2]);
616 template <
typename Description,
int dim,
typename Number>
623 std::cout <<
"TimeIntegrator<dim, Number>::step_strang_erk_43_cn()"
630 Number tau = hyperbolic_module_->template step<0>(
631 state_vector, {}, {}, temporary_[0]);
632 hyperbolic_module_->apply_boundary_conditions(temporary_[0], t + tau);
635 hyperbolic_module_->template step<1>(temporary_[0],
640 hyperbolic_module_->apply_boundary_conditions(temporary_[1], t + 2. * tau);
643 hyperbolic_module_->template step<1>(
644 temporary_[1], {{temporary_[0]}}, {{Number(-1.)}}, temporary_[2], tau);
645 hyperbolic_module_->apply_boundary_conditions(temporary_[2], t + 3. * tau);
648 hyperbolic_module_->template step<2>(temporary_[2],
649 {{temporary_[0], temporary_[1]}},
650 {{Number(5. / 3.), Number(-10. / 3.)}},
653 hyperbolic_module_->apply_boundary_conditions(temporary_[3], t + 4. * tau);
656 parabolic_module_->template step<0>(
657 temporary_[3], t, {}, {}, temporary_[2], 4.0 * tau);
658 sadd(temporary_[2], Number(2.), Number(-1.), temporary_[3]);
663 hyperbolic_module_->template step<0>(
664 temporary_[2], {}, {}, temporary_[0], tau);
665 hyperbolic_module_->apply_boundary_conditions(temporary_[0], t + 5. * tau);
668 hyperbolic_module_->template step<1>(temporary_[0],
673 hyperbolic_module_->apply_boundary_conditions(temporary_[1], t + 6. * tau);
676 hyperbolic_module_->template step<1>(
677 temporary_[1], {{temporary_[0]}}, {{Number(-1.)}}, temporary_[2], tau);
678 hyperbolic_module_->apply_boundary_conditions(temporary_[2], t + 7. * tau);
681 hyperbolic_module_->template step<2>(temporary_[2],
682 {{temporary_[0], temporary_[1]}},
683 {{Number(5. / 3.), Number(-10. / 3.)}},
686 hyperbolic_module_->apply_boundary_conditions(temporary_[3], t + 8. * tau);
688 state_vector.swap(temporary_[3]);
static constexpr bool is_identity
Number step_ssprk_33(StateVector &state_vector, Number t)
Number step_erk_54(StateVector &state_vector, Number t)
Number step_strang_erk_33_cn(StateVector &state_vector, Number t)
typename View::StateVector StateVector
TimeIntegrator(const MPI_Comm &mpi_communicator, std::map< std::string, dealii::Timer > &computing_timer, 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(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)