chombo-discharge
CD_MeshODEStepperImplem.H
Go to the documentation of this file.
1 /* chombo-discharge
2  * Copyright © 2022 SINTEF Energy Research.
3  * Please refer to Copyright.txt and LICENSE in the chombo-discharge root directory.
4  */
5 
12 #ifndef CD_MeshODEStepperImplem_H
13 #define CD_MeshODEStepperImplem_H
14 
15 // Our includes
16 #include <CD_TimeStepper.H>
17 #include <CD_MeshODESolver.H>
18 #include <CD_NamespaceHeader.H>
19 
20 using namespace Physics::MeshODE;
21 
22 template <size_t N>
24 {
25  CH_TIME("MeshODEStepper::MeshODEStepper");
26 
27  m_verbosity = 10;
28  m_realm = Realm::Primal;
29  m_phase = phase::gas;
30 
31  this->parseOptions();
32 }
33 
34 template <size_t N>
36 {
37  CH_TIME("MeshODEStepper::~MeshODEStepper");
38  if (m_verbosity > 5) {
39  pout() << "MeshODEStepper::~MeshODEStepper" << endl;
40  }
41 }
42 
43 template <size_t N>
44 void
46 {
47  CH_TIME("MeshODEStepper::setupSolvers");
48  if (m_verbosity > 5) {
49  pout() << "MeshODEStepper::setupSolvers" << endl;
50  }
51 
52  m_solver = RefCountedPtr<MeshODESolver<N>>(new MeshODESolver<N>(m_amr));
53 
54  m_solver->setPhase(m_phase);
55  m_solver->setRealm(m_realm);
56  m_solver->parseOptions();
57 }
58 
59 template <size_t N>
60 void
62 {
63  CH_TIME("MeshODEStepper::allocate()");
64  if (m_verbosity > 5) {
65  pout() << "MeshODEStepper::allocate()" << endl;
66  }
67 
68  m_solver->allocate();
69 }
70 
71 template <size_t N>
72 void
74 {
75  CH_TIME("MeshODEStepper::initialData()");
76  if (m_verbosity > 5) {
77  pout() << "MeshODEStepper::initialData()" << endl;
78  }
79 
80  m_solver->setPhi(m_initialData);
81  m_solver->computeRHS(m_rhsFunction);
82 }
83 
84 template <size_t N>
85 void
87 {
88  CH_TIME("MeshODEStepper::postInitialize()");
89  if (m_verbosity > 5) {
90  pout() << "MeshODEStepper::postInitialize()" << endl;
91  }
92 }
93 
94 template <size_t N>
95 void
97 {
98  CH_TIME("MeshODEStepper::postCheckpointSetup()");
99  if (m_verbosity > 5) {
100  pout() << "MeshODEStepper::postCheckpointSetup()" << endl;
101  }
102 
103  m_solver->computeRHS(m_rhsFunction);
104 }
105 
106 template <size_t N>
107 void
109 {
110  CH_TIME("MeshODEStepper::registerRealms()");
111  if (m_verbosity > 5) {
112  pout() << "MeshODEStepper::registerRealms()" << endl;
113  }
114 
115  m_amr->registerRealm(Realm::Primal);
116 }
117 
118 template <size_t N>
119 void
121 {
122  CH_TIME("MeshODEStepper::registerOperators()");
123  if (m_verbosity > 5) {
124  pout() << "MeshODEStepper::registerOperators()" << endl;
125  }
126 
127  m_solver->registerOperators();
128 }
129 
130 template <size_t N>
131 void
133 {
134  CH_TIME("MeshODEStepper::parseOptions()");
135  if (m_verbosity > 5) {
136  pout() << "MeshODEStepper::parseOptions()" << endl;
137  }
138 
139  this->parseIntegrator();
140  this->parseVerbosity();
141  this->parseProblem();
142 }
143 
144 template <size_t N>
145 void
147 {
148  CH_TIME("MeshODEStepper::parseRuntimeOptions()");
149  if (m_verbosity > 5) {
150  pout() << "MeshODEStepper::parseRuntimeOptions()" << endl;
151  }
152 
153  m_solver->parseRuntimeOptions();
154 
155  this->parseIntegrator();
156  this->parseVerbosity();
157 }
158 
159 template <size_t N>
160 void
162 {
163  CH_TIME("MeshODEStepper::parseProblem()");
164  if (m_verbosity > 5) {
165  pout() << "MeshODEStepper::parseProblem()" << endl;
166  }
167 
168  ParmParse pp("MeshODEStepper");
169 
170  Real initPhi = 0.0;
171  Real frequency = 0.0;
172 
173  pp.get("init_phi", initPhi);
174  pp.get("frequency", frequency);
175  pp.get("dt", m_dt);
176 
177  m_initialData = [initPhi](const RealVect& a_pos) -> std::array<Real, N> {
178  std::array<Real, N> Y;
179 
180  for (auto& y : Y) {
181  y = initPhi;
182  }
183 
184  return Y;
185  };
186 
187  m_rhsFunction = [frequency](const std::array<Real, N> Y, const Real t) -> std::array<Real, N> {
188  std::array<Real, N> rhs;
189 
190  for (auto& r : rhs) {
191  r = cos(2 * M_PI * frequency * t);
192  }
193 
194  return rhs;
195  };
196 }
197 
198 #ifdef CH_USE_HDF5
199 template <size_t N>
200 void
201 MeshODEStepper<N>::writeCheckpointData(HDF5Handle& a_handle, const int a_lvl) const
202 {
203  CH_TIME("MeshODEStepper::writeCheckpointData(HDF5Handle, int)");
204  if (m_verbosity > 5) {
205  pout() << "MeshODEStepper::writeCheckpointData(HDF5Handle, int)" << endl;
206  }
207 
208  m_solver->writeCheckpointLevel(a_handle, a_lvl);
209 }
210 #endif
211 
212 #ifdef CH_USE_HDF5
213 template <size_t N>
214 void
215 MeshODEStepper<N>::readCheckpointData(HDF5Handle& a_handle, const int a_lvl)
216 {
217  CH_TIME("MeshODEStepper::readCheckpointData(HDF5Handle, int)");
218  if (m_verbosity > 5) {
219  pout() << "MeshODEStepper::readCheckpointData(HDF5Handle, int)" << endl;
220  }
221 
222  m_solver->readCheckpointLevel(a_handle, a_lvl);
223 }
224 #endif
225 
226 template <size_t N>
227 int
229 {
230  CH_TIME("MeshODEStepper::getNumberOfPlotVariables()");
231  if (m_verbosity > 5) {
232  pout() << "MeshODEStepper::getNumberOfPlotVariables()" << endl;
233  }
234 
235  return m_solver->getNumberOfPlotVariables();
236 }
237 
238 template <size_t N>
239 Vector<std::string>
241 {
242  CH_TIME("MeshODEStepper::getPlotVariableNames()");
243  if (m_verbosity > 5) {
244  pout() << "MeshODEStepper::getPlotVariableNames()" << endl;
245  }
246 
247  return m_solver->getPlotVariableNames();
248 }
249 
250 template <size_t N>
251 void
252 MeshODEStepper<N>::writePlotData(LevelData<EBCellFAB>& a_output,
253  int& a_icomp,
254  const std::string a_outputRealm,
255  const int a_level) const
256 {
257  CH_TIME("MeshODEStepper::writePlotData");
258  if (m_verbosity > 5) {
259  pout() << "MeshODEStepper::writePlotData" << endl;
260  }
261 
262  m_solver->writePlotData(a_output, a_icomp, a_outputRealm, a_level);
263 }
264 
265 template <size_t N>
266 Real
268 {
269  CH_TIME("MeshODEStepper::computeDt()");
270  if (m_verbosity > 5) {
271  pout() << "MeshODEStepper::computeDt()" << endl;
272  }
273 
274  return m_dt;
275 }
276 
277 template <size_t N>
278 Real
280 {
281  CH_TIME("MeshODEStepper::avdvance(Real)");
282  if (m_verbosity > 5) {
283  pout() << "MeshODEStepper::advance(Real)" << endl;
284  }
285 
286  switch (m_algorithm) {
287  case IntegrationAlgorithm::Euler: {
288  this->advanceEuler(a_dt);
289 
290  break;
291  }
292  case IntegrationAlgorithm::RK2: {
293  this->advanceRK2(a_dt);
294 
295  break;
296  }
297  case IntegrationAlgorithm::RK4: {
298  this->advanceRK4(a_dt);
299 
300  break;
301  }
302  default: {
303  MayDay::Error("MeshODEStepper::advance -- logic bust");
304 
305  break;
306  }
307  }
308 
309  // Update the source term.
310  m_solver->computeRHS(m_rhsFunction);
311 
312  return a_dt;
313 }
314 
315 template <size_t N>
316 void
317 MeshODEStepper<N>::synchronizeSolverTimes(const int a_step, const Real a_time, const Real a_dt)
318 {
319  CH_TIME("MeshODEStepper::synchronizeSolverTimes(int, Real, Real)");
320  if (m_verbosity > 5) {
321  pout() << "MeshODEStepper::synchronizeSolverTimes(int, Real, Real)" << endl;
322  }
323 
324  m_timeStep = a_step;
325  m_time = a_time;
326 
327  m_solver->setTime(a_step, a_time, a_dt);
328 }
329 
330 template <size_t N>
331 void
332 MeshODEStepper<N>::preRegrid(const int a_lmin, const int a_oldFinestLevel)
333 {
334  CH_TIME("MeshODEStepper::preRegrid(int, int)");
335  if (m_verbosity > 5) {
336  pout() << "MeshODEStepper::preRegrid(int, int)" << endl;
337  }
338 
339  m_solver->preRegrid(a_lmin, a_oldFinestLevel);
340 }
341 
342 template <size_t N>
343 void
344 MeshODEStepper<N>::regrid(const int a_lmin, const int a_oldFinestLevel, const int a_newFinestLevel)
345 {
346  CH_TIME("MeshODEStepper::regrid(int, int, int)");
347  if (m_verbosity > 5) {
348  pout() << "MeshODEStepper::regrid(int, int, int)" << endl;
349  }
350 
351  m_solver->regrid(a_lmin, a_oldFinestLevel, a_newFinestLevel);
352 }
353 
354 template <size_t N>
355 void
357 {
358  CH_TIME("MeshODEStepper::postRegrid()");
359  if (m_verbosity > 5) {
360  pout() << "MeshODEStepper::postRegrid()" << endl;
361  }
362 
363  // Compute new right-hand side.
364  m_solver->computeRHS(m_rhsFunction);
365 }
366 
367 template <size_t N>
368 void
370 {
371  CH_TIME("MeshODEStepper::parseIntegrator()");
372  if (m_verbosity > 5) {
373  pout() << "MeshODEStepper::parseIntegrator()" << endl;
374  }
375 
376  ParmParse pp("MeshODEStepper");
377 
378  std::string str;
379 
380  pp.get("integration", str);
381  if (str == "euler") {
382  m_algorithm = IntegrationAlgorithm::Euler;
383  }
384  else if (str == "rk2") {
385  m_algorithm = IntegrationAlgorithm::RK2;
386  }
387  else if (str == "rk4") {
388  m_algorithm = IntegrationAlgorithm::RK4;
389  }
390  else {
391  MayDay::Error("MeshODEStepper::parseIntegrator -- logic bust");
392  }
393 }
394 
395 template <size_t N>
396 void
398 {
399  CH_TIME("MeshODEStepper::parseVerbosity()");
400  if (m_verbosity > 5) {
401  pout() << "MeshODEStepper::parseVerbosity()" << endl;
402  }
403 
404  ParmParse pp("MeshODEStepper");
405 
406  pp.get("verbosity", m_verbosity);
407 }
408 
409 template <size_t N>
410 void
412 {
413  CH_TIME("MeshODEStepper::advanceEuler()");
414  if (m_verbosity > 5) {
415  pout() << "MeshODEStepper::advanceEuler()" << endl;
416  }
417 
418  // Let Y = Y + S * dt
419  EBAMRCellData& phi = m_solver->getPhi();
420  EBAMRCellData& rhs = m_solver->getRHS();
421 
422  m_solver->computeRHS(rhs, m_rhsFunction);
423 
424  DataOps::incr(phi, rhs, a_dt);
425 }
426 
427 template <size_t N>
428 void
430 {
431  CH_TIME("MeshODEStepper::advanceRK2()");
432  if (m_verbosity > 5) {
433  pout() << "MeshODEStepper::advanceRK2()" << endl;
434  }
435 
436  EBAMRCellData& phi = m_solver->getPhi();
437 
438  EBAMRCellData k1;
439  EBAMRCellData k2;
440 
441  m_amr->allocate(k1, m_realm, m_phase, N);
442  m_amr->allocate(k2, m_realm, m_phase, N);
443 
444  m_solver->computeRHS(k1, m_rhsFunction);
445  DataOps::incr(phi, k1, a_dt);
446 
447  m_solver->computeRHS(k2, m_rhsFunction);
448  DataOps::incr(phi, k2, 0.5 * a_dt);
449  DataOps::incr(phi, k1, -0.5 * a_dt);
450 }
451 
452 template <size_t N>
453 void
455 {
456  CH_TIME("MeshODEStepper::advanceRK4()");
457  if (m_verbosity > 5) {
458  pout() << "MeshODEStepper::advanceRK4()" << endl;
459  }
460 
461  MayDay::Error("MeshODEStepper::advanceRK4 -- not implemented");
462 }
463 
464 #include <CD_NamespaceFooter.H>
465 
466 #endif
Encapsulation of an ODE solver on the mesh.
Declaration of main (abstract) time stepper class.
static void incr(MFAMRCellData &a_lhs, const MFAMRCellData &a_rhs, const Real a_scale) noexcept
Function which increments data in the form a_lhs = a_lhs + a_rhs*a_scale for all components.
Definition: CD_DataOps.cpp:787
Class for solving dy/dt = f on an AMR hierarchy.
Definition: CD_MeshODESolver.H:28
Implementation of TimeStepper for solving an ODE on a mesh. N is the number of variables.
Definition: CD_MeshODEStepper.H:41
virtual void advanceEuler(const Real a_dt)
Advance using the explicit Euler rule.
Definition: CD_MeshODEStepperImplem.H:411
virtual Real advance(const Real a_dt) override
Advancement method. Swaps between various kernels.
Definition: CD_MeshODEStepperImplem.H:279
void registerOperators() override
Register operators.
Definition: CD_MeshODEStepperImplem.H:120
virtual void writePlotData(LevelData< EBCellFAB > &a_output, int &a_icomp, const std::string a_outputRealm, const int a_level) const override
Write plot data to output holder.
Definition: CD_MeshODEStepperImplem.H:252
void parseRuntimeOptions() override
Parse runtime options.
Definition: CD_MeshODEStepperImplem.H:146
virtual Vector< std::string > getPlotVariableNames() const override
Get plot variable names.
Definition: CD_MeshODEStepperImplem.H:240
virtual void advanceRK2(const Real a_dt)
Advance using a second-order Runge-Kutta method.
Definition: CD_MeshODEStepperImplem.H:429
virtual void regrid(const int a_lmin, const int a_oldFinestLevel, const int a_newFinestLevel) override
Time stepper regrid method.
Definition: CD_MeshODEStepperImplem.H:344
virtual void parseIntegrator()
Parse integrator.
Definition: CD_MeshODEStepperImplem.H:369
void initialData() override
Fill problem with initial data.
Definition: CD_MeshODEStepperImplem.H:73
void allocate() override
Allocate storage for solvers and time stepper.
Definition: CD_MeshODEStepperImplem.H:61
virtual void synchronizeSolverTimes(const int a_step, const Real a_time, const Real a_dt) override
Synchronize solver times and time steps.
Definition: CD_MeshODEStepperImplem.H:317
virtual ~MeshODEStepper()
Destructor.
Definition: CD_MeshODEStepperImplem.H:35
virtual void parseVerbosity()
Parse chattiness.
Definition: CD_MeshODEStepperImplem.H:397
virtual void parseProblem()
Parse the problem type.
Definition: CD_MeshODEStepperImplem.H:161
void setupSolvers() override
Instantiate the ODE solver.
Definition: CD_MeshODEStepperImplem.H:45
virtual void advanceRK4(const Real a_dt)
Advance using a fourth order Runge-Kutta method.
Definition: CD_MeshODEStepperImplem.H:454
virtual void preRegrid(const int a_lmin, const int a_oldFinestLevel) override
Perform pre-regrid operations.
Definition: CD_MeshODEStepperImplem.H:332
void postCheckpointSetup() override
Post checkpoint operations.
Definition: CD_MeshODEStepperImplem.H:96
virtual int getNumberOfPlotVariables() const override
Get the number of plot variables for this time stepper.
Definition: CD_MeshODEStepperImplem.H:228
void registerRealms() override
Register realms. Primal is the only realm we need.
Definition: CD_MeshODEStepperImplem.H:108
void parseOptions()
Parse options.
Definition: CD_MeshODEStepperImplem.H:132
virtual void postRegrid() override
Perform post-regrid operations.
Definition: CD_MeshODEStepperImplem.H:356
void postInitialize() override
Perform any post-initialization steps.
Definition: CD_MeshODEStepperImplem.H:86
MeshODEStepper()
Constructor. Does nothing.
Definition: CD_MeshODEStepperImplem.H:23
virtual Real computeDt() override
Compute a time step to be used by Driver.
Definition: CD_MeshODEStepperImplem.H:267
static const std::string Primal
Identifier for perimal realm.
Definition: CD_Realm.H:47