17 #include <deal.II/sundials/ida.h> 18 #include <deal.II/base/config.h> 20 #ifdef DEAL_II_WITH_SUNDIALS 22 #include <deal.II/base/utilities.h> 23 #include <deal.II/lac/block_vector.h> 24 #ifdef DEAL_II_WITH_TRILINOS 25 #include <deal.II/lac/trilinos_parallel_block_vector.h> 26 #include <deal.II/lac/trilinos_vector.h> 28 #ifdef DEAL_II_WITH_PETSC 29 #include <deal.II/lac/petsc_parallel_block_vector.h> 30 #include <deal.II/lac/petsc_parallel_vector.h> 32 #include <deal.II/base/utilities.h> 33 #include <deal.II/sundials/copy.h> 35 #ifdef DEAL_II_SUNDIALS_WITH_IDAS 36 #include <idas/idas_impl.h> 38 #include <ida/ida_impl.h> 44 DEAL_II_NAMESPACE_OPEN
52 template<
typename VectorType>
53 int t_dae_residual(realtype tt, N_Vector yy, N_Vector yp,
54 N_Vector rr,
void *user_data)
56 IDA<VectorType> &solver = *
static_cast<IDA<VectorType> *
>(user_data);
60 solver.reinit_vector(*src_yy);
63 solver.reinit_vector(*src_yp);
66 solver.reinit_vector(*residual);
71 int err = solver.residual(tt, *src_yy, *src_yp, *residual);
80 template<
typename VectorType>
81 int t_dae_lsetup(IDAMem IDA_mem,
93 IDA<VectorType> &solver = *
static_cast<IDA<VectorType> *
>(IDA_mem->ida_user_data);
97 solver.reinit_vector(*src_yy);
100 solver.reinit_vector(*src_yp);
105 int err = solver.setup_jacobian(IDA_mem->ida_tn,
114 template<
typename VectorType>
115 int t_dae_solve(IDAMem IDA_mem,
126 IDA<VectorType> &solver = *
static_cast<IDA<VectorType> *
>(IDA_mem->ida_user_data);
130 solver.reinit_vector(*src);
133 solver.reinit_vector(*dst);
137 int err = solver.solve_jacobian_system(*src,*dst);
145 template <
typename VectorType>
147 const MPI_Comm mpi_comm) :
156 Utilities::MPI::duplicate_communicator(mpi_comm))
161 template <
typename VectorType>
166 #ifdef DEAL_II_WITH_MPI 169 const int ierr = MPI_Comm_free(&communicator);
178 template <
typename VectorType>
180 VectorType &solution_dot)
183 unsigned int system_size = solution.size();
185 double t = data.initial_time;
186 double h = data.initial_step_size;
187 unsigned int step_number = 0;
195 #ifdef DEAL_II_WITH_MPI 198 const IndexSet is = solution.locally_owned_elements();
199 const size_t local_system_size = is.
n_elements();
201 yy = N_VNew_Parallel(communicator,
205 yp = N_VNew_Parallel(communicator,
209 diff_id = N_VNew_Parallel(communicator,
213 abs_tolls = N_VNew_Parallel(communicator,
222 yy = N_VNew_Serial(system_size);
223 yp = N_VNew_Serial(system_size);
224 diff_id = N_VNew_Serial(system_size);
225 abs_tolls = N_VNew_Serial(system_size);
227 reset(data.initial_time,
228 data.initial_step_size,
232 double next_time = data.initial_time;
234 output_step( 0, solution, solution_dot, 0);
236 while (t<data.final_time)
239 next_time += data.output_period;
241 status = IDASolve(ida_mem, next_time, &t, yy, yp, IDA_NORMAL);
244 status = IDAGetLastStep(ida_mem, &h);
248 copy(solution_dot, yp);
250 while (solver_should_restart(t, solution, solution_dot))
251 reset(t, h, solution, solution_dot);
255 output_step(t, solution, solution_dot, step_number);
259 #ifdef DEAL_II_WITH_MPI 262 N_VDestroy_Parallel(yy);
263 N_VDestroy_Parallel(yp);
264 N_VDestroy_Parallel(abs_tolls);
265 N_VDestroy_Parallel(diff_id);
270 N_VDestroy_Serial(yy);
271 N_VDestroy_Serial(yp);
272 N_VDestroy_Serial(abs_tolls);
273 N_VDestroy_Serial(diff_id);
279 template <
typename VectorType>
281 const double ¤t_time_step,
282 VectorType &solution,
283 VectorType &solution_dot)
286 unsigned int system_size;
287 bool first_step = (current_time == data.initial_time);
292 ida_mem = IDACreate();
298 #ifdef DEAL_II_WITH_MPI 301 N_VDestroy_Parallel(yy);
302 N_VDestroy_Parallel(yp);
303 N_VDestroy_Parallel(abs_tolls);
304 N_VDestroy_Parallel(diff_id);
309 N_VDestroy_Serial(yy);
310 N_VDestroy_Serial(yp);
311 N_VDestroy_Serial(abs_tolls);
312 N_VDestroy_Serial(diff_id);
318 system_size = solution.size();
319 #ifdef DEAL_II_WITH_MPI 322 const IndexSet is = solution.locally_owned_elements();
323 const size_t local_system_size = is.
n_elements();
325 yy = N_VNew_Parallel(communicator,
329 yp = N_VNew_Parallel(communicator,
333 diff_id = N_VNew_Parallel(communicator,
337 abs_tolls = N_VNew_Parallel(communicator,
345 yy = N_VNew_Serial(system_size);
346 yp = N_VNew_Serial(system_size);
347 diff_id = N_VNew_Serial(system_size);
348 abs_tolls = N_VNew_Serial(system_size);
352 copy(yp, solution_dot);
354 status = IDAInit(ida_mem, t_dae_residual<VectorType>, current_time, yy, yp);
357 if (get_local_tolerances)
359 copy(abs_tolls, get_local_tolerances());
360 status = IDASVtolerances(ida_mem, data.relative_tolerance, abs_tolls);
365 status = IDASStolerances(ida_mem, data.relative_tolerance, data.absolute_tolerance);
369 status = IDASetInitStep(ida_mem, current_time_step);
372 status = IDASetUserData(ida_mem, (
void *)
this);
375 if (data.ic_type == AdditionalData::use_y_diff ||
376 data.reset_type == AdditionalData::use_y_diff ||
377 data.ignore_algebraic_terms_for_errors)
379 VectorType diff_comp_vector(solution);
380 diff_comp_vector = 0.0;
381 auto dc = differential_components();
382 for (
auto i = dc.begin(); i != dc.end(); ++i)
383 diff_comp_vector[*i] = 1.0;
385 copy(diff_id, diff_comp_vector);
386 status = IDASetId(ida_mem, diff_id);
390 status = IDASetSuppressAlg(ida_mem, data.ignore_algebraic_terms_for_errors);
394 status = IDASetStopTime(ida_mem, data.final_time);
397 status = IDASetMaxNonlinIters(ida_mem, data.maximum_non_linear_iterations);
402 IDA_mem = (IDAMem) ida_mem;
404 IDA_mem->ida_lsetup = t_dae_lsetup<VectorType>;
405 IDA_mem->ida_lsolve = t_dae_solve<VectorType>;
406 #if DEAL_II_SUNDIALS_VERSION_LT(3,0,0) 407 IDA_mem->ida_setupNonNull =
true;
410 status = IDASetMaxOrd(ida_mem, data.maximum_order);
417 type = data.reset_type;
419 status = IDASetMaxNumItersIC(ida_mem, data.maximum_non_linear_iterations_ic);
422 if (type == AdditionalData::use_y_dot)
425 status = IDACalcIC(ida_mem, IDA_Y_INIT, current_time+current_time_step);
428 status = IDAGetConsistentIC(ida_mem, yy, yp);
432 copy(solution_dot, yp);
434 else if (type == AdditionalData::use_y_diff)
436 status = IDACalcIC(ida_mem, IDA_YA_YDP_INIT, current_time+current_time_step);
439 status = IDAGetConsistentIC(ida_mem, yy, yp);
443 copy(solution_dot, yp);
447 template<
typename VectorType>
451 reinit_vector = [](VectorType &)
453 AssertThrow(
false, ExcFunctionNotProvided(
"reinit_vector"));
456 residual = [](
const double,
462 AssertThrow(
false, ExcFunctionNotProvided(
"residual"));
466 setup_jacobian = [](
const double,
472 AssertThrow(
false, ExcFunctionNotProvided(
"setup_jacobian"));
476 solve_jacobian_system = [](
const VectorType &,
480 AssertThrow(
false, ExcFunctionNotProvided(
"solve_jacobian_system"));
484 output_step = [](
const double,
492 solver_should_restart = [](
const double,
499 differential_components = [&]() ->
IndexSet 504 const unsigned int size = v->size();
505 return complete_index_set(size);
512 #ifdef DEAL_II_WITH_MPI 514 #ifdef DEAL_II_WITH_TRILINOS 517 #endif // DEAL_II_WITH_TRILINOS 519 #ifdef DEAL_II_WITH_PETSC 520 #ifndef PETSC_USE_COMPLEX 523 #endif // PETSC_USE_COMPLEX 524 #endif // DEAL_II_WITH_PETSC 526 #endif //DEAL_II_WITH_MPI 530 DEAL_II_NAMESPACE_CLOSE
532 #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()