Block-Structured AMR Software Framework
AMReX_TimeIntegrator.H
Go to the documentation of this file.
1 #ifndef AMREX_TIME_INTEGRATOR_H
2 #define AMREX_TIME_INTEGRATOR_H
3 #include <AMReX_REAL.H>
4 #include <AMReX_Vector.H>
5 #include <AMReX_ParmParse.H>
6 #include <AMReX_IntegratorBase.H>
7 #include <AMReX_FEIntegrator.H>
8 #include <AMReX_RKIntegrator.H>
9 
10 #ifdef AMREX_USE_SUNDIALS
12 #endif
13 
14 #include <functional>
15 
16 namespace amrex {
17 
18 enum struct IntegratorTypes {
19  ForwardEuler = 0,
21  Sundials
22 };
23 
24 template<class T>
26 {
27 private:
28  std::unique_ptr<IntegratorBase<T> > integrator_ptr;
29 
31  {
32  amrex::ParmParse pp("integration");
33 
34  int integrator_type;
35  std::string integrator_str;
36  pp.get("type", integrator_str);
37 
38  if (integrator_str == "ForwardEuler") {
39  integrator_type = static_cast<int>(IntegratorTypes::ForwardEuler);
40  } else if (integrator_str == "RungeKutta") {
41  integrator_type = static_cast<int>(IntegratorTypes::ExplicitRungeKutta);
42  } else if (integrator_str == "SUNDIALS") {
43  integrator_type = static_cast<int>(IntegratorTypes::Sundials);
44  } else {
45  try {
46  integrator_type = std::stoi(integrator_str, nullptr);
47  } catch (const std::invalid_argument& ia) {
48  Print() << "Invalid integration.type: " << ia.what() << '\n';
49  Error("Failed to initialize AMReX TimeIntegrator class.");
50  }
51 
52  AMREX_ALWAYS_ASSERT(integrator_type >= static_cast<int>(IntegratorTypes::ForwardEuler) &&
53  integrator_type <= static_cast<int>(IntegratorTypes::Sundials));
54  }
55 
56 #ifndef AMREX_USE_SUNDIALS
57  if (integrator_type == static_cast<int>(IntegratorTypes::Sundials)) {
58  Error("AMReX has not been compiled with SUNDIALS. Recompile with USE_SUNDIALS=TRUE.");
59  }
60 #endif
61 
62  return static_cast<IntegratorTypes>(integrator_type);
63  }
64 
66  {
67  // By default, do nothing in the RHS
68  set_rhs([](T& /* S_rhs */, T& /* S_data */, const amrex::Real /* time */){});
69  set_imex_rhs([](T& /* S_rhs */, T& /* S_data */, const amrex::Real /* time */){},
70  [](T& /* S_rhs */, T& /* S_data */, const amrex::Real /* time */){});
71  set_fast_rhs([](T& /* S_rhs */, T& /* S_data */, const amrex::Real /* time */){});
72 
73  // In general, the following functions can be used to fill BCs. Which
74  // function to set will depend on the method type and intended use case
75 
76  // By default, do nothing after a stage or step
77  set_post_stage_action([](T& /* S_data */, const amrex::Real /* time */){});
78  set_post_step_action([](T& /* S_data */, const amrex::Real /* time */){});
79 
80  // By default, do nothing after a stage or step
81  set_post_fast_stage_action([](T& /* S_data */, const amrex::Real /* time */){});
82  set_post_fast_step_action([](T& /* S_data */, const amrex::Real /* time */){});
83  }
84 
85 public:
86 
88  // initialize functions to do nothing
90  }
91 
92  TimeIntegrator (IntegratorTypes integrator_type, const T& S_data, const amrex::Real time = 0.0)
93  {
94  // initialize the integrator class corresponding to the desired type
95  initialize_integrator(integrator_type, S_data, time);
96 
97  // initialize functions to do nothing
99  }
100 
101  TimeIntegrator (const T& S_data, const amrex::Real time = 0.0)
102  {
103  // initialize the integrator class corresponding to the input parameter selection
104  IntegratorTypes integrator_type = read_parameters();
105  initialize_integrator(integrator_type, S_data, time);
106 
107  // initialize functions to do nothing
109  }
110 
111  virtual ~TimeIntegrator () {}
112 
113  void initialize_integrator (IntegratorTypes integrator_type, const T& S_data, const amrex::Real time = 0.0)
114  {
115  switch (integrator_type)
116  {
118  integrator_ptr = std::make_unique<FEIntegrator<T> >(S_data, time);
119  break;
121  integrator_ptr = std::make_unique<RKIntegrator<T> >(S_data, time);
122  break;
123 #ifdef AMREX_USE_SUNDIALS
125  integrator_ptr = std::make_unique<SundialsIntegrator<T> >(S_data, time);
126  break;
127 #endif
128  default:
129  amrex::Error("integrator type did not match a valid integrator type.");
130  break;
131  }
132  }
133 
134  void set_rhs (std::function<void(T&, T&, const amrex::Real)> F)
135  {
136  integrator_ptr->set_rhs(F);
137  }
138 
139  void set_imex_rhs (std::function<void(T&, T&, const amrex::Real)> Fi,
140  std::function<void(T&, T&, const amrex::Real)> Fe)
141  {
142  integrator_ptr->set_imex_rhs(Fi, Fe);
143  }
144 
145  void set_fast_rhs (std::function<void(T&, T&, const amrex::Real)> F)
146  {
147  integrator_ptr->set_fast_rhs(F);
148  }
149 
150  void set_post_stage_action (std::function<void (T&, amrex::Real)> A)
151  {
152  integrator_ptr->set_post_stage_action(A);
153  }
154 
155  void set_post_step_action (std::function<void (T&, amrex::Real)> A)
156  {
157  integrator_ptr->set_post_step_action(A);
158  }
159 
160  void set_post_fast_stage_action (std::function<void (T&, amrex::Real)> A)
161  {
162  integrator_ptr->set_post_fast_stage_action(A);
163  }
164 
165  void set_post_fast_step_action (std::function<void (T&, amrex::Real)> A)
166  {
167  integrator_ptr->set_post_fast_step_action(A);
168  }
169 
170  amrex::Real get_time_step ()
171  {
172  return integrator_ptr->get_time_step();
173  }
174 
175  void set_time_step (amrex::Real dt)
176  {
177  integrator_ptr->set_time_step(dt);
178  }
179 
181  {
182  integrator_ptr->set_adaptive_step();
183  }
184 
185  void set_fast_time_step (amrex::Real dt)
186  {
187  integrator_ptr->set_fast_time_step(dt);
188  }
189 
191  {
192  integrator_ptr->set_adaptive_fast_step();
193  }
194 
195  void set_max_steps (int steps)
196  {
197  integrator_ptr->set_max_steps(steps);
198  }
199 
200  void set_tolerances (amrex::Real rtol, amrex::Real atol)
201  {
202  integrator_ptr->set_tolerances(rtol, atol);
203  }
204 
205  void set_fast_tolerances (amrex::Real rtol, amrex::Real atol)
206  {
207  integrator_ptr->set_fast_tolerances(rtol, atol);
208  }
209 
210  void advance (T& S_old, T& S_new, amrex::Real time, const amrex::Real dt)
211  {
212  integrator_ptr->advance(S_old, S_new, time, dt);
213  }
214 
215  void evolve (T& S_out, const amrex::Real time_out)
216  {
217  integrator_ptr->evolve(S_out, time_out);
218  }
219 
220  void integrate (T& S_old, T& S_new, amrex::Real start_time, const amrex::Real start_timestep,
221  const amrex::Real end_time, const int start_step, const int max_steps)
222  {
223  amrex::Real m_time = start_time;
224  amrex::Real m_timestep = start_timestep;
225  bool stop = false;
226  for (int m_step_number = start_step; m_step_number < max_steps && !stop; ++m_step_number)
227  {
228  if (end_time - m_time < m_timestep) {
229  m_timestep = end_time - m_time;
230  stop = true;
231  }
232 
233  if (m_step_number > 0) {
234  std::swap(S_old, S_new);
235  }
236 
237  // Call the time integrator advance
238  integrator_ptr->advance(S_old, S_new, m_time, m_timestep);
239 
240  // Update our time variable
241  m_time += m_timestep;
242  }
243  }
244 
245  void time_interpolate (const T& S_new, const T& S_old, amrex::Real timestep_fraction, T& data)
246  {
247  integrator_ptr->time_interpolate(S_new, S_old, timestep_fraction, data);
248  }
249 
250  void map_data (std::function<void(T&)> Map)
251  {
252  integrator_ptr->map_data(Map);
253  }
254 };
255 
256 }
257 
258 #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
Parse Parameters From Command Line and Input Files.
Definition: AMReX_ParmParse.H:320
void get(const char *name, bool &ref, int ival=FIRST) const
Same as getkth() but searches for the last occurrence of name.
Definition: AMReX_ParmParse.cpp:1292
This class provides the user with a few print options.
Definition: AMReX_Print.H:35
Definition: AMReX_TimeIntegrator.H:26
void set_adaptive_step()
Definition: AMReX_TimeIntegrator.H:180
void set_adaptive_fast_step()
Definition: AMReX_TimeIntegrator.H:190
void integrate(T &S_old, T &S_new, amrex::Real start_time, const amrex::Real start_timestep, const amrex::Real end_time, const int start_step, const int max_steps)
Definition: AMReX_TimeIntegrator.H:220
TimeIntegrator(const T &S_data, const amrex::Real time=0.0)
Definition: AMReX_TimeIntegrator.H:101
void set_max_steps(int steps)
Definition: AMReX_TimeIntegrator.H:195
void set_post_step_action(std::function< void(T &, amrex::Real)> A)
Definition: AMReX_TimeIntegrator.H:155
void map_data(std::function< void(T &)> Map)
Definition: AMReX_TimeIntegrator.H:250
void set_imex_rhs(std::function< void(T &, T &, const amrex::Real)> Fi, std::function< void(T &, T &, const amrex::Real)> Fe)
Definition: AMReX_TimeIntegrator.H:139
void set_fast_rhs(std::function< void(T &, T &, const amrex::Real)> F)
Definition: AMReX_TimeIntegrator.H:145
void evolve(T &S_out, const amrex::Real time_out)
Definition: AMReX_TimeIntegrator.H:215
IntegratorTypes read_parameters()
Definition: AMReX_TimeIntegrator.H:30
void set_tolerances(amrex::Real rtol, amrex::Real atol)
Definition: AMReX_TimeIntegrator.H:200
void set_post_fast_stage_action(std::function< void(T &, amrex::Real)> A)
Definition: AMReX_TimeIntegrator.H:160
TimeIntegrator()
Definition: AMReX_TimeIntegrator.H:87
void initialize_integrator(IntegratorTypes integrator_type, const T &S_data, const amrex::Real time=0.0)
Definition: AMReX_TimeIntegrator.H:113
void set_post_fast_step_action(std::function< void(T &, amrex::Real)> A)
Definition: AMReX_TimeIntegrator.H:165
void set_post_stage_action(std::function< void(T &, amrex::Real)> A)
Definition: AMReX_TimeIntegrator.H:150
void set_rhs(std::function< void(T &, T &, const amrex::Real)> F)
Definition: AMReX_TimeIntegrator.H:134
void time_interpolate(const T &S_new, const T &S_old, amrex::Real timestep_fraction, T &data)
Definition: AMReX_TimeIntegrator.H:245
std::unique_ptr< IntegratorBase< T > > integrator_ptr
Definition: AMReX_TimeIntegrator.H:28
void set_time_step(amrex::Real dt)
Definition: AMReX_TimeIntegrator.H:175
amrex::Real get_time_step()
Definition: AMReX_TimeIntegrator.H:170
virtual ~TimeIntegrator()
Definition: AMReX_TimeIntegrator.H:111
void advance(T &S_old, T &S_new, amrex::Real time, const amrex::Real dt)
Definition: AMReX_TimeIntegrator.H:210
TimeIntegrator(IntegratorTypes integrator_type, const T &S_data, const amrex::Real time=0.0)
Definition: AMReX_TimeIntegrator.H:92
void set_default_functions()
Definition: AMReX_TimeIntegrator.H:65
void set_fast_tolerances(amrex::Real rtol, amrex::Real atol)
Definition: AMReX_TimeIntegrator.H:205
void set_fast_time_step(amrex::Real dt)
Definition: AMReX_TimeIntegrator.H:185
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void swap(T &a, T &b) noexcept
Definition: AMReX_algoim_K.H:113
Definition: AMReX_Amr.cpp:49
void Error(const std::string &msg)
Print out message to cerr and exit via amrex::Abort().
Definition: AMReX.cpp:219
IntegratorTypes
Definition: AMReX_TimeIntegrator.H:18