17 #include <deal.II/base/config.h> 19 #include <deal.II/sundials/ida.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 # ifdef DEAL_II_SUNDIALS_WITH_IDAS 39 # include <idas/idas_impl.h> 41 # include <ida/ida_impl.h> 47 DEAL_II_NAMESPACE_OPEN
55 template <
typename VectorType>
57 t_dae_residual(realtype tt,
63 IDA<VectorType> &solver = *
static_cast<IDA<VectorType> *
>(user_data);
67 solver.reinit_vector(*src_yy);
70 solver.reinit_vector(*src_yp);
73 solver.reinit_vector(*residual);
78 int err = solver.residual(tt, *src_yy, *src_yp, *residual);
87 template <
typename VectorType>
89 t_dae_lsetup(IDAMem IDA_mem,
101 IDA<VectorType> &solver =
102 *
static_cast<IDA<VectorType> *
>(IDA_mem->ida_user_data);
106 solver.reinit_vector(*src_yy);
109 solver.reinit_vector(*src_yp);
114 int err = solver.setup_jacobian(IDA_mem->ida_tn,
123 template <
typename VectorType>
125 t_dae_solve(IDAMem IDA_mem,
136 IDA<VectorType> &solver =
137 *
static_cast<IDA<VectorType> *
>(IDA_mem->ida_user_data);
141 solver.reinit_vector(*src);
144 solver.reinit_vector(*dst);
148 int err = solver.solve_jacobian_system(*src, *dst);
156 template <
typename VectorType>
166 Utilities::MPI::duplicate_communicator(mpi_comm))
171 template <
typename VectorType>
176 # ifdef DEAL_II_WITH_MPI 179 const int ierr = MPI_Comm_free(&communicator);
188 template <
typename VectorType>
192 unsigned int system_size = solution.size();
194 double t = data.initial_time;
195 double h = data.initial_step_size;
196 unsigned int step_number = 0;
204 # ifdef DEAL_II_WITH_MPI 207 const IndexSet is = solution.locally_owned_elements();
208 const std::size_t local_system_size = is.
n_elements();
210 yy = N_VNew_Parallel(communicator, local_system_size, system_size);
212 yp = N_VNew_Parallel(communicator, local_system_size, system_size);
214 diff_id = N_VNew_Parallel(communicator, local_system_size, system_size);
217 N_VNew_Parallel(communicator, local_system_size, system_size);
224 "Trying to use a serial code with a parallel vector."));
225 yy = N_VNew_Serial(system_size);
226 yp = N_VNew_Serial(system_size);
227 diff_id = N_VNew_Serial(system_size);
228 abs_tolls = N_VNew_Serial(system_size);
230 reset(data.initial_time, data.initial_step_size, solution, solution_dot);
232 double next_time = data.initial_time;
234 output_step(0, solution, solution_dot, 0);
236 while (t < data.final_time)
238 next_time += data.output_period;
240 status = IDASolve(ida_mem, next_time, &t, yy, yp, IDA_NORMAL);
243 status = IDAGetLastStep(ida_mem, &h);
247 copy(solution_dot, yp);
249 while (solver_should_restart(t, solution, solution_dot))
250 reset(t, h, solution, solution_dot);
254 output_step(t, solution, solution_dot, step_number);
258 # ifdef DEAL_II_WITH_MPI 261 N_VDestroy_Parallel(yy);
262 N_VDestroy_Parallel(yp);
263 N_VDestroy_Parallel(abs_tolls);
264 N_VDestroy_Parallel(diff_id);
269 N_VDestroy_Serial(yy);
270 N_VDestroy_Serial(yp);
271 N_VDestroy_Serial(abs_tolls);
272 N_VDestroy_Serial(diff_id);
278 template <
typename VectorType>
281 const double current_time_step,
282 VectorType & solution,
283 VectorType & solution_dot)
285 unsigned int system_size;
286 bool first_step = (current_time == data.initial_time);
291 ida_mem = IDACreate();
297 # ifdef DEAL_II_WITH_MPI 300 N_VDestroy_Parallel(yy);
301 N_VDestroy_Parallel(yp);
302 N_VDestroy_Parallel(abs_tolls);
303 N_VDestroy_Parallel(diff_id);
308 N_VDestroy_Serial(yy);
309 N_VDestroy_Serial(yp);
310 N_VDestroy_Serial(abs_tolls);
311 N_VDestroy_Serial(diff_id);
317 system_size = solution.size();
318 # ifdef DEAL_II_WITH_MPI 321 const IndexSet is = solution.locally_owned_elements();
322 const std::size_t local_system_size = is.
n_elements();
324 yy = N_VNew_Parallel(communicator, local_system_size, system_size);
326 yp = N_VNew_Parallel(communicator, local_system_size, system_size);
328 diff_id = N_VNew_Parallel(communicator, local_system_size, system_size);
331 N_VNew_Parallel(communicator, local_system_size, system_size);
336 yy = N_VNew_Serial(system_size);
337 yp = N_VNew_Serial(system_size);
338 diff_id = N_VNew_Serial(system_size);
339 abs_tolls = N_VNew_Serial(system_size);
343 copy(yp, solution_dot);
345 status = IDAInit(ida_mem, t_dae_residual<VectorType>, current_time, yy, yp);
348 if (get_local_tolerances)
350 copy(abs_tolls, get_local_tolerances());
351 status = IDASVtolerances(ida_mem, data.relative_tolerance, abs_tolls);
356 status = IDASStolerances(ida_mem,
357 data.relative_tolerance,
358 data.absolute_tolerance);
362 status = IDASetInitStep(ida_mem, current_time_step);
365 status = IDASetUserData(ida_mem,
this);
368 if (data.ic_type == AdditionalData::use_y_diff ||
369 data.reset_type == AdditionalData::use_y_diff ||
370 data.ignore_algebraic_terms_for_errors)
372 VectorType diff_comp_vector(solution);
373 diff_comp_vector = 0.0;
374 auto dc = differential_components();
375 for (
auto i = dc.begin(); i != dc.end(); ++i)
376 diff_comp_vector[*i] = 1.0;
378 copy(diff_id, diff_comp_vector);
379 status = IDASetId(ida_mem, diff_id);
383 status = IDASetSuppressAlg(ida_mem, data.ignore_algebraic_terms_for_errors);
387 status = IDASetStopTime(ida_mem, data.final_time);
390 status = IDASetMaxNonlinIters(ida_mem, data.maximum_non_linear_iterations);
394 auto IDA_mem =
static_cast<IDAMem
>(ida_mem);
396 IDA_mem->ida_lsetup = t_dae_lsetup<VectorType>;
397 IDA_mem->ida_lsolve = t_dae_solve<VectorType>;
398 # if DEAL_II_SUNDIALS_VERSION_LT(3, 0, 0) 399 IDA_mem->ida_setupNonNull =
true;
402 status = IDASetMaxOrd(ida_mem, data.maximum_order);
409 type = data.reset_type;
412 IDASetMaxNumItersIC(ida_mem, data.maximum_non_linear_iterations_ic);
415 if (type == AdditionalData::use_y_dot)
419 IDACalcIC(ida_mem, IDA_Y_INIT, current_time + current_time_step);
422 status = IDAGetConsistentIC(ida_mem, yy, yp);
426 copy(solution_dot, yp);
428 else if (type == AdditionalData::use_y_diff)
431 IDACalcIC(ida_mem, IDA_YA_YDP_INIT, current_time + current_time_step);
434 status = IDAGetConsistentIC(ida_mem, yy, yp);
438 copy(solution_dot, yp);
442 template <
typename VectorType>
446 reinit_vector = [](VectorType &) {
447 AssertThrow(
false, ExcFunctionNotProvided(
"reinit_vector"));
450 residual = [](
const double,
453 VectorType &) ->
int {
455 AssertThrow(
false, ExcFunctionNotProvided(
"residual"));
459 setup_jacobian = [](
const double,
462 const double) ->
int {
464 AssertThrow(
false, ExcFunctionNotProvided(
"setup_jacobian"));
468 solve_jacobian_system = [](
const VectorType &, VectorType &) ->
int {
470 AssertThrow(
false, ExcFunctionNotProvided(
"solve_jacobian_system"));
474 output_step = [](
const double,
477 const unsigned int) {
return; };
479 solver_should_restart =
480 [](
const double, VectorType &, VectorType &) ->
bool {
return false; };
482 differential_components = [&]() ->
IndexSet {
486 const unsigned int size = v->size();
487 return complete_index_set(size);
494 # ifdef DEAL_II_WITH_MPI 496 # ifdef DEAL_II_WITH_TRILINOS 499 # endif // DEAL_II_WITH_TRILINOS 501 # ifdef DEAL_II_WITH_PETSC 502 # ifndef PETSC_USE_COMPLEX 505 # endif // PETSC_USE_COMPLEX 506 # endif // DEAL_II_WITH_PETSC 508 # endif // DEAL_II_WITH_MPI 512 DEAL_II_NAMESPACE_CLOSE
514 #endif // DEAL_II_WITH_SUNDIALS void set_functions_to_trigger_an_assert()
#define AssertNothrow(cond, exc)
InitialConditionCorrection
void reset(const double t, const double h, VectorType &y, VectorType &yp)
#define AssertThrow(cond, exc)
IDA(const AdditionalData &data=AdditionalData(), const MPI_Comm mpi_comm=MPI_COMM_WORLD)
#define Assert(cond, exc)
unsigned int solve_dae(VectorType &solution, VectorType &solution_dot)
size_type n_elements() const
static ::ExceptionBase & ExcInternalError()