21 #ifdef DEAL_II_WITH_SUNDIALS
26 # ifdef DEAL_II_WITH_TRILINOS
30 # ifdef DEAL_II_WITH_PETSC
37 # ifdef DEAL_II_SUNDIALS_WITH_IDAS
38 # include <idas/idas_impl.h>
40 # include <ida/ida_impl.h>
54 template <
typename VectorType>
56 t_dae_residual(realtype tt,
62 IDA<VectorType> &solver = *
static_cast<IDA<VectorType> *
>(user_data);
66 solver.reinit_vector(*src_yy);
69 solver.reinit_vector(*src_yp);
72 solver.reinit_vector(*residual);
77 int err = solver.residual(tt, *src_yy, *src_yp, *residual);
86 template <
typename VectorType>
88 t_dae_lsetup(IDAMem IDA_mem,
100 IDA<VectorType> &solver =
101 *
static_cast<IDA<VectorType> *
>(IDA_mem->ida_user_data);
105 solver.reinit_vector(*src_yy);
108 solver.reinit_vector(*src_yp);
113 int err = solver.setup_jacobian(IDA_mem->ida_tn,
122 template <
typename VectorType>
124 t_dae_solve(IDAMem IDA_mem,
135 IDA<VectorType> &solver =
136 *
static_cast<IDA<VectorType> *
>(IDA_mem->ida_user_data);
140 solver.reinit_vector(*src);
143 solver.reinit_vector(*dst);
147 int err = solver.solve_jacobian_system(*src, *dst);
155 template <
typename VectorType>
170 template <
typename VectorType>
175 # ifdef DEAL_II_WITH_MPI
178 const int ierr = MPI_Comm_free(&communicator);
187 template <
typename VectorType>
191 unsigned int system_size = solution.size();
193 double t = data.initial_time;
194 double h = data.initial_step_size;
195 unsigned int step_number = 0;
203 # ifdef DEAL_II_WITH_MPI
206 const IndexSet is = solution.locally_owned_elements();
207 const std::size_t local_system_size = is.
n_elements();
209 yy = N_VNew_Parallel(communicator, local_system_size, system_size);
211 yp = N_VNew_Parallel(communicator, local_system_size, system_size);
213 diff_id = N_VNew_Parallel(communicator, local_system_size, system_size);
216 N_VNew_Parallel(communicator, local_system_size, system_size);
223 "Trying to use a serial code with a parallel vector."));
224 yy = N_VNew_Serial(system_size);
225 yp = N_VNew_Serial(system_size);
226 diff_id = N_VNew_Serial(system_size);
227 abs_tolls = N_VNew_Serial(system_size);
229 reset(data.initial_time, data.initial_step_size, solution, solution_dot);
231 double next_time = data.initial_time;
233 output_step(0, solution, solution_dot, 0);
235 while (t < data.final_time)
237 next_time += data.output_period;
239 status = IDASolve(ida_mem, next_time, &t, yy, yp, IDA_NORMAL);
242 status = IDAGetLastStep(ida_mem, &h);
246 copy(solution_dot, yp);
248 while (solver_should_restart(t, solution, solution_dot))
249 reset(t, h, solution, solution_dot);
253 output_step(t, solution, solution_dot, step_number);
257 # ifdef DEAL_II_WITH_MPI
260 N_VDestroy_Parallel(yy);
261 N_VDestroy_Parallel(yp);
262 N_VDestroy_Parallel(abs_tolls);
263 N_VDestroy_Parallel(diff_id);
268 N_VDestroy_Serial(yy);
269 N_VDestroy_Serial(yp);
270 N_VDestroy_Serial(abs_tolls);
271 N_VDestroy_Serial(diff_id);
277 template <
typename VectorType>
280 const double current_time_step,
284 unsigned int system_size;
285 bool first_step = (current_time == data.initial_time);
290 ida_mem = IDACreate();
296 # ifdef DEAL_II_WITH_MPI
299 N_VDestroy_Parallel(yy);
300 N_VDestroy_Parallel(yp);
301 N_VDestroy_Parallel(abs_tolls);
302 N_VDestroy_Parallel(diff_id);
307 N_VDestroy_Serial(yy);
308 N_VDestroy_Serial(yp);
309 N_VDestroy_Serial(abs_tolls);
310 N_VDestroy_Serial(diff_id);
316 system_size = solution.size();
317 # ifdef DEAL_II_WITH_MPI
320 const IndexSet is = solution.locally_owned_elements();
321 const std::size_t local_system_size = is.
n_elements();
323 yy = N_VNew_Parallel(communicator, local_system_size, system_size);
325 yp = N_VNew_Parallel(communicator, local_system_size, system_size);
327 diff_id = N_VNew_Parallel(communicator, local_system_size, system_size);
330 N_VNew_Parallel(communicator, local_system_size, system_size);
335 yy = N_VNew_Serial(system_size);
336 yp = N_VNew_Serial(system_size);
337 diff_id = N_VNew_Serial(system_size);
338 abs_tolls = N_VNew_Serial(system_size);
342 copy(yp, solution_dot);
344 status = IDAInit(ida_mem, t_dae_residual<VectorType>, current_time, yy, yp);
347 if (get_local_tolerances)
349 copy(abs_tolls, get_local_tolerances());
350 status = IDASVtolerances(ida_mem, data.relative_tolerance, abs_tolls);
355 status = IDASStolerances(ida_mem,
356 data.relative_tolerance,
357 data.absolute_tolerance);
361 status = IDASetInitStep(ida_mem, current_time_step);
364 status = IDASetUserData(ida_mem,
this);
367 if (data.ic_type == AdditionalData::use_y_diff ||
368 data.reset_type == AdditionalData::use_y_diff ||
369 data.ignore_algebraic_terms_for_errors)
372 diff_comp_vector = 0.0;
373 auto dc = differential_components();
374 for (
auto i = dc.begin(); i != dc.end(); ++i)
375 diff_comp_vector[*i] = 1.0;
377 copy(diff_id, diff_comp_vector);
378 status = IDASetId(ida_mem, diff_id);
382 status = IDASetSuppressAlg(ida_mem, data.ignore_algebraic_terms_for_errors);
386 status = IDASetStopTime(ida_mem, data.final_time);
389 status = IDASetMaxNonlinIters(ida_mem, data.maximum_non_linear_iterations);
393 auto IDA_mem =
static_cast<IDAMem
>(ida_mem);
395 IDA_mem->ida_lsetup = t_dae_lsetup<VectorType>;
396 IDA_mem->ida_lsolve = t_dae_solve<VectorType>;
397 # if DEAL_II_SUNDIALS_VERSION_LT(3, 0, 0)
398 IDA_mem->ida_setupNonNull =
true;
401 status = IDASetMaxOrd(ida_mem, data.maximum_order);
408 type = data.reset_type;
411 IDASetMaxNumItersIC(ida_mem, data.maximum_non_linear_iterations_ic);
414 if (type == AdditionalData::use_y_dot)
418 IDACalcIC(ida_mem, IDA_Y_INIT, current_time + current_time_step);
421 status = IDAGetConsistentIC(ida_mem, yy, yp);
425 copy(solution_dot, yp);
427 else if (type == AdditionalData::use_y_diff)
430 IDACalcIC(ida_mem, IDA_YA_YDP_INIT, current_time + current_time_step);
433 status = IDAGetConsistentIC(ida_mem, yy, yp);
437 copy(solution_dot, yp);
441 template <
typename VectorType>
446 AssertThrow(
false, ExcFunctionNotProvided(
"reinit_vector"));
449 residual = [](
const double,
454 AssertThrow(
false, ExcFunctionNotProvided(
"residual"));
458 setup_jacobian = [](
const double,
463 AssertThrow(
false, ExcFunctionNotProvided(
"setup_jacobian"));
469 AssertThrow(
false, ExcFunctionNotProvided(
"solve_jacobian_system"));
473 output_step = [](
const double,
476 const unsigned int) {
return; };
478 solver_should_restart =
481 differential_components = [&]() ->
IndexSet {
485 const unsigned int size = v->size();
493 # ifdef DEAL_II_WITH_MPI
495 # ifdef DEAL_II_WITH_TRILINOS
498 # endif // DEAL_II_WITH_TRILINOS
500 # ifdef DEAL_II_WITH_PETSC
501 # ifndef PETSC_USE_COMPLEX
504 # endif // PETSC_USE_COMPLEX
505 # endif // DEAL_II_WITH_PETSC
507 # endif // DEAL_II_WITH_MPI
513 #endif // DEAL_II_WITH_SUNDIALS