21 #ifdef DEAL_II_WITH_SUNDIALS
28 # ifdef DEAL_II_WITH_TRILINOS
32 # ifdef DEAL_II_WITH_PETSC
40 # include <sundials/sundials_config.h>
42 # include <kinsol/kinsol_direct.h>
43 # include <sunlinsol/sunlinsol_dense.h>
44 # include <sunmatrix/sunmatrix_dense.h>
56 template <
typename VectorType>
59 const unsigned int maximum_non_linear_iterations,
60 const double function_tolerance,
61 const double step_tolerance,
62 const bool no_init_setup,
63 const unsigned int maximum_setup_calls,
64 const double maximum_newton_step,
65 const double dq_relative_error,
66 const unsigned int maximum_beta_failures,
67 const unsigned int anderson_subspace_size)
69 , maximum_non_linear_iterations(maximum_non_linear_iterations)
70 , function_tolerance(function_tolerance)
71 , step_tolerance(step_tolerance)
72 , no_init_setup(no_init_setup)
73 , maximum_setup_calls(maximum_setup_calls)
74 , maximum_newton_step(maximum_newton_step)
75 , dq_relative_error(dq_relative_error)
76 , maximum_beta_failures(maximum_beta_failures)
77 , anderson_subspace_size(anderson_subspace_size)
82 template <
typename VectorType>
86 static std::string strategy_str(
"newton");
89 "Choose among newton|linesearch|fixed_point|picard",
91 "newton|linesearch|fixed_point|picard"));
93 if (
value ==
"newton")
95 else if (
value ==
"linesearch")
96 strategy = linesearch;
97 else if (
value ==
"fixed_point")
98 strategy = fixed_point;
99 else if (
value ==
"picard")
105 maximum_non_linear_iterations);
106 prm.
add_parameter(
"Function norm stopping tolerance", function_tolerance);
107 prm.
add_parameter(
"Scaled step stopping tolerance", step_tolerance);
112 maximum_setup_calls);
113 prm.
add_parameter(
"Maximum allowable scaled length of the Newton step",
114 maximum_newton_step);
115 prm.
add_parameter(
"Relative error for different quotient computation",
120 prm.
add_parameter(
"Maximum number of beta-condition failures",
121 maximum_beta_failures);
127 anderson_subspace_size);
134 template <
typename VectorType>
136 residual_callback(N_Vector yy, N_Vector FF,
void *user_data)
141 auto *src_yy = internal::unwrap_nvector_const<VectorType>(yy);
142 auto *dst_FF = internal::unwrap_nvector<VectorType>(FF);
146 err = solver.
residual(*src_yy, *dst_FF);
155 template <
typename VectorType>
157 iteration_callback(N_Vector yy, N_Vector FF,
void *user_data)
162 auto *src_yy = internal::unwrap_nvector_const<VectorType>(yy);
163 auto *dst_FF = internal::unwrap_nvector<VectorType>(FF);
176 # if DEAL_II_SUNDIALS_VERSION_LT(4, 1, 0)
177 template <
typename VectorType>
181 KINSOL<VectorType> &solver =
182 *
static_cast<KINSOL<VectorType> *
>(
kinsol_mem->kin_user_data);
185 internal::unwrap_nvector_const<VectorType>(
kinsol_mem->kin_uu);
187 internal::unwrap_nvector_const<VectorType>(
kinsol_mem->kin_fval);
189 int err = solver.setup_jacobian(*src_ycur, *src_fcur);
195 template <
typename VectorType>
197 solve_with_jacobian_callback(KINMem
kinsol_mem,
203 KINSOL<VectorType> &solver =
204 *
static_cast<KINSOL<VectorType> *
>(
kinsol_mem->kin_user_data);
207 internal::unwrap_nvector_const<VectorType>(
kinsol_mem->kin_uu);
209 internal::unwrap_nvector_const<VectorType>(
kinsol_mem->kin_fval);
210 auto *src = internal::unwrap_nvector_const<VectorType>(
b);
211 auto *dst = internal::unwrap_nvector<VectorType>(x);
213 int err = solver.solve_jacobian_system(*src_ycur, *src_fcur, *src, *dst);
225 template <
typename VectorType>
227 setup_jacobian_callback(N_Vector u,
237 const KINSOL<VectorType> &solver =
238 *
static_cast<const KINSOL<VectorType> *
>(user_data);
240 auto *ycur = internal::unwrap_nvector_const<VectorType>(u);
241 auto *fcur = internal::unwrap_nvector_const<VectorType>(f);
244 solver.setup_jacobian(*ycur, *fcur);
251 template <
typename VectorType>
253 solve_with_jacobian_callback(SUNLinearSolver LS,
262 const KINSOL<VectorType> &solver =
263 *
static_cast<const KINSOL<VectorType> *
>(LS->content);
267 if (solver.solve_with_jacobian)
269 auto *src_b = internal::unwrap_nvector<VectorType>(
b);
270 auto *dst_x = internal::unwrap_nvector<VectorType>(x);
272 const int err = solver.solve_with_jacobian(*src_b, *dst_x, tol);
289 auto *src_b = internal::unwrap_nvector_const<VectorType>(
b);
290 auto *dst_x = internal::unwrap_nvector<VectorType>(x);
298 solver.solve_jacobian_system(*src_ycur, *src_fcur, *src_b, *dst_x);
308 template <
typename VectorType>
318 template <
typename VectorType>
322 KINFree(&kinsol_mem);
327 template <
typename VectorType>
333 VectorType u_scale_temp, f_scale_temp;
335 if (get_solution_scaling)
336 u_scale = internal::make_nvector_view(get_solution_scaling());
339 reinit_vector(u_scale_temp);
341 u_scale = internal::make_nvector_view(u_scale_temp);
344 if (get_function_scaling)
345 f_scale = internal::make_nvector_view(get_function_scaling());
348 reinit_vector(f_scale_temp);
350 f_scale = internal::make_nvector_view(f_scale_temp);
354 if (data.strategy == AdditionalData::fixed_point)
356 Assert(iteration_function,
357 ExcFunctionNotProvided(
"iteration_function"));
361 Assert(residual, ExcFunctionNotProvided(
"residual"));
362 Assert(solve_jacobian_system || solve_with_jacobian,
363 ExcFunctionNotProvided(
364 "solve_jacobian_system || solve_with_jacobian"));
367 auto solution = internal::make_nvector_view(initial_guess_and_solution);
370 KINFree(&kinsol_mem);
372 kinsol_mem = KINCreate();
377 status = KINSetUserData(kinsol_mem,
static_cast<void *
>(
this));
381 status = KINSetNumMaxIters(kinsol_mem, data.maximum_non_linear_iterations);
385 status = KINSetMAA(kinsol_mem, data.anderson_subspace_size);
388 if (data.strategy == AdditionalData::fixed_point)
389 status = KINInit(kinsol_mem, iteration_callback<VectorType>, solution);
391 status = KINInit(kinsol_mem, residual_callback<VectorType>, solution);
394 status = KINSetFuncNormTol(kinsol_mem, data.function_tolerance);
397 status = KINSetScaledStepTol(kinsol_mem, data.step_tolerance);
400 status = KINSetMaxSetupCalls(kinsol_mem, data.maximum_setup_calls);
403 status = KINSetNoInitSetup(kinsol_mem, data.no_init_setup);
406 status = KINSetMaxNewtonStep(kinsol_mem, data.maximum_newton_step);
409 status = KINSetMaxBetaFails(kinsol_mem, data.maximum_beta_failures);
412 status = KINSetRelErrFunc(kinsol_mem, data.dq_relative_error);
415 SUNMatrix J =
nullptr;
416 SUNLinearSolver LS =
nullptr;
418 if (solve_jacobian_system ||
423 # if DEAL_II_SUNDIALS_VERSION_LT(4, 1, 0)
424 auto KIN_mem =
static_cast<KINMem
>(kinsol_mem);
426 Assert(solve_jacobian_system,
427 ExcFunctionNotProvided(
"solve_jacobian_system"))
428 KIN_mem->kin_lsolve = solve_with_jacobian_callback<VectorType>;
431 KIN_mem->kin_lsetup = setup_jacobian_callback<VectorType>;
434 # elif DEAL_II_SUNDIALS_VERSION_LT(5, 0, 0)
453 [](SUNLinearSolver ) -> SUNLinearSolver_Type {
454 return SUNLINEARSOLVER_MATRIX_ITERATIVE;
457 LS->ops->free = [](SUNLinearSolver LS) ->
int {
460 LS->content =
nullptr;
472 LS->ops->solve = solve_with_jacobian_callback<VectorType>;
479 J = SUNMatNewEmpty();
482 J->ops->getid = [](SUNMatrix ) -> SUNMatrix_ID {
483 return SUNMATRIX_CUSTOM;
486 J->ops->destroy = [](SUNMatrix
A) {
489 A->content =
nullptr;
501 status = KINSetLinearSolver(kinsol_mem, LS, J);
508 setup_jacobian = [](
const VectorType &,
const VectorType &) {
511 status = KINSetJacFn(kinsol_mem, &setup_jacobian_callback<VectorType>);
517 status = KINSol(kinsol_mem, solution, data.strategy, u_scale, f_scale);
521 status = KINGetNumNonlinSolvIters(kinsol_mem, &nniters);
528 KINFree(&kinsol_mem);
530 return static_cast<unsigned int>(nniters);
533 template <
typename VectorType>
537 reinit_vector = [](VectorType &) {
538 AssertThrow(
false, ExcFunctionNotProvided(
"reinit_vector"));
548 # ifdef DEAL_II_WITH_MPI
550 # ifdef DEAL_II_WITH_TRILINOS
555 # ifdef DEAL_II_WITH_PETSC
556 # ifndef PETSC_USE_COMPLEX
void add_parameter(const std::string &entry, ParameterType ¶meter, const std::string &documentation="", const Patterns::PatternBase &pattern= *Patterns::Tools::Convert< ParameterType >::to_pattern(), const bool has_to_be_set=false)
void add_action(const std::string &entry, const std::function< void(const std::string &value)> &action)
void enter_subsection(const std::string &subsection)
AdditionalData(const SolutionStrategy &strategy=linesearch, const unsigned int maximum_non_linear_iterations=200, const double function_tolerance=0.0, const double step_tolerance=0.0, const bool no_init_setup=false, const unsigned int maximum_setup_calls=0, const double maximum_newton_step=0.0, const double dq_relative_error=0.0, const unsigned int maximum_beta_failures=0, const unsigned int anderson_subspace_size=0)
void add_parameters(ParameterHandler &prm)
void set_functions_to_trigger_an_assert()
KINSOL(const AdditionalData &data=AdditionalData(), const MPI_Comm &mpi_comm=MPI_COMM_WORLD)
unsigned int solve(VectorType &initial_guess_and_solution)
GrowingVectorMemory< VectorType > mem
std::function< int(const VectorType &src, VectorType &dst)> residual
std::function< int(const VectorType &src, VectorType &dst)> iteration_function
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcInternalError()
#define Assert(cond, exc)
static ::ExceptionBase & ExcNotImplemented()
#define AssertThrow(cond, exc)
#define AssertKINSOL(code)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
SUNLinearSolver SUNLinSolNewEmpty()