17 #include <deal.II/base/config.h>
19 #include <deal.II/sundials/kinsol.h>
21 #ifdef DEAL_II_WITH_SUNDIALS
23 # include <deal.II/base/utilities.h>
25 # include <deal.II/lac/block_vector.h>
26 # ifdef DEAL_II_WITH_TRILINOS
27 # include <deal.II/lac/trilinos_parallel_block_vector.h>
28 # include <deal.II/lac/trilinos_vector.h>
30 # ifdef DEAL_II_WITH_PETSC
31 # include <deal.II/lac/petsc_block_vector.h>
32 # include <deal.II/lac/petsc_vector.h>
34 # include <deal.II/base/utilities.h>
36 # include <deal.II/sundials/copy.h>
38 # include <sundials/sundials_config.h>
39 # if DEAL_II_SUNDIALS_VERSION_GTE(3, 0, 0)
40 # include <kinsol/kinsol_direct.h>
41 # include <sunlinsol/sunlinsol_dense.h>
42 # include <sunmatrix/sunmatrix_dense.h>
44 # include <kinsol/kinsol_dense.h>
50 DEAL_II_NAMESPACE_OPEN
58 template <
typename VectorType>
60 t_kinsol_function(N_Vector yy, N_Vector FF,
void *user_data)
62 KINSOL<VectorType> &solver =
63 *
static_cast<KINSOL<VectorType> *
>(user_data);
67 solver.reinit_vector(*src_yy);
70 solver.reinit_vector(*dst_FF);
76 err = solver.residual(*src_yy, *dst_FF);
77 else if (solver.iteration_function)
78 err = solver.iteration_function(*src_yy, *dst_FF);
89 template <
typename VectorType>
91 t_kinsol_setup_jacobian(KINMem kinsol_mem)
93 KINSOL<VectorType> &solver =
94 *
static_cast<KINSOL<VectorType> *
>(kinsol_mem->kin_user_data);
98 solver.reinit_vector(*src_ycur);
101 solver.reinit_vector(*src_fcur);
103 copy(*src_ycur, kinsol_mem->kin_uu);
104 copy(*src_fcur, kinsol_mem->kin_fval);
106 int err = solver.setup_jacobian(*src_ycur, *src_fcur);
112 template <
typename VectorType>
114 t_kinsol_solve_jacobian(KINMem kinsol_mem,
120 KINSOL<VectorType> &solver =
121 *
static_cast<KINSOL<VectorType> *
>(kinsol_mem->kin_user_data);
125 solver.reinit_vector(*src_ycur);
128 solver.reinit_vector(*src_fcur);
130 copy(*src_ycur, kinsol_mem->kin_uu);
131 copy(*src_fcur, kinsol_mem->kin_fval);
134 solver.reinit_vector(*src);
137 solver.reinit_vector(*dst);
141 int err = solver.solve_jacobian_system(*src_ycur, *src_fcur, *src, *dst);
144 *sJpnorm = N_VWL2Norm(b, kinsol_mem->kin_fscale);
145 N_VProd(b, kinsol_mem->kin_fscale, b);
146 N_VProd(b, kinsol_mem->kin_fscale, b);
147 *sFdotJp = N_VDotProd(kinsol_mem->kin_fval, b);
153 template <
typename VectorType>
155 const MPI_Comm mpi_comm)
157 , kinsol_mem(nullptr)
163 Utilities::MPI::duplicate_communicator(mpi_comm))
170 template <
typename VectorType>
174 KINFree(&kinsol_mem);
175 # ifdef DEAL_II_WITH_MPI
178 const int ierr = MPI_Comm_free(&communicator);
187 template <
typename VectorType>
191 unsigned int system_size = initial_guess_and_solution.size();
196 # ifdef DEAL_II_WITH_MPI
199 const IndexSet is = initial_guess_and_solution.locally_owned_elements();
200 const unsigned int local_system_size = is.
n_elements();
203 N_VNew_Parallel(communicator, local_system_size, system_size);
205 u_scale = N_VNew_Parallel(communicator, local_system_size, system_size);
206 N_VConst_Parallel(1.e0, u_scale);
208 f_scale = N_VNew_Parallel(communicator, local_system_size, system_size);
209 N_VConst_Parallel(1.e0, f_scale);
216 "Trying to use a serial code with a parallel vector."));
217 solution = N_VNew_Serial(system_size);
218 u_scale = N_VNew_Serial(system_size);
219 N_VConst_Serial(1.e0, u_scale);
220 f_scale = N_VNew_Serial(system_size);
221 N_VConst_Serial(1.e0, f_scale);
224 if (get_solution_scaling)
225 copy(u_scale, get_solution_scaling());
227 if (get_function_scaling)
228 copy(f_scale, get_function_scaling());
230 copy(solution, initial_guess_and_solution);
233 KINFree(&kinsol_mem);
235 kinsol_mem = KINCreate();
237 int status = KINInit(kinsol_mem, t_kinsol_function<VectorType>, solution);
239 AssertKINSOL(status);
241 status = KINSetUserData(kinsol_mem, static_cast<void *>(
this));
242 AssertKINSOL(status);
244 status = KINSetNumMaxIters(kinsol_mem, data.maximum_non_linear_iterations);
245 AssertKINSOL(status);
247 status = KINSetFuncNormTol(kinsol_mem, data.function_tolerance);
248 AssertKINSOL(status);
250 status = KINSetScaledStepTol(kinsol_mem, data.step_tolerance);
251 AssertKINSOL(status);
253 status = KINSetMaxSetupCalls(kinsol_mem, data.maximum_setup_calls);
254 AssertKINSOL(status);
256 status = KINSetNoInitSetup(kinsol_mem, data.no_init_setup);
257 AssertKINSOL(status);
259 status = KINSetMaxNewtonStep(kinsol_mem, data.maximum_newton_step);
260 AssertKINSOL(status);
262 status = KINSetMaxBetaFails(kinsol_mem, data.maximum_beta_failures);
263 AssertKINSOL(status);
265 status = KINSetMAA(kinsol_mem, data.anderson_subspace_size);
266 AssertKINSOL(status);
268 status = KINSetRelErrFunc(kinsol_mem, data.dq_relative_error);
269 AssertKINSOL(status);
271 # if DEAL_II_SUNDIALS_VERSION_GTE(3, 0, 0)
272 SUNMatrix J =
nullptr;
273 SUNLinearSolver LS =
nullptr;
276 if (solve_jacobian_system)
278 auto KIN_mem = static_cast<KINMem>(kinsol_mem);
279 KIN_mem->kin_lsolve = t_kinsol_solve_jacobian<VectorType>;
282 KIN_mem->kin_lsetup = t_kinsol_setup_jacobian<VectorType>;
283 # if DEAL_II_SUNDIALS_VERSION_LT(3, 0, 0)
284 KIN_mem->kin_setupNonNull =
true;
290 # if DEAL_II_SUNDIALS_VERSION_GTE(3, 0, 0)
291 J = SUNDenseMatrix(system_size, system_size);
292 LS = SUNDenseLinearSolver(u_scale, J);
293 status = KINDlsSetLinearSolver(kinsol_mem, LS, J);
295 status = KINDense(kinsol_mem, system_size);
297 AssertKINSOL(status);
300 if (data.strategy == AdditionalData::newton ||
301 data.strategy == AdditionalData::linesearch)
302 Assert(residual, ExcFunctionNotProvided(
"residual"));
304 if (data.strategy == AdditionalData::fixed_point ||
305 data.strategy == AdditionalData::picard)
306 Assert(iteration_function, ExcFunctionNotProvided(
"iteration_function"));
309 status = KINSol(kinsol_mem, solution, data.strategy, u_scale, f_scale);
310 AssertKINSOL(status);
312 copy(initial_guess_and_solution, solution);
315 # ifdef DEAL_II_WITH_MPI
318 N_VDestroy_Parallel(solution);
319 N_VDestroy_Parallel(u_scale);
320 N_VDestroy_Parallel(f_scale);
325 N_VDestroy_Serial(solution);
326 N_VDestroy_Serial(u_scale);
327 N_VDestroy_Serial(f_scale);
331 status = KINGetNumNonlinSolvIters(kinsol_mem, &nniters);
332 AssertKINSOL(status);
334 # if DEAL_II_SUNDIALS_VERSION_GTE(3, 0, 0)
338 KINFree(&kinsol_mem);
340 return static_cast<unsigned int>(nniters);
343 template <
typename VectorType>
347 reinit_vector = [](VectorType &) {
348 AssertThrow(
false, ExcFunctionNotProvided(
"reinit_vector"));
355 # ifdef DEAL_II_WITH_MPI
357 # ifdef DEAL_II_WITH_TRILINOS
362 # ifdef DEAL_II_WITH_PETSC
363 # ifndef PETSC_USE_COMPLEX
373 DEAL_II_NAMESPACE_CLOSE