Block-Structured AMR Software Framework
AMReX_SundialsIntegrator.H
Go to the documentation of this file.
1 #ifndef AMREX_SUNDIALS_INTEGRATOR_H
2 #define AMREX_SUNDIALS_INTEGRATOR_H
3 
4 #include <functional>
5 
6 #include <AMReX_Config.H>
7 #include <AMReX_REAL.H>
8 #include <AMReX_Vector.H>
9 #include <AMReX_ParmParse.H>
10 #include <AMReX_IntegratorBase.H>
11 #include <AMReX_NVector_MultiFab.H>
12 #include <AMReX_Sundials.H>
13 
14 #include <nvector/nvector_manyvector.h>
15 #include <sunlinsol/sunlinsol_spgmr.h>
16 #include <arkode/arkode_arkstep.h>
17 #include <arkode/arkode_mristep.h>
18 
19 namespace amrex {
20 
22  // ERK or DIRK right-hand side function
23  // EX-MRI or IM-MRI slow right-hand side function
24  std::function<int(amrex::Real, N_Vector, N_Vector, void*)> f;
25 
26  // ImEx-RK right-hand side functions
27  // ImEx-MRI slow right-hand side functions
28  std::function<int(amrex::Real, N_Vector, N_Vector, void*)> fi;
29  std::function<int(amrex::Real, N_Vector, N_Vector, void*)> fe;
30 
31  // MRI fast time scale right-hand side function
32  std::function<int(amrex::Real, N_Vector, N_Vector, void*)> ff;
33 
34  // Post stage and step actions
35  std::function<int(amrex::Real, N_Vector, void*)> post_stage;
36  std::function<int(amrex::Real, N_Vector, void*)> post_step;
37 
38  // Post fast stage and step actions
39  std::function<int(amrex::Real, N_Vector, void*)> post_fast_stage;
40  std::function<int(amrex::Real, N_Vector, void*)> post_fast_step;
41 };
42 
43 namespace SundialsUserFun {
44  static int f (amrex::Real t, N_Vector y_data, N_Vector y_rhs, void *user_data) {
45  SundialsUserData* udata = static_cast<SundialsUserData*>(user_data);
46  return udata->f(t, y_data, y_rhs, user_data);
47  }
48 
49  static int fi (amrex::Real t, N_Vector y_data, N_Vector y_rhs, void *user_data) {
50  SundialsUserData* udata = static_cast<SundialsUserData*>(user_data);
51  return udata->fi(t, y_data, y_rhs, user_data);
52  }
53 
54  static int fe (amrex::Real t, N_Vector y_data, N_Vector y_rhs, void *user_data) {
55  SundialsUserData* udata = static_cast<SundialsUserData*>(user_data);
56  return udata->fe(t, y_data, y_rhs, user_data);
57  }
58 
59  static int ff (amrex::Real t, N_Vector y_data, N_Vector y_rhs, void *user_data) {
60  SundialsUserData* udata = static_cast<SundialsUserData*>(user_data);
61  return udata->ff(t, y_data, y_rhs, user_data);
62  }
63 
64  static int post_stage (amrex::Real t, N_Vector y_data, void *user_data) {
65  SundialsUserData* udata = static_cast<SundialsUserData*>(user_data);
66  return udata->post_stage(t, y_data, user_data);
67  }
68 
69  static int post_step (amrex::Real t, N_Vector y_data, void *user_data) {
70  SundialsUserData* udata = static_cast<SundialsUserData*>(user_data);
71  return udata->post_step(t, y_data, user_data);
72  }
73 
74  static int post_fast_stage (amrex::Real t, N_Vector y_data, void *user_data) {
75  SundialsUserData* udata = static_cast<SundialsUserData*>(user_data);
76  return udata->post_fast_stage(t, y_data, user_data);
77  }
78 
79  static int post_fast_step (amrex::Real t, N_Vector y_data, void *user_data) {
80  SundialsUserData* udata = static_cast<SundialsUserData*>(user_data);
81  return udata->post_fast_step(t, y_data, user_data);
82  }
83 }
84 
85 template<class T>
87 {
88 private:
90 
91  // Method type: ERK, DIRK, IMEX-RK, EX-MRI, IM-MRI, IMEX-MRI
92  std::string type = "ERK";
93 
94  // Use SUNDIALS default methods
95  std::string method = "DEFAULT";
96  std::string method_e = "DEFAULT";
97  std::string method_i = "DEFAULT";
98 
99  // Fast method type (ERK or DIRK) and method
100  std::string fast_type = "ERK";
101  std::string fast_method = "DEFAULT";
102 
103  // SUNDIALS package flags, set based on type
104  bool use_ark = false;
105  bool use_mri = false;
106 
107  // structure for interfacing with user-supplied functions
109 
110  // SUNDIALS context
111  //
112  // We should probably use context created by amrex:sundials::Initialize but
113  // that context is not MPI-aware
114  ::sundials::Context sunctx;
115 
116  // Single rate or slow time scale
117  void *arkode_mem = nullptr;
118  SUNLinearSolver LS = nullptr;
119 
120  // Fast time scale
121  void *arkode_fast_mem = nullptr;
122  MRIStepInnerStepper fast_stepper = nullptr;
123  SUNLinearSolver fast_LS = nullptr;
124 
126  {
127  amrex::ParmParse pp("integration.sundials");
128 
129  pp.query("type", type);
130  pp.query("method", method);
131  pp.query("method_e", method);
132  pp.query("method_i", method);
133 
134  pp.query("fast_type", fast_type);
135  pp.query("fast_method", fast_method);
136 
137  if (type == "ERK" || type == "DIRK" || type == "IMEX-RK") {
138  use_ark = true;
139  }
140  else if (type == "EX-MRI" || type == "IM-MRI" || type == "IMEX-MRI") {
141  use_mri = true;
142  }
143  else {
144  std::string msg("Unknown method type: ");
145  msg += type;
146  amrex::Error(msg.c_str());
147  }
148  }
149 
150  void SetupRK (amrex::Real time, N_Vector y_data)
151  {
152  // Create integrator and select method
153  if (type == "ERK") {
154  amrex::Print() << "SUNDIALS ERK time integrator\n";
155  arkode_mem = ARKStepCreate(SundialsUserFun::f, nullptr, time, y_data, sunctx);
156 
157  if (method != "DEFAULT") {
158  amrex::Print() << "SUNDIALS ERK method " << method << "\n";
159  ARKStepSetTableName(arkode_mem, "ARKODE_DIRK_NONE", method.c_str());
160  }
161  }
162  else if (type == "DIRK") {
163  amrex::Print() << "SUNDIALS DIRK time integrator\n";
164  arkode_mem = ARKStepCreate(nullptr, SundialsUserFun::f, time, y_data, sunctx);
165 
166  if (method != "DEFAULT") {
167  amrex::Print() << "SUNDIALS DIRK method " << method << "\n";
168  ARKStepSetTableName(arkode_mem, method.c_str(), "ARKODE_ERK_NONE");
169  }
170  }
171  else if (type == "IMEX-RK") {
172  amrex::Print() << "SUNDIALS IMEX time integrator\n";
173  arkode_mem = ARKStepCreate(SundialsUserFun::fe, SundialsUserFun::fi, time, y_data, sunctx);
174 
175  if (method_e != "DEFAULT" && method_i != "DEFAULT")
176  {
177  amrex::Print() << "SUNDIALS IMEX method " << method_i << " and "
178  << method_e << "\n";
179  ARKStepSetTableName(arkode_mem, method_i.c_str(), method_e.c_str());
180  }
181  }
182 
183  // Attach structure with user-supplied function wrappers
184  ARKStepSetUserData(arkode_mem, &udata);
185 
186  // Set integrator tolerances
187  ARKStepSStolerances(arkode_mem, BaseT::rel_tol, BaseT::abs_tol);
188 
189  // Create and attach linear solver for implicit methods
190  if (type == "DIRK" || type == "IMEX-RK") {
191  LS = SUNLinSol_SPGMR(y_data, SUN_PREC_NONE, 0, sunctx);
192  ARKStepSetLinearSolver(arkode_mem, LS, nullptr);
193  }
194 
195  // Set post stage and step function
196  ARKStepSetPostprocessStageFn(arkode_mem, SundialsUserFun::post_stage);
197  ARKStepSetPostprocessStepFn(arkode_mem, SundialsUserFun::post_step);
198  }
199 
200  void SetupMRI (amrex::Real time, N_Vector y_data)
201  {
202  // Create the fast integrator and select method
203  if (fast_type == "ERK") {
204  amrex::Print() << "SUNDIALS ERK time integrator\n";
205  arkode_fast_mem = ARKStepCreate(SundialsUserFun::ff, nullptr, time, y_data, sunctx);
206 
207  if (method != "DEFAULT") {
208  amrex::Print() << "SUNDIALS ERK method " << method << "\n";
209  ARKStepSetTableName(arkode_fast_mem, "ARKODE_DIRK_NONE", fast_method.c_str());
210  }
211  }
212  else if (fast_type == "DIRK") {
213  amrex::Print() << "SUNDIALS DIRK time integrator\n";
214  arkode_fast_mem = ARKStepCreate(nullptr, SundialsUserFun::ff, time, y_data, sunctx);
215 
216  if (method != "DEFAULT") {
217  amrex::Print() << "SUNDIALS DIRK method " << method << "\n";
218  ARKStepSetTableName(arkode_fast_mem, fast_method.c_str(), "ARKODE_ERK_NONE");
219  }
220 
221  fast_LS = SUNLinSol_SPGMR(y_data, SUN_PREC_NONE, 0, sunctx);
222  ARKStepSetLinearSolver(arkode_fast_mem, fast_LS, nullptr);
223  }
224 
225  // Attach structure with user-supplied function wrappers
226  ARKStepSetUserData(arkode_fast_mem, &udata);
227 
228  // Set integrator tolerances
230 
231  // Set post stage and step function
232  ARKStepSetPostprocessStageFn(arkode_fast_mem, SundialsUserFun::post_fast_stage);
233  ARKStepSetPostprocessStepFn(arkode_fast_mem, SundialsUserFun::post_fast_step);
234 
235  // Wrap fast integrator as an inner stepper
236  ARKStepCreateMRIStepInnerStepper(arkode_fast_mem, &fast_stepper);
237 
238  // Create slow integrator
239  if (type == "EX-MRI") {
240  amrex::Print() << "SUNDIALS ERK time integrator\n";
241  arkode_mem = MRIStepCreate(SundialsUserFun::f, nullptr, time, y_data,
243  }
244  else if (type == "IM-MRI") {
245  amrex::Print() << "SUNDIALS DIRK time integrator\n";
246  arkode_mem = MRIStepCreate(nullptr, SundialsUserFun::f, time, y_data,
248  }
249  else if (type == "IMEX-MRI") {
250  amrex::Print() << "SUNDIALS IMEX time integrator\n";
252  time, y_data, fast_stepper, sunctx);
253  }
254 
255  // Set method
256  if (method != "DEFAULT") {
257  MRIStepCoupling MRIC = MRIStepCoupling_LoadTableByName(method.c_str());
258  MRIStepSetCoupling(arkode_mem, MRIC);
259  MRIStepCoupling_Free(MRIC);
260  }
261 
262  // Attach structure with user-supplied function wrappers
263  MRIStepSetUserData(arkode_mem, &udata);
264 
265  // Set integrator tolerances
266  MRIStepSStolerances(arkode_mem, BaseT::rel_tol, BaseT::abs_tol);
267 
268  // Create and attach linear solver
269  if (type == "IM-MRI" || type == "IMEX-MRI") {
270  LS = SUNLinSol_SPGMR(y_data, SUN_PREC_NONE, 0, sunctx);
271  MRIStepSetLinearSolver(arkode_mem, LS, nullptr);
272  }
273 
274  // Set post stage and step function
275  MRIStepSetPostprocessStageFn(arkode_mem, SundialsUserFun::post_stage);
276  MRIStepSetPostprocessStepFn(arkode_mem, SundialsUserFun::post_step);
277  }
278 
279  // -------------------------------------
280  // Vector<MultiFab> / N_Vector Utilities
281  // -------------------------------------
282 
283  // Utility to unpack a SUNDIALS ManyVector into a vector of MultiFabs
284  void unpack_vector (N_Vector y_data, amrex::Vector<amrex::MultiFab>& S_data)
285  {
286  const int num_vecs = N_VGetNumSubvectors_ManyVector(y_data);
287  S_data.resize(num_vecs);
288 
289  for(int i = 0; i < num_vecs; i++)
290  {
291  S_data.at(i) = amrex::MultiFab(*amrex::sundials::getMFptr(N_VGetSubvector_ManyVector(y_data, i)),
293  0,
294  amrex::sundials::getMFptr(N_VGetSubvector_ManyVector(y_data, i))->nComp());
295  }
296  };
297 
298  // Utility to wrap vector of MultiFabs as a SUNDIALS ManyVector
300  {
301  auto get_length = [&](int index) -> sunindextype {
302  auto* p_mf = &S_data[index];
303  return p_mf->nComp() * (p_mf->boxArray()).numPts();
304  };
305 
306  sunindextype NV_len = S_data.size();
307  N_Vector* NV_array = new N_Vector[NV_len];
308 
309  for (int i = 0; i < NV_len; ++i) {
310  NV_array[i] = amrex::sundials::N_VMake_MultiFab(get_length(i),
311  &S_data[i], &sunctx);
312  }
313 
314  N_Vector y_data = N_VNew_ManyVector(NV_len, NV_array, sunctx);
315 
316  delete[] NV_array;
317 
318  return y_data;
319  };
320 
321  // Utility to wrap vector of MultiFabs as a SUNDIALS ManyVector
322  N_Vector copy_data (const amrex::Vector<amrex::MultiFab>& S_data)
323  {
324  auto get_length = [&](int index) -> sunindextype {
325  auto* p_mf = &S_data[index];
326  return p_mf->nComp() * (p_mf->boxArray()).numPts();
327  };
328 
329  sunindextype NV_len = S_data.size();
330  N_Vector* NV_array = new N_Vector[NV_len];
331 
332  for (int i = 0; i < NV_len; ++i) {
333  NV_array[i] = amrex::sundials::N_VNew_MultiFab(get_length(i),
334  S_data[i].boxArray(),
335  S_data[i].DistributionMap(),
336  S_data[i].nComp(),
337  S_data[i].nGrow(),
338  &sunctx);
339 
341  S_data[i],
342  0,
343  0,
344  S_data[i].nComp(),
345  S_data[i].nGrow());
346  }
347 
348  N_Vector y_data = N_VNew_ManyVector(NV_len, NV_array, sunctx);
349 
350  delete[] NV_array;
351 
352  return y_data;
353  };
354 
355  // -----------------------------
356  // MultiFab / N_Vector Utilities
357  // -----------------------------
358 
359  // Utility to unpack a SUNDIALS Vector into a MultiFab
360  void unpack_vector (N_Vector y_data, amrex::MultiFab& S_data)
361  {
362  S_data = amrex::MultiFab(*amrex::sundials::getMFptr(y_data),
364  0,
365  amrex::sundials::getMFptr(y_data)->nComp());
366  };
367 
368  // Utility to wrap a MultiFab as a SUNDIALS Vector
369  N_Vector wrap_data (amrex::MultiFab& S_data)
370  {
371  return amrex::sundials::N_VMake_MultiFab(S_data.nComp() * S_data.boxArray().numPts(),
372  &S_data, &sunctx);
373  };
374 
375  // Utility to wrap a MultiFab as a SUNDIALS Vector
376  N_Vector copy_data (const amrex::MultiFab& S_data)
377  {
378  N_Vector y_data = amrex::sundials::N_VNew_MultiFab(S_data.nComp() * S_data.boxArray().numPts(),
379  S_data.boxArray(),
380  S_data.DistributionMap(),
381  S_data.nComp(),
382  S_data.nGrow(),
383  &sunctx);
384 
386  S_data,
387  0,
388  0,
389  S_data.nComp(),
390  S_data.nGrow());
391 
392  return y_data;
393  };
394 
395 public:
397 
398  SundialsIntegrator (const T& S_data, const amrex::Real time = 0.0)
399  {
400  initialize(S_data, time);
401  }
402 
403  void initialize (const T& S_data, const amrex::Real time = 0.0)
404  {
407 #if defined(SUNDIALS_VERSION_MAJOR) && (SUNDIALS_VERSION_MAJOR < 7)
408 # ifdef AMREX_USE_MPI
409  sunctx = ::sundials::Context(&mpi_comm);
410 # else
411  sunctx = ::sundials::Context(nullptr);
412 # endif
413 #else
414 # ifdef AMREX_USE_MPI
415  sunctx = ::sundials::Context(mpi_comm);
416 # else
417  sunctx = ::sundials::Context(SUN_COMM_NULL);
418 # endif
419 #endif
420 
421  // Right-hand side function wrappers
422  udata.f = [&](amrex::Real rhs_time, N_Vector y_data, N_Vector y_rhs,
423  void * /* user_data */) -> int {
424 
425  T S_data;
426  unpack_vector(y_data, S_data);
427 
428  T S_rhs;
429  unpack_vector(y_rhs, S_rhs);
430 
431  BaseT::Rhs(S_rhs, S_data, rhs_time);
432 
433  return 0;
434  };
435 
436  udata.fi = [&](amrex::Real rhs_time, N_Vector y_data, N_Vector y_rhs,
437  void * /* user_data */) -> int {
438 
439  T S_data;
440  unpack_vector(y_data, S_data);
441 
442  T S_rhs;
443  unpack_vector(y_rhs, S_rhs);
444 
445  BaseT::RhsIm(S_rhs, S_data, rhs_time);
446 
447  return 0;
448  };
449 
450  udata.fe = [&](amrex::Real rhs_time, N_Vector y_data, N_Vector y_rhs,
451  void * /* user_data */) -> int {
452 
453  T S_data;
454  unpack_vector(y_data, S_data);
455 
456  T S_rhs;
457  unpack_vector(y_rhs, S_rhs);
458 
459  BaseT::RhsEx(S_rhs, S_data, rhs_time);
460 
461  return 0;
462  };
463 
464  udata.ff = [&](amrex::Real rhs_time, N_Vector y_data, N_Vector y_rhs,
465  void * /* user_data */) -> int {
466 
467  T S_data;
468  unpack_vector(y_data, S_data);
469 
470  T S_rhs;
471  unpack_vector(y_rhs, S_rhs);
472 
473  BaseT::RhsFast(S_rhs, S_data, rhs_time);
474 
475  return 0;
476  };
477 
478  udata.post_stage = [&](amrex::Real time, N_Vector y_data,
479  void * /* user_data */) -> int {
480 
481  T S_data;
482  unpack_vector(y_data, S_data);
483 
484  BaseT::post_stage_action(S_data, time);
485 
486  return 0;
487  };
488 
489  udata.post_step = [&](amrex::Real time, N_Vector y_data,
490  void * /* user_data */) -> int {
491 
492  T S_data;
493  unpack_vector(y_data, S_data);
494 
495  BaseT::post_step_action(S_data, time);
496 
497  return 0;
498  };
499 
500  udata.post_fast_stage = [&](amrex::Real time, N_Vector y_data,
501  void * /* user_data */) -> int {
502 
503  T S_data;
504  unpack_vector(y_data, S_data);
505 
506  BaseT::post_fast_stage_action(S_data, time);
507 
508  return 0;
509  };
510 
511  udata.post_fast_step = [&](amrex::Real time, N_Vector y_data,
512  void * /* user_data */) -> int {
513 
514  T S_data;
515  unpack_vector(y_data, S_data);
516 
517  BaseT::post_fast_step_action(S_data, time);
518 
519  return 0;
520  };
521 
522  N_Vector y_data = copy_data(S_data); // ideally just wrap and ignore const
523 
524  if (use_ark) {
525  SetupRK(time, y_data);
526  }
527  else if (use_mri)
528  {
529  SetupMRI(time, y_data);
530  }
531 
532  N_VDestroy(y_data);
533  }
534 
535  virtual ~SundialsIntegrator () {
536  // Clean up allocated memory
537  SUNLinSolFree(LS);
538  SUNLinSolFree(fast_LS);
539  MRIStepInnerStepper_Free(&fast_stepper);
540  MRIStepFree(&arkode_fast_mem);
541  ARKStepFree(&arkode_mem);
542  }
543 
544  amrex::Real advance (T& S_old, T& S_new, amrex::Real time, const amrex::Real dt) override
545  {
546  amrex::Real tout = time + dt;
547  amrex::Real tret;
548 
549  N_Vector y_old = wrap_data(S_old);
550  N_Vector y_new = wrap_data(S_new);
551 
552  if (use_ark) {
553  ARKStepReset(arkode_mem, time, y_old); // should probably resize
554  ARKStepSetFixedStep(arkode_mem, dt);
555  int flag = ARKStepEvolve(arkode_mem, tout, y_new, &tret, ARK_ONE_STEP);
556  AMREX_ALWAYS_ASSERT(flag >= 0);
557  }
558  else if (use_mri) {
559  MRIStepReset(arkode_mem, time, y_old); // should probably resize -- need to resize inner stepper
560  MRIStepSetFixedStep(arkode_mem, dt);
561  int flag = MRIStepEvolve(arkode_mem, tout, y_new, &tret, ARK_ONE_STEP);
562  AMREX_ALWAYS_ASSERT(flag >= 0);
563  } else {
564  Error("SUNDIALS integrator type not specified.");
565  }
566 
567  N_VDestroy(y_old);
568  N_VDestroy(y_new);
569 
570  return dt;
571  }
572 
573  void evolve (T& S_out, const amrex::Real time_out) override
574  {
575  int flag = 0; // SUNDIALS return status
576  amrex::Real time_ret; // SUNDIALS return time
577 
578  N_Vector y_out = wrap_data(S_out);
579 
580  if (use_ark) {
582  ARKStepSetFixedStep(arkode_mem, BaseT::time_step);
583  }
584  flag = ARKStepEvolve(arkode_mem, time_out, y_out, &time_ret, ARK_NORMAL);
585  AMREX_ALWAYS_ASSERT(flag >= 0);
586  }
587  else if (use_mri) {
589  MRIStepSetFixedStep(arkode_mem, BaseT::time_step);
590  }
592  ARKStepSetFixedStep(arkode_fast_mem, BaseT::fast_time_step);
593  }
594  flag = MRIStepEvolve(arkode_mem, time_out, y_out, &time_ret, ARK_NORMAL);
595  AMREX_ALWAYS_ASSERT(flag >= 0);
596  } else {
597  Error("SUNDIALS integrator type not specified.");
598  }
599 
600  N_VDestroy(y_out);
601  }
602 
603  void time_interpolate (const T& /* S_new */, const T& /* S_old */, amrex::Real /* timestep_fraction */, T& /* data */) override {}
604 
605  void map_data (std::function<void(T&)> /* Map */) override {}
606 };
607 
608 }
609 
610 #endif
#define AMREX_ALWAYS_ASSERT(EX)
Definition: AMReX_BLassert.H:50
amrex::ParmParse pp
Input file parser instance for the given namespace.
Definition: AMReX_HypreIJIface.cpp:15
int MPI_Comm
Definition: AMReX_ccse-mpi.H:47
Long numPts() const noexcept
Returns the total number of cells contained in all boxes in the BoxArray.
const BoxArray & boxArray() const noexcept
Return a constant reference to the BoxArray that defines the valid region associated with this FabArr...
Definition: AMReX_FabArrayBase.H:94
int nGrow(int direction=0) const noexcept
Return the grow factor that defines the region of definition.
Definition: AMReX_FabArrayBase.H:77
const DistributionMapping & DistributionMap() const noexcept
Return constant reference to associated DistributionMapping.
Definition: AMReX_FabArrayBase.H:130
int nComp() const noexcept
Return number of variables (aka components) associated with each point.
Definition: AMReX_FabArrayBase.H:82
Definition: AMReX_IntegratorBase.H:163
bool use_adaptive_fast_time_step
Flag to enable/disable adaptive time stepping at the fast time scale in multirate methods (bool)
Definition: AMReX_IntegratorBase.H:232
amrex::Real fast_rel_tol
Relative tolerance for adaptive time stepping at the fast time scale (Real)
Definition: AMReX_IntegratorBase.H:264
amrex::Real rel_tol
Relative tolerance for adaptive time stepping (Real)
Definition: AMReX_IntegratorBase.H:253
std::function< void(T &, amrex::Real)> post_fast_stage_action
The post_stage_action function is called by the integrator on the computed stage just after it is com...
Definition: AMReX_IntegratorBase.H:204
amrex::Real fast_abs_tol
Absolute tolerance for adaptive time stepping at the fast time scale (Real)
Definition: AMReX_IntegratorBase.H:270
amrex::Real fast_time_step
Current integrator fast time scale time step size with multirate methods (Real)
Definition: AMReX_IntegratorBase.H:238
std::function< void(T &rhs, T &state, const amrex::Real time)> RhsEx
RhsEx is the explicit right-hand-side function an ImEx integrator will use.
Definition: AMReX_IntegratorBase.H:180
std::function< void(T &, amrex::Real)> post_step_action
The post_step_action function is called by the integrator on the computed state just after it is comp...
Definition: AMReX_IntegratorBase.H:198
std::function< void(T &, amrex::Real)> post_fast_step_action
The post_step_action function is called by the integrator on the computed state just after it is comp...
Definition: AMReX_IntegratorBase.H:210
std::function< void(T &rhs, T &state, const amrex::Real time)> RhsIm
RhsIm is the implicit right-hand-side function an ImEx integrator will use.
Definition: AMReX_IntegratorBase.H:174
std::function< void(T &rhs, T &state, const amrex::Real time)> Rhs
Rhs is the right-hand-side function the integrator will use.
Definition: AMReX_IntegratorBase.H:168
bool use_adaptive_time_step
Flag to enable/disable adaptive time stepping in single rate methods or at the slow time scale in mul...
Definition: AMReX_IntegratorBase.H:216
std::function< void(T &, amrex::Real)> post_stage_action
The post_stage_action function is called by the integrator on the computed stage just after it is com...
Definition: AMReX_IntegratorBase.H:192
amrex::Real time_step
Current integrator time step size (Real)
Definition: AMReX_IntegratorBase.H:221
std::function< void(T &rhs, T &state, const amrex::Real time)> RhsFast
RhsFast is the fast timescale right-hand-side function a multirate integrator will use.
Definition: AMReX_IntegratorBase.H:186
amrex::Real abs_tol
Absolute tolerance for adaptive time stepping (Real)
Definition: AMReX_IntegratorBase.H:258
A collection (stored as an array) of FArrayBox objects.
Definition: AMReX_MultiFab.H:38
static void Copy(MultiFab &dst, const MultiFab &src, int srccomp, int dstcomp, int numcomp, int nghost)
Copy from src to dst including nghost ghost cells. The two MultiFabs MUST have the same underlying Bo...
Definition: AMReX_MultiFab.cpp:193
Parse Parameters From Command Line and Input Files.
Definition: AMReX_ParmParse.H:320
int query(const char *name, bool &ref, int ival=FIRST) const
Same as querykth() but searches for the last occurrence of name.
Definition: AMReX_ParmParse.cpp:1309
This class provides the user with a few print options.
Definition: AMReX_Print.H:35
Definition: AMReX_SundialsIntegrator.H:87
SUNLinearSolver fast_LS
Definition: AMReX_SundialsIntegrator.H:123
bool use_mri
Definition: AMReX_SundialsIntegrator.H:105
void time_interpolate(const T &, const T &, amrex::Real, T &) override
Definition: AMReX_SundialsIntegrator.H:603
SundialsIntegrator()
Definition: AMReX_SundialsIntegrator.H:396
void unpack_vector(N_Vector y_data, amrex::MultiFab &S_data)
Definition: AMReX_SundialsIntegrator.H:360
N_Vector copy_data(const amrex::MultiFab &S_data)
Definition: AMReX_SundialsIntegrator.H:376
std::string type
Definition: AMReX_SundialsIntegrator.H:92
void initialize(const T &S_data, const amrex::Real time=0.0)
Definition: AMReX_SundialsIntegrator.H:403
::sundials::Context sunctx
Definition: AMReX_SundialsIntegrator.H:114
MRIStepInnerStepper fast_stepper
Definition: AMReX_SundialsIntegrator.H:122
void unpack_vector(N_Vector y_data, amrex::Vector< amrex::MultiFab > &S_data)
Definition: AMReX_SundialsIntegrator.H:284
N_Vector copy_data(const amrex::Vector< amrex::MultiFab > &S_data)
Definition: AMReX_SundialsIntegrator.H:322
void SetupRK(amrex::Real time, N_Vector y_data)
Definition: AMReX_SundialsIntegrator.H:150
std::string method_e
Definition: AMReX_SundialsIntegrator.H:96
void * arkode_mem
Definition: AMReX_SundialsIntegrator.H:117
std::string method_i
Definition: AMReX_SundialsIntegrator.H:97
std::string fast_method
Definition: AMReX_SundialsIntegrator.H:101
amrex::Real advance(T &S_old, T &S_new, amrex::Real time, const amrex::Real dt) override
Take a single time step from (time, S_old) to (time + dt, S_new) with the given step size.
Definition: AMReX_SundialsIntegrator.H:544
void * arkode_fast_mem
Definition: AMReX_SundialsIntegrator.H:121
void evolve(T &S_out, const amrex::Real time_out) override
Evolve the current (internal) integrator state to time_out.
Definition: AMReX_SundialsIntegrator.H:573
N_Vector wrap_data(amrex::MultiFab &S_data)
Definition: AMReX_SundialsIntegrator.H:369
bool use_ark
Definition: AMReX_SundialsIntegrator.H:104
virtual ~SundialsIntegrator()
Definition: AMReX_SundialsIntegrator.H:535
SundialsUserData udata
Definition: AMReX_SundialsIntegrator.H:108
void initialize_parameters()
Definition: AMReX_SundialsIntegrator.H:125
N_Vector wrap_data(amrex::Vector< amrex::MultiFab > &S_data)
Definition: AMReX_SundialsIntegrator.H:299
std::string method
Definition: AMReX_SundialsIntegrator.H:95
SUNLinearSolver LS
Definition: AMReX_SundialsIntegrator.H:118
SundialsIntegrator(const T &S_data, const amrex::Real time=0.0)
Definition: AMReX_SundialsIntegrator.H:398
void SetupMRI(amrex::Real time, N_Vector y_data)
Definition: AMReX_SundialsIntegrator.H:200
std::string fast_type
Definition: AMReX_SundialsIntegrator.H:100
void map_data(std::function< void(T &)>) override
Definition: AMReX_SundialsIntegrator.H:605
Long size() const noexcept
Definition: AMReX_Vector.H:50
MPI_Comm CommunicatorSub() noexcept
sub-communicator for current frame
Definition: AMReX_ParallelContext.H:70
static int fi(amrex::Real t, N_Vector y_data, N_Vector y_rhs, void *user_data)
Definition: AMReX_SundialsIntegrator.H:49
static int fe(amrex::Real t, N_Vector y_data, N_Vector y_rhs, void *user_data)
Definition: AMReX_SundialsIntegrator.H:54
static int post_fast_step(amrex::Real t, N_Vector y_data, void *user_data)
Definition: AMReX_SundialsIntegrator.H:79
static int f(amrex::Real t, N_Vector y_data, N_Vector y_rhs, void *user_data)
Definition: AMReX_SundialsIntegrator.H:44
static int post_step(amrex::Real t, N_Vector y_data, void *user_data)
Definition: AMReX_SundialsIntegrator.H:69
static int ff(amrex::Real t, N_Vector y_data, N_Vector y_rhs, void *user_data)
Definition: AMReX_SundialsIntegrator.H:59
static int post_stage(amrex::Real t, N_Vector y_data, void *user_data)
Definition: AMReX_SundialsIntegrator.H:64
static int post_fast_stage(amrex::Real t, N_Vector y_data, void *user_data)
Definition: AMReX_SundialsIntegrator.H:74
amrex::MultiFab *& getMFptr(N_Vector v)
Definition: AMReX_NVector_MultiFab.cpp:228
N_Vector N_VMake_MultiFab(sunindextype length, amrex::MultiFab *v_mf, ::sundials::Context *sunctx)
Definition: AMReX_NVector_MultiFab.cpp:103
N_Vector N_VNew_MultiFab(sunindextype length, const amrex::BoxArray &ba, const amrex::DistributionMapping &dm, sunindextype nComp, sunindextype nGhost, ::sundials::Context *sunctx)
Definition: AMReX_NVector_MultiFab.cpp:78
Definition: AMReX_Amr.cpp:49
DistributionMapping const & DistributionMap(FabArrayBase const &fa)
@ make_alias
Definition: AMReX_MakeType.H:7
int nComp(FabArrayBase const &fa)
BoxArray const & boxArray(FabArrayBase const &fa)
void Error(const std::string &msg)
Print out message to cerr and exit via amrex::Abort().
Definition: AMReX.cpp:219
const int[]
Definition: AMReX_BLProfiler.cpp:1664
Definition: AMReX_SundialsIntegrator.H:21
std::function< int(amrex::Real, N_Vector, N_Vector, void *)> fi
Definition: AMReX_SundialsIntegrator.H:28
std::function< int(amrex::Real, N_Vector, void *)> post_fast_stage
Definition: AMReX_SundialsIntegrator.H:39
std::function< int(amrex::Real, N_Vector, void *)> post_step
Definition: AMReX_SundialsIntegrator.H:36
std::function< int(amrex::Real, N_Vector, N_Vector, void *)> f
Definition: AMReX_SundialsIntegrator.H:24
std::function< int(amrex::Real, N_Vector, void *)> post_stage
Definition: AMReX_SundialsIntegrator.H:35
std::function< int(amrex::Real, N_Vector, N_Vector, void *)> ff
Definition: AMReX_SundialsIntegrator.H:32
std::function< int(amrex::Real, N_Vector, void *)> post_fast_step
Definition: AMReX_SundialsIntegrator.H:40
std::function< int(amrex::Real, N_Vector, N_Vector, void *)> fe
Definition: AMReX_SundialsIntegrator.H:29