deal.II version GIT relicensing-6960-g70e9c5b7be 2026-10-22 20:10: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
45
46# include <boost/signals2.hpp>
47
48# include <sundials/sundials_linearsolver.h>
49# include <sundials/sundials_math.h>
50
51# include <complex>
52# include <exception>
53# include <memory>
54# include <string>
55
56#endif // DEAL_II_WITH_SUNDIALS
57
59
60#ifdef DEAL_II_WITH_SUNDIALS
61
62namespace SUNDIALS
63{
67 template <typename VectorType>
68 class ARKode;
69
80 template <typename VectorType>
82 {
83 public:
88 friend class ARKode<VectorType>;
89
94 virtual ~ARKodeStepper() = default;
95
112 virtual void *
113 get_arkode_memory() const = 0;
114
115 private:
124 void
125 attach(std::exception_ptr &pending_exception
127 ,
128 const internal::SharedSUNContext &context
129# endif
130 )
131 {
132 Assert(pending_exception_ptr == nullptr,
133 ExcMessage("This stepper is already attached to an ARKode "
134 "object."));
135 pending_exception_ptr = &pending_exception;
136# if DEAL_II_SUNDIALS_VERSION_GTE(6, 0, 0)
137 sundials_context = context;
138# endif
139 }
140
149 virtual void
150 reinit(double t0, const VectorType &y0) = 0;
151
162 virtual void
163 resize(double t0, const VectorType &y0, double hscale) = 0;
164
165 protected:
171 template <typename Stepper>
173 {
174 Stepper *stepper = nullptr;
175 std::exception_ptr *pending_exception = nullptr;
176 };
177
185 using ARKodeMemoryPtr = std::unique_ptr<void, void (*)(void *)>;
186
194 {
195 Assert(pending_exception_ptr != nullptr,
196 ExcMessage("This stepper is not attached to an ARKode object."));
198 {
200# if DEAL_II_SUNDIALS_VERSION_GTE(6, 0, 0)
201 ,
203# endif
204 };
205 }
206
207 private:
211 std::exception_ptr *pending_exception_ptr = nullptr;
212
213# if DEAL_II_SUNDIALS_VERSION_GTE(6, 0, 0)
220# endif
221 };
222
462 template <typename VectorType = Vector<double>>
463 class ARKStepper : public ARKodeStepper<VectorType>
464 {
465 public:
470 {
471 public:
517 explicit AdditionalData(
518 const unsigned int order = 0,
519 const unsigned int maximum_non_linear_iterations = 10,
520 const bool implicit_function_is_linear = false,
521 const bool implicit_function_is_time_independent = false,
522 const bool mass_is_time_independent = false,
523 const int anderson_acceleration_subspace = 3,
524 const std::string &implicit_butcher_table = "",
525 const std::string &explicit_butcher_table = "");
526
541 void
543
552 unsigned int order;
553
559
564
570
576
582
593
604 };
605
612
613 void *
614 get_arkode_memory() const override;
615
632 std::function<
633 void(const double t, const VectorType &y, VectorType &explicit_f)>
635
652 std::function<void(const double t, const VectorType &y, VectorType &res)>
654
673 std::function<void(const double t, const VectorType &v, VectorType &Mv)>
675
710 std::function<void(const double t)> mass_times_vector_setup;
711
738 std::function<void(const VectorType &v,
739 VectorType &Jv,
740 const double t,
741 const VectorType &y,
742 const VectorType &fy)>
744
780 std::function<
781 void(const double t, const VectorType &y, const VectorType &fy)>
783
811
835
867 std::function<void(const double t,
868 const VectorType &y,
869 const VectorType &fy,
870 const VectorType &r,
871 VectorType &z,
872 const double gamma,
873 const double tol,
874 const int lr)>
876
919 std::function<void(const double t,
920 const VectorType &y,
921 const VectorType &fy,
922 const int jok,
923 int &jcur,
924 const double gamma)>
926
954 std::function<void(const double t,
955 const VectorType &r,
956 VectorType &z,
957 const double tol,
958 const int lr)>
960
985 std::function<void(const double t)> mass_preconditioner_setup;
986
1012 std::function<void(void *arkode_mem)> custom_setup;
1013
1014 private:
1016 VectorType>::template CallbackContext<ARKStepper<VectorType>>;
1017
1019
1028 void
1029 reinit(double t0, const VectorType &y0) override;
1030
1041 void
1042 resize(double t0, const VectorType &y0, double hscale) override;
1043
1051 void
1052 setup_system_solver(const VectorType &solution);
1053
1062 void
1063 setup_mass_solver(const VectorType &solution);
1064
1069
1075 std::unique_ptr<internal::LinearSolverWrapper<VectorType>> linear_solver;
1076
1081 std::unique_ptr<internal::LinearSolverWrapper<VectorType>> mass_solver;
1082
1090
1095 };
1096
1097
1098 template <typename VectorType>
1100 const unsigned int order,
1101 const unsigned int maximum_non_linear_iterations,
1102 const bool implicit_function_is_linear,
1103 const bool implicit_function_is_time_independent,
1104 const bool mass_is_time_independent,
1105 const int anderson_acceleration_subspace,
1106 const std::string &implicit_butcher_table,
1107 const std::string &explicit_butcher_table)
1108 : order(order)
1109 , maximum_non_linear_iterations(maximum_non_linear_iterations)
1110 , implicit_function_is_linear(implicit_function_is_linear)
1111 , implicit_function_is_time_independent(
1112 implicit_function_is_time_independent)
1113 , mass_is_time_independent(mass_is_time_independent)
1114 , anderson_acceleration_subspace(anderson_acceleration_subspace)
1115 , implicit_butcher_table(implicit_butcher_table)
1116 , explicit_butcher_table(explicit_butcher_table)
1117 {}
1118
1119
1120
1121 template <typename VectorType>
1122 void
1124 {
1125 prm.add_parameter("Integration accuracy order", order);
1126 prm.add_parameter("Maximum number of nonlinear iterations",
1127 maximum_non_linear_iterations);
1128 prm.add_parameter("Implicit function is linear",
1129 implicit_function_is_linear);
1130 prm.add_parameter("Implicit function is time independent",
1131 implicit_function_is_time_independent);
1132 prm.add_parameter("Mass is time independent", mass_is_time_independent);
1133 prm.add_parameter("Anderson-acceleration subspace",
1134 anderson_acceleration_subspace);
1135 prm.add_parameter("Implicit Butcher table", implicit_butcher_table);
1136 prm.add_parameter("Explicit Butcher table", explicit_butcher_table);
1137 }
1138
1139
1209 template <typename VectorType = Vector<double>>
1210 class ERKStepper : public ARKodeStepper<VectorType>
1211 {
1212 public:
1221 {
1222 public:
1235 AdditionalData(const unsigned int order = 0,
1236 const std::string &explicit_butcher_table = "");
1237
1252 void
1253 add_parameters(ParameterHandler &prm);
1254
1263 unsigned int order;
1264
1274 };
1275
1282
1283 void *
1284 get_arkode_memory() const override;
1285
1297 std::function<
1298 void(const double t, const VectorType &y, VectorType &explicit_f)>
1300
1326 std::function<void(void *arkode_mem)> custom_setup;
1327
1328 private:
1330 VectorType>::template CallbackContext<ERKStepper<VectorType>>;
1331
1333
1342 void
1343 reinit(double t0, const VectorType &y0) override;
1344
1353 void
1354 resize(double t0, const VectorType &y0, double hscale) override;
1355
1360
1365
1370 };
1371
1372
1373 template <typename VectorType>
1375 const unsigned int order,
1376 const std::string &explicit_butcher_table)
1377 : order(order)
1378 , explicit_butcher_table(explicit_butcher_table)
1379 {}
1380
1381
1382
1383 template <typename VectorType>
1384 void
1386 {
1387 prm.add_parameter("Integration accuracy order", order);
1388 prm.add_parameter("Explicit Butcher table", explicit_butcher_table);
1389 }
1390
1391
1392# if DEAL_II_SUNDIALS_VERSION_GTE(7, 2, 0)
1393
1443 template <typename VectorType = Vector<double>>
1444 class LSRKStepperSTS : public ARKodeStepper<VectorType>
1445 {
1446 public:
1451 {
1452 public:
1489 const std::string &method_name = "",
1490 const unsigned int dom_eig_frequency = numbers::invalid_unsigned_int,
1491 const unsigned int max_num_stages = 0,
1492 const unsigned int dom_eig_estimator_max_iters = 0,
1493 const double dom_eig_estimator_rel_tol = 0,
1494 const unsigned int dom_eig_estimator_num_warmups =
1496 : method_name(method_name)
1497 , dom_eig_frequency(dom_eig_frequency)
1498 , max_num_stages(max_num_stages)
1499 , dom_eig_estimator_max_iters(dom_eig_estimator_max_iters)
1500 , dom_eig_estimator_rel_tol(dom_eig_estimator_rel_tol)
1501 , dom_eig_estimator_num_warmups(dom_eig_estimator_num_warmups)
1502 {}
1503
1509 void
1510 add_parameters(ParameterHandler &prm);
1511
1516 std::string method_name;
1517
1526 unsigned int dom_eig_frequency;
1527
1532 unsigned int max_num_stages;
1533
1542
1551
1561 };
1562
1569
1570 void *
1571 get_arkode_memory() const override;
1572
1584 std::function<
1585 void(const double t, const VectorType &y, VectorType &explicit_f)>
1587
1615 std::function<std::complex<double>(const double t,
1616 const VectorType &y,
1617 const VectorType &f)>
1619
1634 std::function<void(void *arkode_mem)> custom_setup;
1635
1636 private:
1638 VectorType>::template CallbackContext<LSRKStepperSTS<VectorType>>;
1639
1641
1650 void
1651 reinit(double t0, const VectorType &y0) override;
1652
1663 void
1664 resize(double t0, const VectorType &y0, double hscale) override;
1665
1666# if DEAL_II_SUNDIALS_VERSION_GTE(7, 5, 0)
1672 void
1674# endif
1675
1680
1681# if DEAL_II_SUNDIALS_VERSION_GTE(7, 5, 0)
1690 std::unique_ptr<void, void (*)(void *)> dom_eig_estimator;
1691# endif
1692
1697
1702 };
1703
1704
1705 template <typename VectorType>
1706 void
1708 ParameterHandler &prm)
1709 {
1710 prm.add_parameter(
1711 "Method name",
1712 method_name,
1713 "STS method name passed to LSRKStepSetSTSMethodByName. "
1714 "If empty, SUNDIALS uses the default (ARKODE_LSRK_RKC_2).");
1715 prm.add_parameter(
1716 "Dominant eigenvalue recomputation frequency",
1717 dom_eig_frequency,
1718 "Number of successful steps after which the dominant eigenvalue "
1719 "estimate is recomputed. 0 means constant dominant eigenvalue "
1720 "(no change throughout the simulation). Any negative value leaves "
1721 "this option at the SUNDIALS default of 25.");
1722 prm.add_parameter("Maximum number of stages",
1723 max_num_stages,
1724 "Maximum number of polynomial stages per time step. "
1725 "0 means no limit.");
1726 prm.add_parameter(
1727 "Dominant eigenvalue estimator maximum iterations",
1728 dom_eig_estimator_max_iters,
1729 "Maximum number of power iterations performed by the built-in "
1730 "dominant-eigenvalue estimator. Only used when no dominant eigenvalue "
1731 "function is provided.");
1732 prm.add_parameter(
1733 "Dominant eigenvalue estimator relative tolerance",
1734 dom_eig_estimator_rel_tol,
1735 "Relative convergence tolerance of the power iteration used by the "
1736 "built-in dominant-eigenvalue estimator. Only used when no dominant "
1737 "eigenvalue function is provided.");
1738 prm.add_parameter(
1739 "Dominant eigenvalue estimator warmup iterations",
1740 dom_eig_estimator_num_warmups,
1741 "Number of preprocessing warmup iterations performed once when the "
1742 "built-in dominant-eigenvalue estimator is first initialized. Only used "
1743 "when no dominant eigenvalue function is provided.");
1744 }
1745
1746
1774 template <typename VectorType = Vector<double>>
1775 class LSRKStepperSSP : public ARKodeStepper<VectorType>
1776 {
1777 public:
1782 {
1783 public:
1796 AdditionalData(const std::string &method_name = "",
1797 const unsigned int num_stages = 0)
1798 : method_name(method_name)
1799 , num_stages(num_stages)
1800 {}
1801
1807 void
1808 add_parameters(ParameterHandler &prm);
1809
1814 std::string method_name;
1815
1821 unsigned int num_stages;
1822 };
1823
1830
1831 void *
1832 get_arkode_memory() const override;
1833
1845 std::function<
1846 void(const double t, const VectorType &y, VectorType &explicit_f)>
1848
1863 std::function<void(void *arkode_mem)> custom_setup;
1864
1865 private:
1867 VectorType>::template CallbackContext<LSRKStepperSSP<VectorType>>;
1868
1870
1879 void
1880 reinit(double t0, const VectorType &y0) override;
1881
1890 void
1891 resize(double t0, const VectorType &y0, double hscale) override;
1892
1897
1902
1907 };
1908
1909
1910 template <typename VectorType>
1911 void
1913 ParameterHandler &prm)
1914 {
1915 prm.add_parameter(
1916 "Method name",
1917 method_name,
1918 "SSP method name passed to LSRKStepSetSSPMethodByName. "
1919 "If empty, SUNDIALS uses the default (ARKODE_LSRK_SSP_10_4).");
1920 prm.add_parameter("Number of SSP stages",
1921 num_stages,
1922 "Number of stages for variable-stage SSP methods "
1923 "(ARKODE_LSRK_SSP_S_2, ARKODE_LSRK_SSP_S_3). "
1924 "0 means SUNDIALS default.");
1925 }
1926
1927# endif // DEAL_II_SUNDIALS_VERSION_GTE(7, 2, 0)
1928
1929} // namespace SUNDIALS
1930
1931#endif // DEAL_II_WITH_SUNDIALS
1932
1934
1935#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::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) override
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::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 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