deal.II version GIT relicensing-6842-g793a97d2aa 2026-10-02 14:00:01+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
arkode_stepper.h
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2026 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15
16#ifndef dealii_sundials_arkode_stepper_h
17#define dealii_sundials_arkode_stepper_h
18
19#include <deal.II/base/config.h>
20
21
22#ifdef DEAL_II_WITH_SUNDIALS
23
28
29# ifdef DEAL_II_WITH_PETSC
32# endif
33# include <deal.II/lac/vector.h>
35
36# include <arkode/arkode.h>
37# include <nvector/nvector_serial.h>
38# ifdef DEAL_II_WITH_MPI
39# include <nvector/nvector_parallel.h>
40# endif
42
47
48# include <boost/signals2.hpp>
49
50# include <sundials/sundials_linearsolver.h>
51# include <sundials/sundials_math.h>
52
53# include <complex>
54# include <exception>
55# include <memory>
56# include <string>
57
58#endif // DEAL_II_WITH_SUNDIALS
59
61
62#ifdef DEAL_II_WITH_SUNDIALS
63
64namespace SUNDIALS
65{
69 template <typename VectorType>
70 class ARKode;
71
82 template <typename VectorType>
84 {
85 public:
90 friend class ARKode<VectorType>;
91
96 virtual ~ARKodeStepper() = default;
97
114 virtual void *
115 get_arkode_memory() const = 0;
116
117 private:
133 virtual void
134 reinit(double t0,
135 const VectorType &y0,
136 internal::InvocationContext inv_ctx) = 0;
137
138 protected:
144 template <typename Stepper>
146 {
147 Stepper *stepper = nullptr;
148 std::exception_ptr *pending_exception = nullptr;
149 };
150
158 using ARKodeMemoryPtr = std::unique_ptr<void, void (*)(void *)>;
159 };
160
400 template <typename VectorType = Vector<double>>
401 class ARKStepper : public ARKodeStepper<VectorType>
402 {
403 public:
408 {
409 public:
455 explicit AdditionalData(
456 const unsigned int order = 0,
457 const unsigned int maximum_non_linear_iterations = 10,
458 const bool implicit_function_is_linear = false,
459 const bool implicit_function_is_time_independent = false,
460 const bool mass_is_time_independent = false,
461 const int anderson_acceleration_subspace = 3,
462 const std::string &implicit_butcher_table = "",
463 const std::string &explicit_butcher_table = "");
464
479 void
481
490 unsigned int order;
491
497
502
508
514
520
531
542 };
543
550
551 void *
552 get_arkode_memory() const override;
553
570 std::function<
571 void(const double t, const VectorType &y, VectorType &explicit_f)>
573
590 std::function<void(const double t, const VectorType &y, VectorType &res)>
592
611 std::function<void(const double t, const VectorType &v, VectorType &Mv)>
613
648 std::function<void(const double t)> mass_times_vector_setup;
649
676 std::function<void(const VectorType &v,
677 VectorType &Jv,
678 const double t,
679 const VectorType &y,
680 const VectorType &fy)>
682
718 std::function<
719 void(const double t, const VectorType &y, const VectorType &fy)>
721
749
773
805 std::function<void(const double t,
806 const VectorType &y,
807 const VectorType &fy,
808 const VectorType &r,
809 VectorType &z,
810 const double gamma,
811 const double tol,
812 const int lr)>
814
857 std::function<void(const double t,
858 const VectorType &y,
859 const VectorType &fy,
860 const int jok,
861 int &jcur,
862 const double gamma)>
864
892 std::function<void(const double t,
893 const VectorType &r,
894 VectorType &z,
895 const double tol,
896 const int lr)>
898
923 std::function<void(const double t)> mass_preconditioner_setup;
924
950 std::function<void(void *arkode_mem)> custom_setup;
951
952 private:
954 VectorType>::template CallbackContext<ARKStepper<VectorType>>;
955
957
968 void
969 reinit(double t0,
970 const VectorType &y0,
971 internal::InvocationContext inv_ctx) override;
972
982 void
983 setup_system_solver(const VectorType &solution,
985
996 void
997 setup_mass_solver(const VectorType &solution,
999
1004
1010 std::unique_ptr<internal::LinearSolverWrapper<VectorType>> linear_solver;
1011
1016 std::unique_ptr<internal::LinearSolverWrapper<VectorType>> mass_solver;
1017
1025
1030 };
1031
1032
1033 template <typename VectorType>
1035 const unsigned int order,
1036 const unsigned int maximum_non_linear_iterations,
1037 const bool implicit_function_is_linear,
1038 const bool implicit_function_is_time_independent,
1039 const bool mass_is_time_independent,
1040 const int anderson_acceleration_subspace,
1041 const std::string &implicit_butcher_table,
1042 const std::string &explicit_butcher_table)
1043 : order(order)
1044 , maximum_non_linear_iterations(maximum_non_linear_iterations)
1045 , implicit_function_is_linear(implicit_function_is_linear)
1046 , implicit_function_is_time_independent(
1047 implicit_function_is_time_independent)
1048 , mass_is_time_independent(mass_is_time_independent)
1049 , anderson_acceleration_subspace(anderson_acceleration_subspace)
1050 , implicit_butcher_table(implicit_butcher_table)
1051 , explicit_butcher_table(explicit_butcher_table)
1052 {}
1053
1054
1055
1056 template <typename VectorType>
1057 void
1059 {
1060 prm.add_parameter("Integration accuracy order", order);
1061 prm.add_parameter("Maximum number of nonlinear iterations",
1062 maximum_non_linear_iterations);
1063 prm.add_parameter("Implicit function is linear",
1064 implicit_function_is_linear);
1065 prm.add_parameter("Implicit function is time independent",
1066 implicit_function_is_time_independent);
1067 prm.add_parameter("Mass is time independent", mass_is_time_independent);
1068 prm.add_parameter("Anderson-acceleration subspace",
1069 anderson_acceleration_subspace);
1070 prm.add_parameter("Implicit Butcher table", implicit_butcher_table);
1071 prm.add_parameter("Explicit Butcher table", explicit_butcher_table);
1072 }
1073
1074
1144 template <typename VectorType = Vector<double>>
1145 class ERKStepper : public ARKodeStepper<VectorType>
1146 {
1147 public:
1156 {
1157 public:
1170 AdditionalData(const unsigned int order = 0,
1171 const std::string &explicit_butcher_table = "");
1172
1187 void
1188 add_parameters(ParameterHandler &prm);
1189
1198 unsigned int order;
1199
1209 };
1210
1217
1218 void *
1219 get_arkode_memory() const override;
1220
1232 std::function<
1233 void(const double t, const VectorType &y, VectorType &explicit_f)>
1235
1261 std::function<void(void *arkode_mem)> custom_setup;
1262
1263 private:
1265 VectorType>::template CallbackContext<ERKStepper<VectorType>>;
1266
1268
1279 void
1280 reinit(double t0,
1281 const VectorType &y0,
1282 internal::InvocationContext inv_ctx) override;
1283
1288
1293
1298 };
1299
1300
1301 template <typename VectorType>
1303 const unsigned int order,
1304 const std::string &explicit_butcher_table)
1305 : order(order)
1306 , explicit_butcher_table(explicit_butcher_table)
1307 {}
1308
1309
1310
1311 template <typename VectorType>
1312 void
1314 {
1315 prm.add_parameter("Integration accuracy order", order);
1316 prm.add_parameter("Explicit Butcher table", explicit_butcher_table);
1317 }
1318
1319
1320# if DEAL_II_SUNDIALS_VERSION_GTE(7, 2, 0)
1321
1371 template <typename VectorType = Vector<double>>
1372 class LSRKStepperSTS : public ARKodeStepper<VectorType>
1373 {
1374 public:
1379 {
1380 public:
1417 const std::string &method_name = "",
1418 const unsigned int dom_eig_frequency = numbers::invalid_unsigned_int,
1419 const unsigned int max_num_stages = 0,
1420 const unsigned int dom_eig_estimator_max_iters = 0,
1421 const double dom_eig_estimator_rel_tol = 0,
1422 const unsigned int dom_eig_estimator_num_warmups =
1424 : method_name(method_name)
1425 , dom_eig_frequency(dom_eig_frequency)
1426 , max_num_stages(max_num_stages)
1427 , dom_eig_estimator_max_iters(dom_eig_estimator_max_iters)
1428 , dom_eig_estimator_rel_tol(dom_eig_estimator_rel_tol)
1429 , dom_eig_estimator_num_warmups(dom_eig_estimator_num_warmups)
1430 {}
1431
1437 void
1438 add_parameters(ParameterHandler &prm);
1439
1444 std::string method_name;
1445
1454 unsigned int dom_eig_frequency;
1455
1460 unsigned int max_num_stages;
1461
1470
1479
1489 };
1490
1497
1498 void *
1499 get_arkode_memory() const override;
1500
1512 std::function<
1513 void(const double t, const VectorType &y, VectorType &explicit_f)>
1515
1543 std::function<std::complex<double>(const double t,
1544 const VectorType &y,
1545 const VectorType &f)>
1547
1562 std::function<void(void *arkode_mem)> custom_setup;
1563
1564 private:
1566 VectorType>::template CallbackContext<LSRKStepperSTS<VectorType>>;
1567
1569
1580 void
1581 reinit(double t0,
1582 const VectorType &y0,
1583 internal::InvocationContext inv_ctx) override;
1584
1589
1590# if DEAL_II_SUNDIALS_VERSION_GTE(7, 5, 0)
1599 std::unique_ptr<void, void (*)(void *)> dom_eig_estimator;
1600# endif
1601
1606
1611 };
1612
1613
1614 template <typename VectorType>
1615 void
1617 ParameterHandler &prm)
1618 {
1619 prm.add_parameter(
1620 "Method name",
1621 method_name,
1622 "STS method name passed to LSRKStepSetSTSMethodByName. "
1623 "If empty, SUNDIALS uses the default (ARKODE_LSRK_RKC_2).");
1624 prm.add_parameter(
1625 "Dominant eigenvalue recomputation frequency",
1626 dom_eig_frequency,
1627 "Number of successful steps after which the dominant eigenvalue "
1628 "estimate is recomputed. 0 means constant dominant eigenvalue "
1629 "(no change throughout the simulation). Any negative value leaves "
1630 "this option at the SUNDIALS default of 25.");
1631 prm.add_parameter("Maximum number of stages",
1632 max_num_stages,
1633 "Maximum number of polynomial stages per time step. "
1634 "0 means no limit.");
1635 prm.add_parameter(
1636 "Dominant eigenvalue estimator maximum iterations",
1637 dom_eig_estimator_max_iters,
1638 "Maximum number of power iterations performed by the built-in "
1639 "dominant-eigenvalue estimator. Only used when no dominant eigenvalue "
1640 "function is provided.");
1641 prm.add_parameter(
1642 "Dominant eigenvalue estimator relative tolerance",
1643 dom_eig_estimator_rel_tol,
1644 "Relative convergence tolerance of the power iteration used by the "
1645 "built-in dominant-eigenvalue estimator. Only used when no dominant "
1646 "eigenvalue function is provided.");
1647 prm.add_parameter(
1648 "Dominant eigenvalue estimator warmup iterations",
1649 dom_eig_estimator_num_warmups,
1650 "Number of preprocessing warmup iterations performed once when the "
1651 "built-in dominant-eigenvalue estimator is first initialized. Only used "
1652 "when no dominant eigenvalue function is provided.");
1653 }
1654
1655
1683 template <typename VectorType = Vector<double>>
1684 class LSRKStepperSSP : public ARKodeStepper<VectorType>
1685 {
1686 public:
1691 {
1692 public:
1705 AdditionalData(const std::string &method_name = "",
1706 const unsigned int num_stages = 0)
1707 : method_name(method_name)
1708 , num_stages(num_stages)
1709 {}
1710
1716 void
1717 add_parameters(ParameterHandler &prm);
1718
1723 std::string method_name;
1724
1730 unsigned int num_stages;
1731 };
1732
1739
1740 void *
1741 get_arkode_memory() const override;
1742
1754 std::function<
1755 void(const double t, const VectorType &y, VectorType &explicit_f)>
1757
1772 std::function<void(void *arkode_mem)> custom_setup;
1773
1774 private:
1776 VectorType>::template CallbackContext<LSRKStepperSSP<VectorType>>;
1777
1779
1790 void
1791 reinit(double t0,
1792 const VectorType &y0,
1793 internal::InvocationContext inv_ctx) override;
1794
1799
1804
1809 };
1810
1811
1812 template <typename VectorType>
1813 void
1815 ParameterHandler &prm)
1816 {
1817 prm.add_parameter(
1818 "Method name",
1819 method_name,
1820 "SSP method name passed to LSRKStepSetSSPMethodByName. "
1821 "If empty, SUNDIALS uses the default (ARKODE_LSRK_SSP_10_4).");
1822 prm.add_parameter("Number of SSP stages",
1823 num_stages,
1824 "Number of stages for variable-stage SSP methods "
1825 "(ARKODE_LSRK_SSP_S_2, ARKODE_LSRK_SSP_S_3). "
1826 "0 means SUNDIALS default.");
1827 }
1828
1829# endif // DEAL_II_SUNDIALS_VERSION_GTE(7, 2, 0)
1830
1831} // namespace SUNDIALS
1832
1833#endif // DEAL_II_WITH_SUNDIALS
1834
1836
1837#endif
void add_parameter(const std::string &entry, ParameterType &parameter, const std::string &documentation="", const Patterns::PatternBase &pattern= *Patterns::Tools::Convert< ParameterType >::to_pattern(), const bool has_to_be_set=false)
void add_parameters(ParameterHandler &prm)
AdditionalData(const unsigned int order=0, const unsigned int maximum_non_linear_iterations=10, const bool implicit_function_is_linear=false, const bool implicit_function_is_time_independent=false, const bool mass_is_time_independent=false, const int anderson_acceleration_subspace=3, const std::string &implicit_butcher_table="", const std::string &explicit_butcher_table="")
void setup_mass_solver(const VectorType &solution, internal::InvocationContext inv_ctx)
std::unique_ptr< internal::LinearSolverWrapper< VectorType > > mass_solver
std::function< void(void *arkode_mem)> custom_setup
std::unique_ptr< internal::LinearSolverWrapper< VectorType > > linear_solver
void reinit(double t0, const VectorType &y0, internal::InvocationContext inv_ctx) override
std::function< void(const double t, const VectorType &y, VectorType &res)> implicit_function
std::function< void(const double t)> mass_times_vector_setup
ARKStepper(const AdditionalData &data=AdditionalData())
CallbackContext callback_ctx
typename ARKodeStepper< VectorType >::template CallbackContext< ARKStepper< VectorType > > CallbackContext
void setup_system_solver(const VectorType &solution, internal::InvocationContext inv_ctx)
std::function< void(const double t)> mass_preconditioner_setup
std::function< void(const double t, const VectorType &y, VectorType &explicit_f)> explicit_function
std::function< void(const double t, const VectorType &v, VectorType &Mv)> mass_times_vector
std::function< void(const double t, const VectorType &y, const VectorType &fy)> jacobian_times_vector_setup
ARKodeMemoryPtr arkode_mem
std::function< void(const double t, const VectorType &y, const VectorType &fy, const VectorType &r, VectorType &z, const double gamma, const double tol, const int lr)> jacobian_preconditioner_solve
std::function< void(const double t, const VectorType &r, VectorType &z, const double tol, const int lr)> mass_preconditioner_solve
typename ARKodeStepper< VectorType >::ARKodeMemoryPtr ARKodeMemoryPtr
LinearSolveFunction< VectorType > solve_linearized_system
LinearSolveFunction< VectorType > solve_mass
std::function< void(const VectorType &v, VectorType &Jv, const double t, const VectorType &y, const VectorType &fy)> jacobian_times_vector
std::function< void(const double t, const VectorType &y, const VectorType &fy, const int jok, int &jcur, const double gamma)> jacobian_preconditioner_setup
void * get_arkode_memory() const override
virtual ~ARKodeStepper()=default
virtual void reinit(double t0, const VectorType &y0, internal::InvocationContext inv_ctx)=0
std::unique_ptr< void, void(*)(void *)> ARKodeMemoryPtr
virtual void * get_arkode_memory() const =0
AdditionalData(const unsigned int order=0, const std::string &explicit_butcher_table="")
void add_parameters(ParameterHandler &prm)
void reinit(double t0, const VectorType &y0, internal::InvocationContext inv_ctx) override
CallbackContext callback_ctx
ARKodeMemoryPtr arkode_mem
void * get_arkode_memory() const override
std::function< void(void *arkode_mem)> custom_setup
ERKStepper(const AdditionalData &data=AdditionalData())
typename ARKodeStepper< VectorType >::ARKodeMemoryPtr ARKodeMemoryPtr
typename ARKodeStepper< VectorType >::template CallbackContext< ERKStepper< VectorType > > CallbackContext
std::function< void(const double t, const VectorType &y, VectorType &explicit_f)> explicit_function
void add_parameters(ParameterHandler &prm)
AdditionalData(const std::string &method_name="", const unsigned int num_stages=0)
LSRKStepperSSP(const AdditionalData &data=AdditionalData())
std::function< void(const double t, const VectorType &y, VectorType &explicit_f)> explicit_function
void * get_arkode_memory() const override
typename ARKodeStepper< VectorType >::template CallbackContext< LSRKStepperSSP< VectorType > > CallbackContext
std::function< void(void *arkode_mem)> custom_setup
void reinit(double t0, const VectorType &y0, internal::InvocationContext inv_ctx) override
typename ARKodeStepper< VectorType >::ARKodeMemoryPtr ARKodeMemoryPtr
AdditionalData(const std::string &method_name="", const unsigned int dom_eig_frequency=numbers::invalid_unsigned_int, const unsigned int max_num_stages=0, const unsigned int dom_eig_estimator_max_iters=0, const double dom_eig_estimator_rel_tol=0, const unsigned int dom_eig_estimator_num_warmups=numbers::invalid_unsigned_int)
void add_parameters(ParameterHandler &prm)
std::function< void(const double t, const VectorType &y, VectorType &explicit_f)> explicit_function
typename ARKodeStepper< VectorType >::ARKodeMemoryPtr ARKodeMemoryPtr
LSRKStepperSTS(const AdditionalData &data=AdditionalData())
std::function< std::complex< double >(const double t, const VectorType &y, const VectorType &f)> dominant_eigenvalue_function
std::function< void(void *arkode_mem)> custom_setup
void * get_arkode_memory() const override
void reinit(double t0, const VectorType &y0, internal::InvocationContext inv_ctx) override
typename ARKodeStepper< VectorType >::template CallbackContext< LSRKStepperSTS< VectorType > > CallbackContext
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
std::vector< index_type > data
Definition mpi.cc:734
std::function< void(SundialsOperator< VectorType > &op, SundialsPreconditioner< VectorType > &prec, VectorType &x, const VectorType &b, double tol)> LinearSolveFunction
constexpr unsigned int invalid_unsigned_int
Definition types.h:228