22#ifdef DEAL_II_WITH_SUNDIALS
30# ifdef DEAL_II_WITH_TRILINOS
34# ifdef DEAL_II_WITH_PETSC
42# include <arkode/arkode_arkstep.h>
43# include <sunlinsol/sunlinsol_spgmr.h>
44# include <sunnonlinsol/sunnonlinsol_fixedpoint.h>
54 template <
typename VectorType>
56 explicit_function_callback(realtype tt,
62 ARKode<VectorType> &solver =
63 *
static_cast<ARKode<VectorType> *
>(user_data);
65 auto *src_yy = internal::unwrap_nvector_const<VectorType>(yy);
66 auto *dst_yp = internal::unwrap_nvector<VectorType>(yp);
68 return solver.explicit_function(tt, *src_yy, *dst_yp);
73 template <
typename VectorType>
75 implicit_function_callback(realtype tt,
81 ARKode<VectorType> &solver =
82 *
static_cast<ARKode<VectorType> *
>(user_data);
84 auto *src_yy = internal::unwrap_nvector_const<VectorType>(yy);
85 auto *dst_yp = internal::unwrap_nvector<VectorType>(yp);
87 return solver.implicit_function(tt, *src_yy, *dst_yp);
92 template <
typename VectorType>
94 jacobian_times_vector_callback(N_Vector v,
103 ARKode<VectorType> &solver =
104 *
static_cast<ARKode<VectorType> *
>(user_data);
106 auto *src_v = internal::unwrap_nvector_const<VectorType>(v);
107 auto *src_y = internal::unwrap_nvector_const<VectorType>(y);
108 auto *src_fy = internal::unwrap_nvector_const<VectorType>(fy);
110 auto *dst_Jv = internal::unwrap_nvector<VectorType>(Jv);
112 return solver.jacobian_times_vector(*src_v, *dst_Jv, t, *src_y, *src_fy);
117 template <
typename VectorType>
119 jacobian_times_vector_setup_callback(realtype t,
125 ARKode<VectorType> &solver =
126 *
static_cast<ARKode<VectorType> *
>(user_data);
128 auto *src_y = internal::unwrap_nvector_const<VectorType>(y);
129 auto *src_fy = internal::unwrap_nvector_const<VectorType>(fy);
131 return solver.jacobian_times_setup(t, *src_y, *src_fy);
136 template <
typename VectorType>
138 solve_with_jacobian_callback(realtype t,
149 ARKode<VectorType> &solver =
150 *
static_cast<ARKode<VectorType> *
>(user_data);
152 auto *src_y = internal::unwrap_nvector_const<VectorType>(y);
153 auto *src_fy = internal::unwrap_nvector_const<VectorType>(fy);
154 auto *src_r = internal::unwrap_nvector_const<VectorType>(r);
156 auto *dst_z = internal::unwrap_nvector<VectorType>(z);
158 return solver.jacobian_preconditioner_solve(
159 t, *src_y, *src_fy, *src_r, *dst_z, gamma, delta, lr);
164 template <
typename VectorType>
166 jacobian_solver_setup_callback(realtype t,
170 booleantype *jcurPtr,
175 ARKode<VectorType> &solver =
176 *
static_cast<ARKode<VectorType> *
>(user_data);
178 auto *src_y = internal::unwrap_nvector_const<VectorType>(y);
179 auto *src_fy = internal::unwrap_nvector_const<VectorType>(fy);
181 return solver.jacobian_preconditioner_setup(
182 t, *src_y, *src_fy, jok, *jcurPtr, gamma);
187 template <
typename VectorType>
189 mass_matrix_times_vector_callback(N_Vector v,
195 ARKode<VectorType> &solver =
196 *
static_cast<ARKode<VectorType> *
>(mtimes_data);
198 auto *src_v = internal::unwrap_nvector_const<VectorType>(v);
199 auto *dst_Mv = internal::unwrap_nvector<VectorType>(Mv);
201 return solver.mass_times_vector(t, *src_v, *dst_Mv);
206 template <
typename VectorType>
208 mass_matrix_times_vector_setup_callback(realtype t,
void *mtimes_data)
211 ARKode<VectorType> &solver =
212 *
static_cast<ARKode<VectorType> *
>(mtimes_data);
214 return solver.mass_times_setup(t);
219 template <
typename VectorType>
221 solve_with_mass_matrix_callback(realtype t,
229 ARKode<VectorType> &solver =
230 *
static_cast<ARKode<VectorType> *
>(user_data);
232 auto *src_r = internal::unwrap_nvector_const<VectorType>(r);
233 auto *dst_z = internal::unwrap_nvector<VectorType>(z);
235 return solver.mass_preconditioner_solve(t, *src_r, *dst_z, delta, lr);
240 template <
typename VectorType>
242 mass_matrix_solver_setup_callback(realtype t,
void *user_data)
245 ARKode<VectorType> &solver =
246 *
static_cast<ARKode<VectorType> *
>(user_data);
248 return solver.mass_preconditioner_setup(t);
253 template <
typename VectorType>
255 :
ARKode(data, MPI_COMM_SELF)
259 template <
typename VectorType>
263 , arkode_mem(nullptr)
265 , arkode_ctx(nullptr)
267 , mpi_communicator(mpi_comm)
268 , last_end_time(data.initial_time)
272# if DEAL_II_SUNDIALS_VERSION_GTE(6, 0, 0)
289 template <
typename VectorType>
292 ARKStepFree(&arkode_mem);
294# if DEAL_II_SUNDIALS_VERSION_GTE(6, 0, 0)
295 const int status = SUNContext_Free(&arkode_ctx);
303 template <
typename VectorType>
309 data.initial_step_size);
311 return do_evolve_time(solution, time,
true);
316 template <
typename VectorType>
319 const double intermediate_time,
320 const bool reset_solver)
323 intermediate_time > last_end_time,
325 "The requested intermediate time is smaller than the last requested "
326 "intermediate time."));
328 const bool do_reset = reset_solver || arkode_mem ==
nullptr;
329 DiscreteTime time(last_end_time, intermediate_time, data.initial_step_size);
330 return do_evolve_time(solution, time, do_reset);
335 template <
typename VectorType>
355 const int status = ARKStepSetStopTime(arkode_mem, time.
get_end_time());
360 auto solution_nvector = internal::make_nvector_view(solution
372 double actual_next_time;
373 const auto status = ARKStepEvolve(arkode_mem,
403 template <
typename VectorType>
406 const double current_time_step,
407 const VectorType &solution)
409 last_end_time = current_time;
413# if DEAL_II_SUNDIALS_VERSION_GTE(6, 0, 0)
414 status = SUNContext_Free(&arkode_ctx);
418 SUNContext_Create(mpi_communicator == MPI_COMM_SELF ?
nullptr :
426 ARKStepFree(&arkode_mem);
432 auto initial_condition_nvector = internal::make_nvector_view(solution
439 Assert(explicit_function || implicit_function,
440 ExcFunctionNotProvided(
"explicit_function || implicit_function"));
442 arkode_mem = ARKStepCreate(
443 explicit_function ? &explicit_function_callback<VectorType> :
nullptr,
444 implicit_function ? &implicit_function_callback<VectorType> :
nullptr,
446 initial_condition_nvector
454 if (get_local_tolerances)
456 const auto abs_tols = internal::make_nvector_view(get_local_tolerances()
463 ARKStepSVtolerances(arkode_mem, data.relative_tolerance, abs_tols);
468 status = ARKStepSStolerances(arkode_mem,
469 data.relative_tolerance,
470 data.absolute_tolerance);
475 status = ARKStepSetUserData(arkode_mem,
this);
478 setup_system_solver(solution);
480 setup_mass_solver(solution);
482 status = ARKStepSetInitStep(arkode_mem, current_time_step);
485 status = ARKStepSetStopTime(arkode_mem, data.final_time);
488 status = ARKStepSetOrder(arkode_mem, data.maximum_order);
492 custom_setup(arkode_mem);
497 template <
typename VectorType>
502 if (!implicit_function)
509 if (jacobian_times_vector)
512 if (solve_linearized_system)
515 std::make_unique<internal::LinearSolverWrapper<VectorType>>(
516 solve_linearized_system
517# if DEAL_II_SUNDIALS_VERSION_GTE(6, 0, 0)
522 sun_linear_solver = *linear_solver;
528 auto y_template = internal::make_nvector_view(solution
534# if DEAL_II_SUNDIALS_VERSION_LT(6, 0, 0)
536 SUNLinSol_SPGMR(y_template,
541 SUNLinSol_SPGMR(y_template,
547 status = ARKStepSetLinearSolver(arkode_mem, sun_linear_solver,
nullptr);
549 status = ARKStepSetJacTimes(
551 jacobian_times_setup ?
552 jacobian_times_vector_setup_callback<VectorType> :
554 jacobian_times_vector_callback<VectorType>);
556 if (jacobian_preconditioner_solve)
558 status = ARKStepSetPreconditioner(
560 jacobian_preconditioner_setup ?
561 jacobian_solver_setup_callback<VectorType> :
563 solve_with_jacobian_callback<VectorType>);
566 if (data.implicit_function_is_linear)
568 status = ARKStepSetLinear(
569 arkode_mem, data.implicit_function_is_time_independent ? 0 : 1);
575 auto y_template = internal::make_nvector_view(solution
582# if DEAL_II_SUNDIALS_VERSION_LT(6, 0, 0)
583 SUNNonlinearSolver fixed_point_solver =
584 SUNNonlinSol_FixedPoint(y_template,
585 data.anderson_acceleration_subspace);
587 SUNNonlinearSolver fixed_point_solver =
588 SUNNonlinSol_FixedPoint(y_template,
589 data.anderson_acceleration_subspace,
593 status = ARKStepSetNonlinearSolver(arkode_mem, fixed_point_solver);
598 ARKStepSetMaxNonlinIters(arkode_mem, data.maximum_non_linear_iterations);
604 template <
typename VectorType>
611 if (mass_times_vector)
617 std::make_unique<internal::LinearSolverWrapper<VectorType>>(
619# if DEAL_II_SUNDIALS_VERSION_GTE(6, 0, 0)
624 sun_mass_linear_solver = *mass_solver;
628 auto y_template = internal::make_nvector_view(solution
634# if DEAL_II_SUNDIALS_VERSION_LT(6, 0, 0)
635 sun_mass_linear_solver =
636 SUNLinSol_SPGMR(y_template,
640 sun_mass_linear_solver =
641 SUNLinSol_SPGMR(y_template,
647 booleantype mass_time_dependent =
648 data.mass_is_time_independent ? SUNFALSE : SUNTRUE;
649 status = ARKStepSetMassLinearSolver(arkode_mem,
650 sun_mass_linear_solver,
652 mass_time_dependent);
654 status = ARKStepSetMassTimes(
657 mass_matrix_times_vector_setup_callback<VectorType> :
659 mass_matrix_times_vector_callback<VectorType>,
663 if (mass_preconditioner_solve)
665 status = ARKStepSetMassPreconditioner(
667 mass_preconditioner_setup ?
668 mass_matrix_solver_setup_callback<VectorType> :
670 solve_with_mass_matrix_callback<VectorType>);
678 template <
typename VectorType>
682 reinit_vector = [](VectorType &) {
683 AssertThrow(
false, ExcFunctionNotProvided(
"reinit_vector"));
686 solver_should_restart = [](
const double, VectorType &) ->
bool {
693 template <
typename VectorType>
706# ifdef DEAL_II_WITH_MPI
708# ifdef DEAL_II_WITH_TRILINOS
714# ifdef DEAL_II_WITH_PETSC
715# ifndef PETSC_USE_COMPLEX
#define AssertARKode(code)
double get_next_step_size() const
void set_desired_next_step_size(const double time_step_size)
unsigned int get_step_number() const
double get_current_time() const
void set_next_step_size(const double time_step_size)
double get_next_time() const
double get_previous_step_size() const
double get_end_time() const
void setup_mass_solver(const VectorType &solution)
ARKode(const AdditionalData &data=AdditionalData())
void * get_arkode_memory() const
int do_evolve_time(VectorType &solution, ::DiscreteTime &time, const bool do_reset)
MPI_Comm mpi_communicator
void reset(const double t, const double h, const VectorType &y)
void set_functions_to_trigger_an_assert()
unsigned int solve_ode(VectorType &solution)
void setup_system_solver(const VectorType &solution)
unsigned int solve_ode_incrementally(VectorType &solution, const double intermediate_time, const bool reset_solver=false)
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_SUNDIALS_VERSION_GTE(major, minor, patch)
#define DEAL_II_NAMESPACE_CLOSE
#define Assert(cond, exc)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)