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
#define AssertNothrow(cond, exc)
void set_functions_to_trigger_an_assert()
#define AssertThrow(cond, exc)
#define Assert(cond, exc)
KINSOL(const AdditionalData &data=AdditionalData(), const MPI_Comm mpi_comm=MPI_COMM_WORLD)
unsigned int solve(VectorType &initial_guess_and_solution)
size_type n_elements() const
static ::ExceptionBase & ExcInternalError()