deal.II version GIT relicensing-7058-gb35ee29762 2026-11-11 09:30: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: Apache-2.0 WITH LLVM-exception OR 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// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13
14#ifndef dealii_sundials_arkode_stepper_h
15#define dealii_sundials_arkode_stepper_h
16
17#include <deal.II/base/config.h>
18
19
20#ifdef DEAL_II_WITH_SUNDIALS
21
26
27# ifdef DEAL_II_WITH_PETSC
30# endif
31# include <deal.II/lac/vector.h>
33
34# include <arkode/arkode.h>
35# include <nvector/nvector_serial.h>
36# ifdef DEAL_II_WITH_MPI
37# include <nvector/nvector_parallel.h>
38# endif
40
46
47# include <boost/signals2.hpp>
48
49# include <sundials/sundials_linearsolver.h>
50# include <sundials/sundials_math.h>
51# include <sundials/sundials_nonlinearsolver.h>
52
53# include <complex>
54# include <exception>
55# include <memory>
56# include <optional>
57# include <string>
58
59#endif // DEAL_II_WITH_SUNDIALS
60
62
63#ifdef DEAL_II_WITH_SUNDIALS
64
65namespace SUNDIALS
66{
70 template <typename VectorType>
71 class ARKode;
72
83 template <typename VectorType>
85 {
86 public:
91 friend class ARKode<VectorType>;
92
97 virtual ~ARKodeStepper() = default;
98
115 virtual void *
116 get_arkode_memory() const = 0;
117
118 private:
127 void
128 attach(std::exception_ptr &pending_exception
130 ,
131 const internal::SharedSUNContext &context
132# endif
133 )
134 {
135 Assert(pending_exception_ptr == nullptr,
136 ExcMessage("This stepper is already attached to an ARKode "
137 "object."));
138 pending_exception_ptr = &pending_exception;
139# if DEAL_II_SUNDIALS_VERSION_GTE(6, 0, 0)
140 sundials_context = context;
141# endif
142 }
143
152 virtual void
153 reinit(double t0, const VectorType &y0) = 0;
154
165 virtual void
166 resize(double t0, const VectorType &y0, double hscale) = 0;
167
168 protected:
174 template <typename Stepper>
176 {
177 Stepper *stepper = nullptr;
178 std::exception_ptr *pending_exception = nullptr;
179 };
180
188 using ARKodeMemoryPtr = std::unique_ptr<void, void (*)(void *)>;
189
197 {
198 Assert(pending_exception_ptr != nullptr,
199 ExcMessage("This stepper is not attached to an ARKode object."));
201 {
203# if DEAL_II_SUNDIALS_VERSION_GTE(6, 0, 0)
204 ,
206# endif
207 };
208 }
209
210 private:
214 std::exception_ptr *pending_exception_ptr = nullptr;
215
216# if DEAL_II_SUNDIALS_VERSION_GTE(6, 0, 0)
223# endif
224 };
225
465 template <typename VectorType = Vector<double>>
466 class ARKStepper : public ARKodeStepper<VectorType>
467 {
468 public:
473 {
474 public:
520 explicit AdditionalData(
521 const unsigned int order = 0,
522 const unsigned int maximum_non_linear_iterations = 10,
523 const bool implicit_function_is_linear = false,
524 const bool implicit_function_is_time_independent = false,
525 const bool mass_is_time_independent = false,
526 const int anderson_acceleration_subspace = 3,
527 const std::string &implicit_butcher_table = "",
528 const std::string &explicit_butcher_table = "");
529
544 void
546
555 unsigned int order;
556
562
567
573
579
585
596
607 };
608
615
616 void *
617 get_arkode_memory() const override;
618
635 std::function<
636 void(const double t, const VectorType &y, VectorType &explicit_f)>
638
655 std::function<void(const double t, const VectorType &y, VectorType &res)>
657
676 std::function<void(const double t, const VectorType &v, VectorType &Mv)>
678
713 std::function<void(const double t)> mass_times_vector_setup;
714
741 std::function<void(const VectorType &v,
742 VectorType &Jv,
743 const double t,
744 const VectorType &y,
745 const VectorType &fy)>
747
783 std::function<
784 void(const double t, const VectorType &y, const VectorType &fy)>
786
814
838
870 std::function<void(const double t,
871 const VectorType &y,
872 const VectorType &fy,
873 const VectorType &r,
874 VectorType &z,
875 const double gamma,
876 const double tol,
877 const int lr)>
879
922 std::function<void(const double t,
923 const VectorType &y,
924 const VectorType &fy,
925 const int jok,
926 int &jcur,
927 const double gamma)>
929
957 std::function<void(const double t,
958 const VectorType &r,
959 VectorType &z,
960 const double tol,
961 const int lr)>
963
988 std::function<void(const double t)> mass_preconditioner_setup;
989
1015 std::function<void(void *arkode_mem)> custom_setup;
1016
1017 private:
1019 VectorType>::template CallbackContext<ARKStepper<VectorType>>;
1020
1022
1031 void
1032 reinit(double t0, const VectorType &y0) override;
1033
1044 void
1045 resize(double t0, const VectorType &y0, double hscale) override;
1046
1054 void
1055 setup_system_solver(const VectorType &solution);
1056
1065 void
1066 setup_mass_solver(const VectorType &solution);
1067
1072
1078 std::optional<internal::LinearSolverWrapper<VectorType>> linear_solver;
1079
1084 std::optional<internal::LinearSolverWrapper<VectorType>> mass_solver;
1085
1091 std::optional<internal::SundialsLinearSolver> default_linear_solver;
1092
1097 std::optional<internal::SundialsLinearSolver> default_mass_solver;
1098
1103 std::optional<internal::SundialsNonlinearSolver> fixed_point_solver;
1104
1111
1116 };
1117
1118
1119 template <typename VectorType>
1121 const unsigned int order,
1122 const unsigned int maximum_non_linear_iterations,
1123 const bool implicit_function_is_linear,
1124 const bool implicit_function_is_time_independent,
1125 const bool mass_is_time_independent,
1126 const int anderson_acceleration_subspace,
1127 const std::string &implicit_butcher_table,
1128 const std::string &explicit_butcher_table)
1129 : order(order)
1130 , maximum_non_linear_iterations(maximum_non_linear_iterations)
1131 , implicit_function_is_linear(implicit_function_is_linear)
1132 , implicit_function_is_time_independent(
1133 implicit_function_is_time_independent)
1134 , mass_is_time_independent(mass_is_time_independent)
1135 , anderson_acceleration_subspace(anderson_acceleration_subspace)
1136 , implicit_butcher_table(implicit_butcher_table)
1137 , explicit_butcher_table(explicit_butcher_table)
1138 {}
1139
1140
1141
1142 template <typename VectorType>
1143 void
1145 {
1146 prm.add_parameter("Integration accuracy order", order);
1147 prm.add_parameter("Maximum number of nonlinear iterations",
1148 maximum_non_linear_iterations);
1149 prm.add_parameter("Implicit function is linear",
1150 implicit_function_is_linear);
1151 prm.add_parameter("Implicit function is time independent",
1152 implicit_function_is_time_independent);
1153 prm.add_parameter("Mass is time independent", mass_is_time_independent);
1154 prm.add_parameter("Anderson-acceleration subspace",
1155 anderson_acceleration_subspace);
1156 prm.add_parameter("Implicit Butcher table", implicit_butcher_table);
1157 prm.add_parameter("Explicit Butcher table", explicit_butcher_table);
1158 }
1159
1160
1230 template <typename VectorType = Vector<double>>
1231 class ERKStepper : public ARKodeStepper<VectorType>
1232 {
1233 public:
1242 {
1243 public:
1256 AdditionalData(const unsigned int order = 0,
1257 const std::string &explicit_butcher_table = "");
1258
1273 void
1274 add_parameters(ParameterHandler &prm);
1275
1284 unsigned int order;
1285
1295 };
1296
1303
1304 void *
1305 get_arkode_memory() const override;
1306
1318 std::function<
1319 void(const double t, const VectorType &y, VectorType &explicit_f)>
1321
1347 std::function<void(void *arkode_mem)> custom_setup;
1348
1349 private:
1351 VectorType>::template CallbackContext<ERKStepper<VectorType>>;
1352
1354
1363 void
1364 reinit(double t0, const VectorType &y0) override;
1365
1374 void
1375 resize(double t0, const VectorType &y0, double hscale) override;
1376
1381
1386
1391 };
1392
1393
1394 template <typename VectorType>
1396 const unsigned int order,
1397 const std::string &explicit_butcher_table)
1398 : order(order)
1399 , explicit_butcher_table(explicit_butcher_table)
1400 {}
1401
1402
1403
1404 template <typename VectorType>
1405 void
1407 {
1408 prm.add_parameter("Integration accuracy order", order);
1409 prm.add_parameter("Explicit Butcher table", explicit_butcher_table);
1410 }
1411
1412
1413# if DEAL_II_SUNDIALS_VERSION_GTE(7, 2, 0)
1414
1464 template <typename VectorType = Vector<double>>
1465 class LSRKStepperSTS : public ARKodeStepper<VectorType>
1466 {
1467 public:
1472 {
1473 public:
1510 const std::string &method_name = "",
1511 const unsigned int dom_eig_frequency = numbers::invalid_unsigned_int,
1512 const unsigned int max_num_stages = 0,
1513 const unsigned int dom_eig_estimator_max_iters = 0,
1514 const double dom_eig_estimator_rel_tol = 0,
1515 const unsigned int dom_eig_estimator_num_warmups =
1517 : method_name(method_name)
1518 , dom_eig_frequency(dom_eig_frequency)
1519 , max_num_stages(max_num_stages)
1520 , dom_eig_estimator_max_iters(dom_eig_estimator_max_iters)
1521 , dom_eig_estimator_rel_tol(dom_eig_estimator_rel_tol)
1522 , dom_eig_estimator_num_warmups(dom_eig_estimator_num_warmups)
1523 {}
1524
1530 void
1531 add_parameters(ParameterHandler &prm);
1532
1537 std::string method_name;
1538
1547 unsigned int dom_eig_frequency;
1548
1553 unsigned int max_num_stages;
1554
1563
1572
1582 };
1583
1590
1591 void *
1592 get_arkode_memory() const override;
1593
1605 std::function<
1606 void(const double t, const VectorType &y, VectorType &explicit_f)>
1608
1636 std::function<std::complex<double>(const double t,
1637 const VectorType &y,
1638 const VectorType &f)>
1640
1655 std::function<void(void *arkode_mem)> custom_setup;
1656
1657 private:
1659 VectorType>::template CallbackContext<LSRKStepperSTS<VectorType>>;
1660
1662
1671 void
1672 reinit(double t0, const VectorType &y0) override;
1673
1684 void
1685 resize(double t0, const VectorType &y0, double hscale) override;
1686
1687# if DEAL_II_SUNDIALS_VERSION_GTE(7, 5, 0)
1693 void
1695# endif
1696
1701
1702# if DEAL_II_SUNDIALS_VERSION_GTE(7, 5, 0)
1711 std::unique_ptr<void, void (*)(void *)> dom_eig_estimator;
1712# endif
1713
1718
1723 };
1724
1725
1726 template <typename VectorType>
1727 void
1729 ParameterHandler &prm)
1730 {
1731 prm.add_parameter(
1732 "Method name",
1733 method_name,
1734 "STS method name passed to LSRKStepSetSTSMethodByName. "
1735 "If empty, SUNDIALS uses the default (ARKODE_LSRK_RKC_2).");
1736 prm.add_parameter(
1737 "Dominant eigenvalue recomputation frequency",
1738 dom_eig_frequency,
1739 "Number of successful steps after which the dominant eigenvalue "
1740 "estimate is recomputed. 0 means constant dominant eigenvalue "
1741 "(no change throughout the simulation). Any negative value leaves "
1742 "this option at the SUNDIALS default of 25.");
1743 prm.add_parameter("Maximum number of stages",
1744 max_num_stages,
1745 "Maximum number of polynomial stages per time step. "
1746 "0 means no limit.");
1747 prm.add_parameter(
1748 "Dominant eigenvalue estimator maximum iterations",
1749 dom_eig_estimator_max_iters,
1750 "Maximum number of power iterations performed by the built-in "
1751 "dominant-eigenvalue estimator. Only used when no dominant eigenvalue "
1752 "function is provided.");
1753 prm.add_parameter(
1754 "Dominant eigenvalue estimator relative tolerance",
1755 dom_eig_estimator_rel_tol,
1756 "Relative convergence tolerance of the power iteration used by the "
1757 "built-in dominant-eigenvalue estimator. Only used when no dominant "
1758 "eigenvalue function is provided.");
1759 prm.add_parameter(
1760 "Dominant eigenvalue estimator warmup iterations",
1761 dom_eig_estimator_num_warmups,
1762 "Number of preprocessing warmup iterations performed once when the "
1763 "built-in dominant-eigenvalue estimator is first initialized. Only used "
1764 "when no dominant eigenvalue function is provided.");
1765 }
1766
1767
1795 template <typename VectorType = Vector<double>>
1796 class LSRKStepperSSP : public ARKodeStepper<VectorType>
1797 {
1798 public:
1803 {
1804 public:
1817 AdditionalData(const std::string &method_name = "",
1818 const unsigned int num_stages = 0)
1819 : method_name(method_name)
1820 , num_stages(num_stages)
1821 {}
1822
1828 void
1829 add_parameters(ParameterHandler &prm);
1830
1835 std::string method_name;
1836
1842 unsigned int num_stages;
1843 };
1844
1851
1852 void *
1853 get_arkode_memory() const override;
1854
1866 std::function<
1867 void(const double t, const VectorType &y, VectorType &explicit_f)>
1869
1884 std::function<void(void *arkode_mem)> custom_setup;
1885
1886 private:
1888 VectorType>::template CallbackContext<LSRKStepperSSP<VectorType>>;
1889
1891
1900 void
1901 reinit(double t0, const VectorType &y0) override;
1902
1911 void
1912 resize(double t0, const VectorType &y0, double hscale) override;
1913
1918
1923
1928 };
1929
1930
1931 template <typename VectorType>
1932 void
1934 ParameterHandler &prm)
1935 {
1936 prm.add_parameter(
1937 "Method name",
1938 method_name,
1939 "SSP method name passed to LSRKStepSetSSPMethodByName. "
1940 "If empty, SUNDIALS uses the default (ARKODE_LSRK_SSP_10_4).");
1941 prm.add_parameter("Number of SSP stages",
1942 num_stages,
1943 "Number of stages for variable-stage SSP methods "
1944 "(ARKODE_LSRK_SSP_S_2, ARKODE_LSRK_SSP_S_3). "
1945 "0 means SUNDIALS default.");
1946 }
1947
1948# endif // DEAL_II_SUNDIALS_VERSION_GTE(7, 2, 0)
1949
1950} // namespace SUNDIALS
1951
1952#endif // DEAL_II_WITH_SUNDIALS
1953
1955
1956#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="")
std::optional< internal::SundialsNonlinearSolver > fixed_point_solver
std::function< void(void *arkode_mem)> custom_setup
void reinit(double t0, const VectorType &y0) override
std::optional< internal::SundialsLinearSolver > default_mass_solver
std::function< void(const double t, const VectorType &y, VectorType &res)> implicit_function
std::function< void(const double t)> mass_times_vector_setup
void setup_system_solver(const VectorType &solution)
ARKStepper(const AdditionalData &data=AdditionalData())
CallbackContext callback_ctx
void setup_mass_solver(const VectorType &solution)
typename ARKodeStepper< VectorType >::template CallbackContext< ARKStepper< VectorType > > CallbackContext
void resize(double t0, const VectorType &y0, double hscale) override
std::optional< internal::LinearSolverWrapper< VectorType > > linear_solver
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
std::optional< internal::LinearSolverWrapper< VectorType > > mass_solver
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
std::optional< internal::SundialsLinearSolver > default_linear_solver
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 void reinit(double t0, const VectorType &y0)=0
internal::InvocationContext invocation_context() const
virtual ~ARKodeStepper()=default
std::exception_ptr * pending_exception_ptr
std::unique_ptr< void, void(*)(void *)> ARKodeMemoryPtr
internal::SharedSUNContext sundials_context
void attach(std::exception_ptr &pending_exception, const internal::SharedSUNContext &context)
virtual void * get_arkode_memory() const =0
virtual void resize(double t0, const VectorType &y0, double hscale)=0
AdditionalData(const unsigned int order=0, const std::string &explicit_butcher_table="")
void add_parameters(ParameterHandler &prm)
CallbackContext callback_ctx
ARKodeMemoryPtr arkode_mem
void * get_arkode_memory() const override
std::function< void(void *arkode_mem)> custom_setup
void reinit(double t0, const VectorType &y0) override
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 resize(double t0, const VectorType &y0, double hscale) override
void add_parameters(ParameterHandler &prm)
AdditionalData(const std::string &method_name="", const unsigned int num_stages=0)
void reinit(double t0, const VectorType &y0) override
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 resize(double t0, const VectorType &y0, double hscale) 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
void reinit(double t0, const VectorType &y0) override
void resize(double t0, const VectorType &y0, double hscale) override
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 attach_default_dom_eig_estimator(N_Vector y, SUNContext context)
typename ARKodeStepper< VectorType >::template CallbackContext< LSRKStepperSTS< VectorType > > CallbackContext
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_SUNDIALS_VERSION_GTE(major, minor, patch)
Definition config.h:532
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define Assert(cond, exc)
static ::ExceptionBase & ExcMessage(std::string arg1)
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