Alamo
Integrator.cpp
Go to the documentation of this file.
1 ///
2 /// \file Integrator.cpp
3 /// \brief Compute the volume integral of two multiplied Fourier series
4 ///
5 
6 #include "Integrator.H"
7 #include "IO/FileNameParse.H"
8 #include "IO/ParmParse.H"
9 #include "Util/Util.H"
10 #include <numeric>
11 
12 
13 
14 namespace Integrator
15 {
16 
17 Integrator::Integrator() : amrex::AmrCore()
18 {
19  BL_PROFILE("Integrator::Integrator()");
20  {
21  // These are basic parameters that are, in
22  // general, common to all Alamo simulations.
23  IO::ParmParse pp;
24  pp_query_default("max_step", max_step, 2147483647); // Number of iterations before ending (default is maximum possible int)
25  pp_query_required("stop_time", stop_time); // Simulation time before ending
26  pp_query_required("timestep", timestep); // Nominal timestep on amrlev = 0
27  pp_query("restart", restart_file_cell); // Name of restart file to READ from
28  pp_query("restart_cell", restart_file_cell); // Name of cell-fab restart file to read from
29  pp_query("restart_node", restart_file_node); // Name of node-fab restart file to read from
30  }
31  {
32  // This allows the user to ignore certain arguments that
33  // would otherwise cause problems.
34  // Most generally this is used in the event of a "above inputs
35  // specified but not used" error.
36  // The primary purpose of this was to fix those errors that arise
37  // in regression tests.
38  IO::ParmParse pp;
39  std::vector<std::string> ignore;
40  if (pp.contains("ignore")) Util::Message(INFO, "Ignore directive detected");
41  pp_queryarr("ignore", ignore); // Space-separated list of entries to ignore
42  for (unsigned int i = 0; i < ignore.size(); i++)
43  {
44  Util::Message(INFO, "ignoring ", ignore[i]);
45  pp.remove(ignore[i].c_str());
46  }
47  }
48  {
49  // These are parameters that are specific to
50  // the AMR/regridding part of the code.
51  IO::ParmParse pp("amr");
52  pp_query_default("regrid_int", regrid_int, 2); // Regridding interval in step numbers
53  pp_query_default("base_regrid_int", base_regrid_int, 0); // Regridding interval based on coarse level only
54  pp_query_default("plot_int", plot_int, -1); // Interval (in timesteps) between plotfiles (Default negative value will cause the plot interval to be ignored.)
55  pp_query_default("plot_dt", plot_dt, -1.0); // Interval (in simulation time) between plotfiles (Default negative value will cause the plot dt to be ignored.)
56  pp_query_default("plot_file", plot_file, "output"); // Output file
57 
58  pp_query_default("cell.all", cell.all, false); // Turn on to write all output in cell fabs (default: off)
59  pp_query_default("cell.any", cell.any, true); // Turn off to prevent any cell based output (default: on)
60  pp_query_default("node.all", node.all, false); // Turn on to write all output in node fabs (default: off)
61  pp_query_default("node.any", node.any, true); // Turn off to prevent any node based output (default: on)
62 
63  pp_query_default("abort_on_nan",abort_on_nan, true); // Abort if a plotfile contains nan or inf.
64 
65  Util::Assert(INFO, TEST(!(!cell.any && cell.all)));
66  Util::Assert(INFO, TEST(!(!node.any && node.all)));
67 
68  pp_query_default("max_plot_level", max_plot_level, -1); // Specify a maximum level of refinement for output files (NO REFINEMENT)
69 
70  IO::FileNameParse(plot_file);
71 
72  nsubsteps.resize(maxLevel() + 1, 1);
73  int cnt = pp.countval("nsubsteps");
74  if (cnt != 0)
75  if (cnt == maxLevel()) {
76  pp_queryarr("nsubsteps", nsubsteps); // Number of substeps to take on each level (default: 2)
77  nsubsteps.insert(nsubsteps.begin(), 1);
78  nsubsteps.pop_back();
79  }
80  else if (cnt == 1)
81  {
82  int nsubsteps_all;
83  pp_query_required("nsubsteps", nsubsteps_all);// Number of substeps to take on each level (set all levels to this value)
84  for (int lev = 1; lev <= maxLevel(); ++lev) nsubsteps[lev] = nsubsteps_all;
85  }
86  else
87  Util::Abort(INFO, "number of nsubsteps input must equal either 1 or amr.max_level");
88  else
89  for (int lev = 1; lev <= maxLevel(); ++lev)
90  nsubsteps[lev] = MaxRefRatio(lev - 1);
91  }
92  {
93  IO::ParmParse pp("dynamictimestep");
94  // activate dynamic CFL-based timestep
95  pp_query("on",dynamictimestep.on);
96  if (dynamictimestep.on)
97  {
98  // how much information to print
99  pp_query_validate("verbose",dynamictimestep.verbose,{0,1});
100  // number of previous timesteps for rolling average
101  pp_query_default("nprevious",dynamictimestep.nprevious,5);
102  // dynamic teimstep CFL condition
103  pp_query_default("cfl",dynamictimestep.cfl,1.0);
104  // minimum timestep size allowed shen stepping dynamically
105  pp_query_default("min",dynamictimestep.min,timestep);
106  // maximum timestep size allowed shen stepping dynamically
107  pp_query_default("max",dynamictimestep.max,timestep);
108 
109  Util::AssertException(INFO,TEST(dynamictimestep.max >= dynamictimestep.min));
110  }
111  }
112  {
113  // Information on how to generate thermodynamic
114  // data (to show up in thermo.dat)
115  IO::ParmParse pp("amr.thermo");
116  thermo.interval = 1; // Default: integrate every time.
117  pp_query_default("int", thermo.interval, 1); // Integration interval (1)
118  pp_query_default("plot_int", thermo.plot_int, -1); // Interval (in timesteps) between writing (Default negative value will cause the plot interval to be ignored.)
119  pp_query_default("plot_dt", thermo.plot_dt, -1.0); // Interval (in simulation time) between writing (Default negative value will cause the plot dt to be ignored.)
120  }
121 
122  {
123  // Instead of using AMR, prescribe an explicit, user-defined
124  // set of grids to work on. This is pretty much always used
125  // for testing purposes only.
126  IO::ParmParse pp("explicitmesh");
127  pp_query_default("on", explicitmesh.on, 0); // Use explicit mesh instead of AMR
128  if (explicitmesh.on)
129  {
130  for (int ilev = 0; ilev < maxLevel(); ++ilev)
131  {
132  std::string strlo = "lo" + std::to_string(ilev + 1);
133  std::string strhi = "hi" + std::to_string(ilev + 1);
134 
135  Util::Assert(INFO, TEST(pp.contains(strlo.c_str())));
136  Util::Assert(INFO, TEST(pp.contains(strhi.c_str())));
137 
138  amrex::Vector<int> lodata, hidata;
139  pp_queryarr(strlo.c_str(), lodata);
140  pp_queryarr(strhi.c_str(), hidata);
141  amrex::IntVect lo(AMREX_D_DECL(lodata[0], lodata[1], lodata[2]));
142  amrex::IntVect hi(AMREX_D_DECL(hidata[0], hidata[1], hidata[2]));
143 
144  explicitmesh.box.push_back(amrex::Box(lo, hi));
145  }
146  }
147  }
148 
149  int nlevs_max = maxLevel() + 1;
150 
151  istep.resize(nlevs_max, 0);
152 
153  t_new.resize(nlevs_max, 0.0);
154  t_old.resize(nlevs_max, -1.e100);
155  SetTimestep(timestep);
156 
157  plot_file = Util::GetFileName();
158  IO::WriteMetaData(plot_file, IO::Status::Running, 0);
159 }
160 
161 ///
162 /// \func ~Integrator
163 /// \brief Does nothing -- check here first if there are memory leaks
164 ///
165 Integrator::~Integrator()
166 {
167  BL_PROFILE("Integrator::~Integrator");
168  if (amrex::ParallelDescriptor::IOProcessor())
170 }
171 
172 void Integrator::SetTimestep(Set::Scalar _timestep)
173 {
174  BL_PROFILE("Integrator::SetTimestep");
175  int nlevs_max = maxLevel() + 1;
176  timestep = _timestep;
177  dt.resize(nlevs_max, 1.e100);
178  dt[0] = timestep;
179  for (int i = 1; i < nlevs_max; i++)
180  dt[i] = dt[i - 1] / (amrex::Real)nsubsteps[i];
181 }
182 void Integrator::SetPlotInt(int a_plot_int)
183 {
184  BL_PROFILE("Integrator::SetPlotInt");
185  plot_int = a_plot_int;
186 }
187 
188 /// \fn Integrator::MakeNewLevelFromCoarse
189 /// \brief Wrapper to call FillCoarsePatch
190 /// \note **THIS OVERRIDES A PURE VIRTUAL METHOD - DO NOT CHANGE**
191 ///
192 void
193 Integrator::MakeNewLevelFromCoarse(int lev, amrex::Real time, const amrex::BoxArray& cgrids, const amrex::DistributionMapping& dm)
194 {
195  BL_PROFILE("Integrator::MakeNewLevelFromCoarse");
196 
197  for (int n = 0; n < cell.number_of_fabs; n++)
198  {
199  const int ncomp = (*cell.fab_array[n])[lev - 1]->nComp();
200  const int nghost = (*cell.fab_array[n])[lev - 1]->nGrow();
201 
202  (*cell.fab_array[n])[lev].reset(new amrex::MultiFab(cgrids, dm, ncomp, nghost));
203 
204  (*cell.fab_array[n])[lev]->setVal(0.0);
205 
206  FillCoarsePatch(lev, time, *cell.fab_array[n], *cell.physbc_array[n], 0, ncomp);
207  }
208 
209  amrex::BoxArray ngrids = cgrids;
210  ngrids.convert(amrex::IntVect::TheNodeVector());
211 
212  for (int n = 0; n < node.number_of_fabs; n++)
213  {
214  const int ncomp = (*node.fab_array[n])[lev - 1]->nComp();
215  const int nghost = (*node.fab_array[n])[lev - 1]->nGrow();
216 
217  (*node.fab_array[n])[lev].reset(new amrex::MultiFab(ngrids, dm, ncomp, nghost));
218  (*node.fab_array[n])[lev]->setVal(0.0);
219 
220  FillCoarsePatch(lev, time, *node.fab_array[n], *node.physbc_array[n], 0, ncomp);
221  }
222 
223  for (unsigned int n = 0; n < m_basefields.size(); n++)
224  {
225  m_basefields[n]->MakeNewLevelFromCoarse(lev, time, cgrids, dm);
226  }
227  for (unsigned int n = 0; n < m_basefields_cell.size(); n++)
228  {
229  m_basefields_cell[n]->MakeNewLevelFromCoarse(lev, time, cgrids, dm);
230  }
231 
232  Regrid(lev, time);
233 }
234 
235 
236 ///
237 /// RESETS ALL MULTIFABS AT A GIVEN LEVEL
238 ///
239 /// (OVERRIDES PURE VIRTUAL METHOD - DO NOT CHANGE)
240 ///
241 void
242 Integrator::RemakeLevel(int lev, ///<[in] AMR Level
243  amrex::Real time, ///<[in] Simulation time
244  const amrex::BoxArray& cgrids,
245  const amrex::DistributionMapping& dm)
246 {
247  BL_PROFILE("Integrator::RemakeLevel");
248  for (int n = 0; n < cell.number_of_fabs; n++)
249  {
250  const int ncomp = (*cell.fab_array[n])[lev]->nComp();
251  const int nghost = (*cell.fab_array[n])[lev]->nGrow();
252 
253  amrex::MultiFab new_state(cgrids, dm, ncomp, nghost);
254 
255  new_state.setVal(0.0);
256  FillPatch(lev, time, *cell.fab_array[n], new_state, *cell.physbc_array[n], 0);
257  std::swap(new_state, *(*cell.fab_array[n])[lev]);
258  }
259 
260  amrex::BoxArray ngrids = cgrids;
261  ngrids.convert(amrex::IntVect::TheNodeVector());
262 
263  for (int n = 0; n < node.number_of_fabs; n++)
264  {
265  const int ncomp = (*node.fab_array[n])[lev]->nComp();
266  const int nghost = (*node.fab_array[n])[lev]->nGrow();
267 
268  amrex::MultiFab new_state(ngrids, dm, ncomp, nghost);
269 
270  new_state.setVal(0.0);
271  FillPatch(lev, time, *node.fab_array[n], new_state, *node.physbc_array[n], 0);
272  std::swap(new_state, *(*node.fab_array[n])[lev]);
273  }
274 
275  for (unsigned int n = 0; n < m_basefields_cell.size(); n++)
276  {
277  m_basefields_cell[n]->RemakeLevel(lev, time, cgrids, dm);
278  }
279  for (unsigned int n = 0; n < m_basefields.size(); n++)
280  {
281  m_basefields[n]->RemakeLevel(lev, time, cgrids, dm);
282  }
283  Regrid(lev, time);
284 }
285 
286 //
287 // DELETE EVERYTHING
288 //
289 // (OVERRIDES PURE VIRTUAL METHOD - DO NOT CHANGE)
290 //
291 void
292 Integrator::ClearLevel(int lev)
293 {
294  BL_PROFILE("Integrator::ClearLevel");
295  for (int n = 0; n < cell.number_of_fabs; n++)
296  {
297  (*cell.fab_array[n])[lev].reset(nullptr);
298  }
299  for (int n = 0; n < node.number_of_fabs; n++)
300  {
301  (*node.fab_array[n])[lev].reset(nullptr);
302  }
303 }
304 
305 //
306 //
307 //
308 
309 
310 
311 
312 
313 void
314 Integrator::RegisterNewFab(Set::Field<Set::Scalar>& new_fab, BC::BC<Set::Scalar>* new_bc, int ncomp, int nghost, std::string name, bool writeout, std::vector<std::string> suffix)
315 {
316  //Util::Warning(INFO, "RegisterNewFab is depricated. Please replace with AddField");
317  AddField<Set::Scalar, Set::Hypercube::Cell>(new_fab, new_bc, ncomp, nghost, name, writeout, true, suffix);
318 }
319 void
320 Integrator::RegisterNewFab(Set::Field<Set::Scalar>& new_fab, int ncomp, std::string name, bool writeout, std::vector<std::string> suffix)
321 {
322  //Util::Warning(INFO, "RegisterNewFab is depricated. Please replace with AddField");
323  AddField<Set::Scalar, Set::Hypercube::Cell>(new_fab, nullptr, ncomp, 0, name, writeout, true, suffix);
324 }
325 void
326 Integrator::RegisterNodalFab(Set::Field<Set::Scalar>& new_fab, BC::BC<Set::Scalar>* new_bc, int ncomp, int nghost, std::string name, bool writeout, std::vector<std::string> suffix)
327 {
328  //Util::Warning(INFO, "RegisterNodalFab is depricated. Please replace with AddField");
329  AddField<Set::Scalar, Set::Hypercube::Node>(new_fab, new_bc, ncomp, nghost, name, writeout, true,suffix);
330 }
331 void
332 Integrator::RegisterNodalFab(Set::Field<Set::Scalar>& new_fab, int ncomp, int nghost, std::string name, bool writeout, std::vector<std::string> suffix)
333 {
334  //Util::Warning(INFO, "RegisterNodalFab is depricated. Please replace with AddField");
335  AddField<Set::Scalar, Set::Hypercube::Node>(new_fab, nullptr, ncomp, nghost, name, writeout, true,suffix);
336 }
337 
338 
339 
340 
341 void // CUSTOM METHOD - CHANGEABLE
342 Integrator::RegisterIntegratedVariable(Set::Scalar *integrated_variable, std::string name, bool extensive)
343 {
344  BL_PROFILE("Integrator::RegisterIntegratedVariable");
345  thermo.vars.push_back(integrated_variable);
346  thermo.names.push_back(name);
347  thermo.extensives.push_back(extensive);
348  thermo.number++;
349 }
350 
351 long // CUSTOM METHOD - CHANGEABLE
352 Integrator::CountCells(int lev)
353 {
354  BL_PROFILE("Integrator::CountCells");
355  const int N = grids[lev].size();
356 
357  long cnt = 0;
358 
359  for (int i = 0; i < N; ++i)
360  {
361  cnt += grids[lev][i].numPts();
362  }
363 
364  return cnt;
365 }
366 
367 void // CUSTOM METHOD - CHANGEABLE
368 Integrator::FillPatch(int lev, amrex::Real time,
369  amrex::Vector<std::unique_ptr<amrex::MultiFab>>& source_mf,
370  amrex::MultiFab& destination_mf,
371  BC::BC<Set::Scalar>& physbc, int icomp)
372 {
373  BL_PROFILE("Integrator::FillPatch");
374  if (lev == 0)
375  {
376 
377  amrex::Vector<amrex::MultiFab*> smf;
378  smf.push_back(source_mf[lev].get());
379  amrex::Vector<amrex::Real> stime;
380  stime.push_back(time);
381 
382  physbc.define(geom[lev]);
383  amrex::FillPatchSingleLevel(destination_mf, // Multifab
384  time, // time
385  smf, // Vector<MultiFab*> &smf (CONST)
386  stime, // Vector<Real> &stime (CONST)
387  0, // scomp - Source component
388  icomp, // dcomp - Destination component
389  destination_mf.nComp(), // ncomp - Number of components
390  geom[lev], // Geometry (CONST)
391  physbc,
392  0); // BC
393  }
394  else
395  {
396  amrex::Vector<amrex::MultiFab*> cmf, fmf;
397  cmf.push_back(source_mf[lev - 1].get());
398  fmf.push_back(source_mf[lev].get());
399  amrex::Vector<amrex::Real> ctime, ftime;
400  ctime.push_back(time);
401  ftime.push_back(time);
402 
403  physbc.define(geom[lev]);
404 
405  amrex::Interpolater* mapper;
406 
407  if (destination_mf.boxArray().ixType() == amrex::IndexType::TheNodeType())
408  mapper = &amrex::node_bilinear_interp;
409  else
410  mapper = &amrex::cell_cons_interp;
411 
412  amrex::Vector<amrex::BCRec> bcs(destination_mf.nComp(), physbc.GetBCRec()); // todo
413  amrex::FillPatchTwoLevels(destination_mf, time, cmf, ctime, fmf, ftime,
414  0, icomp, destination_mf.nComp(), geom[lev - 1], geom[lev],
415  physbc, 0,
416  physbc, 0,
417  refRatio(lev - 1),
418  mapper, bcs, 0);
419  }
420 }
421 
422 /// \fn Integrator::FillCoarsePatch
423 /// \brief Fill a fab at current level with the data from one level up
424 ///
425 /// \note This is a custom method and is changeable
426 void
427 Integrator::FillCoarsePatch(int lev, ///<[in] AMR level
428  amrex::Real time, ///<[in] Simulatinon time
429  Set::Field<Set::Scalar>& mf, ///<[in] Fab to fill
430  BC::BC<Set::Scalar>& physbc, ///<[in] BC object applying to Fab
431  int icomp, ///<[in] start component
432  int ncomp) ///<[in] end component (i.e. applies to components `icomp`...`ncomp`)
433 {
434  BL_PROFILE("Integrator::FillCoarsePatch");
435  AMREX_ASSERT(lev > 0);
436  amrex::Vector<amrex::MultiFab*> cmf;
437  cmf.push_back(mf[lev - 1].get());
438  amrex::Vector<amrex::Real> ctime;
439  ctime.push_back(time);
440 
441  physbc.define(geom[lev]);
442 
443  amrex::Interpolater* mapper;
444  if (mf[lev]->boxArray().ixType() == amrex::IndexType::TheNodeType())
445  mapper = &amrex::node_bilinear_interp;
446  else
447  mapper = &amrex::cell_cons_interp;
448 
449  amrex::Vector<amrex::BCRec> bcs(ncomp, physbc.GetBCRec());
450  amrex::InterpFromCoarseLevel(*mf[lev], time, *cmf[0], 0, icomp, ncomp, geom[lev - 1], geom[lev],
451  physbc, 0,
452  physbc, 0,
453  refRatio(lev - 1),
454  mapper, bcs, 0);
455 }
456 
457 void
458 Integrator::ErrorEst(int lev, amrex::TagBoxArray& tags, amrex::Real time, int ngrow)
459 {
460  BL_PROFILE("Integrator::ErrorEst");
461  TagCellsForRefinement(lev, tags, time, ngrow);
462 }
463 
464 
465 void
466 Integrator::InitData()
467 {
468  BL_PROFILE("Integrator::InitData");
469 
470  if (restart_file_cell == "" && restart_file_node == "")
471  {
472  const amrex::Real time = 0.0;
473  InitFromScratch(time);
474 
475  for (int lev = finest_level - 1; lev >= 0; --lev)
476  {
477  if (lev < max_level) regrid(lev, 0.0);
478  for (int n = 0; n < cell.number_of_fabs; n++)
479  amrex::average_down(*(*cell.fab_array[n])[lev + 1], *(*cell.fab_array[n])[lev],
480  geom[lev + 1], geom[lev],
481  0, (*cell.fab_array[n])[lev]->nComp(), refRatio(lev));
482  }
483  SetFinestLevel(finest_level);
484  }
485  if (restart_file_cell != "")
486  {
487  Restart(restart_file_cell, false);
488  }
489  if (restart_file_node != "")
490  {
491  Restart(restart_file_node, true);
492  }
493 
494  if (plot_int > 0 || plot_dt > 0.0) {
495  WritePlotFile();
496  }
497 }
498 
499 void
500 Integrator::Restart(const std::string dirname, bool a_nodal)
501 {
502  BL_PROFILE("Integrator::Restart");
503 
504  if (a_nodal && node.fab_array.size() == 0)
505  {
506  Util::Message(INFO, "Nothing here for nodal fabs");
507  return;
508  }
509  if (!a_nodal && cell.fab_array.size() == 0)
510  {
511  Util::Message(INFO, "Nothing here for cell-based fabs");
512  return;
513  }
514 
515  std::string filename = dirname + "/Header";
516  std::string chkptfilename = dirname + "/Checkpoint";
517  amrex::VisMF::IO_Buffer io_buffer(amrex::VisMF::GetIOBufferSize());
518  amrex::Vector<char> fileCharPtr, chkptfileCharPtr;
519  amrex::ParallelDescriptor::ReadAndBcastFile(filename, fileCharPtr);
520  amrex::ParallelDescriptor::ReadAndBcastFile(chkptfilename, chkptfileCharPtr);
521  std::string fileCharPtrString(fileCharPtr.dataPtr());
522  std::string chkptfileCharPtrString(chkptfileCharPtr.dataPtr());
523  std::istringstream is(fileCharPtrString, std::istringstream::in);
524  std::istringstream chkpt_is(chkptfileCharPtrString, std::istringstream::in);
525 
526  std::string line, word;
527 
528  // Get version
529  std::getline(is, line);
530  Util::Message(INFO, "Version: ", line);
531 
532  // Get number of fabs
533  int tmp_numfabs;
534  std::getline(is, line); tmp_numfabs = std::stoi(line);
535  Util::Message(INFO, "number of fabs:", tmp_numfabs);
536  std::vector<std::string> tmp_name_array;
537 
538  for (int i = 0; i < tmp_numfabs; i++)
539  {
540  std::getline(is, line);
541  tmp_name_array.push_back(line);
542  }
543 
544  // Dimension?
545  std::getline(is, line);
546  Util::Warning(INFO, "Dimension: " + line);
547 
548  // Current time
549  Set::Scalar tmp_time = 0.0;
550  std::getline(is, line); tmp_time = std::stof(line); Util::Message(INFO, "Current time: ", tmp_time);
551  for (int i = 0; i < max_level + 1; i++)
552  {
553  t_new[i] = tmp_time; t_old[i] = tmp_time;
554  }
555 
556  // AMR level
557  int tmp_max_level;
558  std::getline(is, line); tmp_max_level = std::stoi(line); Util::Message(INFO, "Max AMR level: ", line);
559  if (tmp_max_level != max_level)
560  Util::Abort(INFO, "The max level specified (", max_level, ") does not match the max level in the restart file (", tmp_max_level, ")");
561  finest_level = tmp_max_level;
562  // Geometry ?
563  std::getline(is, line); Util::Message(INFO, "Input geometry: ", line);
564  std::getline(is, line); Util::Message(INFO, " ", line);
565 
566  // Mesh refinement ratio?
567  std::getline(is, line); Util::Message(INFO, "Mesh refinement ratio: ", line);
568 
569  // Domain
570  std::getline(is, line); Util::Warning(INFO, "Domain: ", line);
571 
572  // Domain
573  std::getline(is, line);
574  std::vector<std::string> tmp_iters = Util::String::Split(line);
575  if (tmp_iters.size() != (unsigned int)(max_level + 1)) Util::Abort(INFO, "Error reading in interation counts: line = ", line);
576  for (int lev = 0; lev <= max_level; lev++) { istep[lev] = std::stoi(tmp_iters[lev]); Util::Message(INFO, "Iter on level ", lev, " = ", istep[lev]); }
577 
578  amrex::Vector<amrex::MultiFab> tmpdata(tmp_max_level + 1);
579  int total_ncomp = 0;
580 
581  if (a_nodal) for (unsigned int i = 0; i < node.fab_array.size(); i++) total_ncomp += node.ncomp_array[i];
582  else for (unsigned int i = 0; i < cell.fab_array.size(); i++) total_ncomp += cell.ncomp_array[i];
583 
584  int total_nghost = a_nodal ? 0 : cell.nghost_array[0];
585 
586  for (int lev = 0; lev <= max_level; lev++)
587  {
588  amrex::BoxArray tmp_ba;
589  tmp_ba.readFrom(chkpt_is);
590  SetBoxArray(lev, tmp_ba);
591  amrex::DistributionMapping tmp_dm(tmp_ba, amrex::ParallelDescriptor::NProcs());
592  SetDistributionMap(lev, tmp_dm);
593 
594  if (a_nodal)
595  {
596  amrex::BoxArray ngrids = grids[lev];
597  ngrids.convert(amrex::IntVect::TheNodeVector());
598  tmpdata[lev].define(ngrids, dmap[lev], total_ncomp, total_nghost);
599  }
600  else
601  {
602  tmpdata[lev].define(grids[lev], dmap[lev], total_ncomp, total_nghost);
603  }
604  amrex::VisMF::Read(tmpdata[lev],
605  amrex::MultiFabFileFullPrefix(lev, dirname, "Level_", "Cell"));
606 
607 
608  if (a_nodal)
609  for (int i = 0; i < node.number_of_fabs; i++)
610  {
611  amrex::BoxArray ngrids = grids[lev];
612  ngrids.convert(amrex::IntVect::TheNodeVector());
613  (*node.fab_array[i])[lev].reset(new amrex::MultiFab(ngrids, dmap[lev], node.ncomp_array[i], node.nghost_array[i]));
614  (*node.fab_array[i])[lev]->setVal(0.);
615  }
616  else
617  for (int i = 0; i < cell.number_of_fabs; i++)
618  (*cell.fab_array[i])[lev].reset(new amrex::MultiFab(grids[lev], dmap[lev], cell.ncomp_array[i], cell.nghost_array[i]));
619  for (int i = 0; i < tmp_numfabs; i++)
620  {
621  bool match = false;
622  if (a_nodal)
623  {
624  for (int j = 0; j < node.number_of_fabs; j++)
625  {
626  if (tmp_name_array[i] == node.name_array[i][j])
627  {
628  match = true;
629  Util::Message(INFO, "Initializing ", node.name_array[i][j], "; nghost=", node.nghost_array[j], " with ", tmp_name_array[i]);
630  amrex::MultiFab::Copy(*((*node.fab_array[j])[lev]).get(), tmpdata[lev], i, 0, 1, total_nghost);
631  }
632  for (int k = 0; k < node.ncomp_array[j]; k++)
633  {
634  if (tmp_name_array[i] == node.name_array[j][k])
635  {
636  match = true;
637  Util::Message(INFO, "Initializing ", node.name_array[j][k], "; ncomp=", node.ncomp_array[j], "; nghost=", node.nghost_array[j], " with ", tmp_name_array[i]);
638  amrex::MultiFab::Copy(*((*node.fab_array[j])[lev]).get(), tmpdata[lev], i, k, 1, total_nghost);
639  }
640  }
641  Util::RealFillBoundary(*((*node.fab_array[j])[lev]).get(), geom[lev]);
642  }
643  }
644  else
645  {
646  for (int j = 0; j < cell.number_of_fabs; j++)
647  for (int k = 0; k < cell.ncomp_array[j]; k++)
648  {
649  if (tmp_name_array[i] == cell.name_array[j][k])
650  {
651  match = true;
652  Util::Message(INFO, "Initializing ", cell.name_array[j][k], "; ncomp=", cell.ncomp_array[j], "; nghost=", cell.nghost_array[j], " with ", tmp_name_array[i]);
653  amrex::MultiFab::Copy(*((*cell.fab_array[j])[lev]).get(), tmpdata[lev], i, k, 1, cell.nghost_array[j]);
654  }
655  }
656  }
657  if (!match) Util::Warning(INFO, "Fab ", tmp_name_array[i], " is in the restart file, but there is no fab with that name here.");
658  }
659 
660  for (unsigned int n = 0; n < m_basefields_cell.size(); n++)
661  {
662  m_basefields_cell[n]->MakeNewLevelFromScratch(lev, t_new[lev], grids[lev], dmap[lev]);
663  }
664  for (unsigned int n = 0; n < m_basefields.size(); n++)
665  {
666  m_basefields[n]->MakeNewLevelFromScratch(lev, t_new[lev], grids[lev], dmap[lev]);
667  }
668  }
669 
670  SetFinestLevel(max_level);
671 }
672 
673 void
674 Integrator::MakeNewLevelFromScratch(int lev, amrex::Real t, const amrex::BoxArray& cgrids,
675  const amrex::DistributionMapping& dm)
676 {
677  BL_PROFILE("Integrator::MakeNewLevelFromScratch");
678  for (int n = 0; n < cell.number_of_fabs; n++)
679  {
680  (*cell.fab_array[n])[lev].reset(new amrex::MultiFab(cgrids, dm, cell.ncomp_array[n], cell.nghost_array[n]));
681  (*cell.fab_array[n])[lev]->setVal(0.0);
682  }
683 
684  amrex::BoxArray ngrids = cgrids;
685  ngrids.convert(amrex::IntVect::TheNodeVector());
686  for (int n = 0; n < node.number_of_fabs; n++)
687  {
688  (*node.fab_array[n])[lev].reset(new amrex::MultiFab(ngrids, dm, node.ncomp_array[n], node.nghost_array[n]));
689  (*node.fab_array[n])[lev]->setVal(0.0);
690  }
691  for (unsigned int n = 0; n < m_basefields_cell.size(); n++)
692  {
693  m_basefields_cell[n]->MakeNewLevelFromScratch(lev, t, cgrids, dm);
694  }
695  for (unsigned int n = 0; n < m_basefields.size(); n++)
696  {
697  m_basefields[n]->MakeNewLevelFromScratch(lev, t, cgrids, dm);
698  }
699 
700  t_new[lev] = t;
701  t_old[lev] = t - dt[lev];
702 
703  Initialize(lev);
704 
705  for (int n = 0; n < cell.number_of_fabs; n++)
706  {
707  cell.physbc_array[n]->define(geom[lev]);
708  cell.physbc_array[n]->FillBoundary(*(*cell.fab_array[n])[lev], 0, 0, t, 0);
709  }
710 
711  //for (int n = 0 ; n < node.number_of_fabs; n++)
712  //{
713  // bcnothing->define(geom[lev]);
714  // for (amrex::MFIter mfi(*(*node.fab_array[n])[lev],true); mfi.isValid(); ++mfi)
715  // {
716  // amrex::BaseFab<Set::Scalar> &patch = (*(*node.fab_array[n])[lev])[mfi];
717  // const amrex::Box& box = mfi.tilebox();
718  // bcnothing->FillBoundary(patch,box,0,0,0,t);
719  // }
720  //}
721 
722  for (unsigned int n = 0; n < m_basefields_cell.size(); n++)
723  {
724  m_basefields_cell[n]->FillBoundary(lev, t);
725  }
726  for (unsigned int n = 0; n < m_basefields.size(); n++)
727  {
728  m_basefields[n]->FillBoundary(lev, t);
729  }
730 }
731 
732 std::vector<std::string>
733 Integrator::PlotFileName(int lev, std::string prefix) const
734 {
735  BL_PROFILE("Integrator::PlotFileName");
736  std::vector<std::string> name;
737  name.push_back(plot_file + "/" + prefix + "/");
738  name.push_back(amrex::Concatenate("", lev, 5));
739  return name;
740 }
741 
742 void
743 Integrator::WritePlotFile(bool initial) const
744 {
745  WritePlotFile(t_new[0], istep, initial, "");
746 }
747 void
748 Integrator::WritePlotFile(std::string prefix, Set::Scalar time, int step) const
749 {
750  amrex::Vector<int> istep(max_level + 1, step);
751  WritePlotFile(time, istep, false, prefix);
752 }
753 
754 void
755 Integrator::WritePlotFile(Set::Scalar time, amrex::Vector<int> iter, bool initial, std::string prefix) const
756 {
757  BL_PROFILE("Integrator::WritePlotFile");
758  int nlevels = finest_level + 1;
759  if (max_plot_level >= 0) nlevels = std::min(nlevels, max_plot_level);
760 
761  int ccomponents = 0, ncomponents = 0, bfcomponents_cell = 0, bfcomponents = 0;
762  amrex::Vector<std::string> cnames, nnames, bfnames_cell, bfnames;
763  for (int i = 0; i < cell.number_of_fabs; i++)
764  {
765  if (!cell.writeout_array[i]) continue;
766  ccomponents += cell.ncomp_array[i];
767  if (cell.ncomp_array[i] > 1)
768  for (int j = 0; j < cell.ncomp_array[i]; j++)
769  cnames.push_back(cell.name_array[i][j]);
770  else
771  cnames.push_back(cell.name_array[i][0]);
772  }
773  for (int i = 0; i < node.number_of_fabs; i++)
774  {
775  if (!node.writeout_array[i]) continue;
776  ncomponents += node.ncomp_array[i];
777  if (node.ncomp_array[i] > 1)
778  for (int j = 0; j < node.ncomp_array[i]; j++)
779  nnames.push_back(node.name_array[i][j]);
780  else
781  nnames.push_back(node.name_array[i][0]);
782  }
783  for (unsigned int i = 0; i < m_basefields_cell.size(); i++)
784  {
785  if (m_basefields_cell[i]->writeout)
786  {
787  bfcomponents_cell += m_basefields_cell[i]->NComp();
788  for (int j = 0; j < m_basefields_cell[i]->NComp(); j++)
789  bfnames_cell.push_back(m_basefields_cell[i]->Name(j));
790  }
791  }
792  for (unsigned int i = 0; i < m_basefields.size(); i++)
793  {
794  if (m_basefields[i]->writeout)
795  {
796  bfcomponents += m_basefields[i]->NComp();
797  for (int j = 0; j < m_basefields[i]->NComp(); j++)
798  bfnames.push_back(m_basefields[i]->Name(j));
799  }
800  }
801 
802  amrex::Vector<amrex::MultiFab> cplotmf(nlevels), nplotmf(nlevels);
803 
804  bool do_cell_plotfile = (ccomponents + bfcomponents_cell > 0 || (ncomponents + bfcomponents > 0 && cell.all)) && cell.any;
805  bool do_node_plotfile = (ncomponents + bfcomponents > 0 || (ccomponents + bfcomponents_cell > 0 && node.all)) && node.any;
806 
807  for (int ilev = 0; ilev < nlevels; ++ilev)
808  {
809  if (do_cell_plotfile)
810  {
811  int ncomp = ccomponents + bfcomponents_cell;
812  if (cell.all) ncomp += ncomponents + bfcomponents;
813  cplotmf[ilev].define(grids[ilev], dmap[ilev], ncomp, 0);
814 
815  int n = 0;
816  for (int i = 0; i < cell.number_of_fabs; i++)
817  {
818  if (!cell.writeout_array[i]) continue;
819  if ((*cell.fab_array[i])[ilev]->contains_nan())
820  {
821  if (abort_on_nan) Util::Abort(INFO, cnames[i], " contains nan (i=", i, ")");
822  else Util::Warning(INFO, cnames[i], " contains nan (i=", i, ")");
823  }
824  if ((*cell.fab_array[i])[ilev]->contains_inf())
825  {
826  if (abort_on_nan) Util::Abort(INFO, cnames[i], " contains inf (i=", i, ")");
827  else Util::Warning(INFO, cnames[i], " contains inf (i=", i, ")");
828  }
829  amrex::MultiFab::Copy(cplotmf[ilev], *(*cell.fab_array[i])[ilev], 0, n, cell.ncomp_array[i], 0);
830  n += cell.ncomp_array[i];
831  }
832  for (unsigned int i = 0; i < m_basefields_cell.size(); i++)
833  {
834  if (m_basefields_cell[i]->writeout)
835  {
836  m_basefields_cell[i]->Copy(ilev, cplotmf[ilev], n, 0);
837  n += m_basefields_cell[i]->NComp();
838  }
839  }
840 
841  if (cell.all)
842  {
843  for (int i = 0; i < node.number_of_fabs; i++)
844  {
845  if (!node.writeout_array[i]) continue;
846  if ((*node.fab_array[i])[ilev]->contains_nan()) Util::Abort(INFO, nnames[i], " contains nan (i=", i, ")");
847  if ((*node.fab_array[i])[ilev]->contains_inf()) Util::Abort(INFO, nnames[i], " contains inf (i=", i, ")");
848  amrex::average_node_to_cellcenter(cplotmf[ilev], n, *(*node.fab_array[i])[ilev], 0, node.ncomp_array[i], 0);
849  n += node.ncomp_array[i];
850  }
851 
852  if (bfcomponents > 0)
853  {
854  amrex::BoxArray ngrids = grids[ilev];
855  ngrids.convert(amrex::IntVect::TheNodeVector());
856  amrex::MultiFab bfplotmf(ngrids, dmap[ilev], bfcomponents, 0);
857  int ctr = 0;
858  for (unsigned int i = 0; i < m_basefields.size(); i++)
859  {
860  if (m_basefields[i]->writeout)
861  {
862  m_basefields[i]->Copy(ilev, bfplotmf, ctr, 0);
863  ctr += m_basefields[i]->NComp();
864  }
865  }
866  amrex::average_node_to_cellcenter(cplotmf[ilev], n, bfplotmf, 0, bfcomponents);
867  n += bfcomponents;
868  }
869  }
870  }
871 
872  if (do_node_plotfile)
873  {
874  amrex::BoxArray ngrids = grids[ilev];
875  ngrids.convert(amrex::IntVect::TheNodeVector());
876  int ncomp = ncomponents + bfcomponents;
877  if (node.all) ncomp += ccomponents + bfcomponents_cell;
878  nplotmf[ilev].define(ngrids, dmap[ilev], ncomp, 0);
879 
880  int n = 0;
881  for (int i = 0; i < node.number_of_fabs; i++)
882  {
883  if (!node.writeout_array[i]) continue;
884  if ((*node.fab_array[i])[ilev]->contains_nan()) Util::Warning(INFO, nnames[i], " contains nan (i=", i, "). Resetting to zero.");
885  if ((*node.fab_array[i])[ilev]->contains_inf()) Util::Abort(INFO, nnames[i], " contains inf (i=", i, ")");
886  amrex::MultiFab::Copy(nplotmf[ilev], *(*node.fab_array[i])[ilev], 0, n, node.ncomp_array[i], 0);
887  n += node.ncomp_array[i];
888  }
889  for (unsigned int i = 0; i < m_basefields.size(); i++)
890  {
891  if (m_basefields[i]->writeout)
892  {
893  m_basefields[i]->Copy(ilev, nplotmf[ilev], n, 0);
894  n += m_basefields[i]->NComp();
895  }
896  }
897 
898  if (node.all)
899  {
900  for (int i = 0; i < cell.number_of_fabs; i++)
901  {
902  if (!cell.writeout_array[i]) continue;
903  if ((*cell.fab_array[i])[ilev]->contains_nan()) Util::Warning(INFO, cnames[i], " contains nan (i=", i, "). Resetting to zero.");
904  if ((*cell.fab_array[i])[ilev]->contains_inf()) Util::Abort(INFO, cnames[i], " contains inf (i=", i, ")");
905  if ((*cell.fab_array[i])[ilev]->nGrow() == 0)
906  {
907  if (initial) Util::Warning(INFO, cnames[i], " has no ghost cells and will not be included in nodal output");
908  continue;
909  }
910  Util::AverageCellcenterToNode(nplotmf[ilev], n, *(*cell.fab_array[i])[ilev], 0, cell.ncomp_array[i]);
911  n += cell.ncomp_array[i];
912  }
913 
914  if (bfcomponents_cell > 0)
915  {
916  amrex::BoxArray cgrids = grids[ilev];
917  amrex::MultiFab bfplotmf(cgrids, dmap[ilev], bfcomponents_cell, 0);
918  int ctr = 0;
919  for (unsigned int i = 0; i < m_basefields_cell.size(); i++)
920  {
921  if (m_basefields_cell[i]->writeout)
922  {
923  m_basefields_cell[i]->Copy(ilev, bfplotmf, ctr, 0);
924  ctr += m_basefields_cell[i]->NComp();
925  }
926  }
927  Util::AverageCellcenterToNode(nplotmf[ilev], n, bfplotmf, 0, bfcomponents_cell);
928  n += bfcomponents_cell;
929  }
930  }
931  }
932  }
933 
934  std::vector<std::string> plotfilename = PlotFileName(istep[0], prefix);
935  if (initial) plotfilename[1] = plotfilename[1] + "init";
936 
937  if (do_cell_plotfile)
938  {
939  amrex::Vector<std::string> allnames = cnames;
940  allnames.insert(allnames.end(), bfnames_cell.begin(), bfnames_cell.end());
941  if (cell.all) {
942  allnames.insert(allnames.end(), nnames.begin(), nnames.end());
943  allnames.insert(allnames.end(), bfnames.begin(), bfnames.end());
944  }
945  WriteMultiLevelPlotfile(plotfilename[0] + plotfilename[1] + "cell", nlevels, amrex::GetVecOfConstPtrs(cplotmf), allnames,
946  Geom(), time, iter, refRatio());
947 
948  std::ofstream chkptfile;
949  chkptfile.open(plotfilename[0] + plotfilename[1] + "cell/Checkpoint");
950  for (int i = 0; i <= max_level; i++) boxArray(i).writeOn(chkptfile);
951  chkptfile.close();
952  }
953 
954  if (do_node_plotfile)
955  {
956  amrex::Vector<std::string> allnames = nnames;
957  allnames.insert(allnames.end(), bfnames.begin(), bfnames.end());
958  if (node.all) allnames.insert(allnames.end(), cnames.begin(), cnames.end());
959  WriteMultiLevelPlotfile(plotfilename[0] + plotfilename[1] + "node", nlevels, amrex::GetVecOfConstPtrs(nplotmf), allnames,
960  Geom(), time, iter, refRatio());
961 
962  std::ofstream chkptfile;
963  chkptfile.open(plotfilename[0] + plotfilename[1] + "node/Checkpoint");
964  for (int i = 0; i <= max_level; i++) boxArray(i).writeOn(chkptfile);
965  chkptfile.close();
966  }
967 
968  if (amrex::ParallelDescriptor::IOProcessor())
969  {
970  std::ofstream coutfile, noutfile;
971  if (istep[0] == 0)
972  {
973  if (do_cell_plotfile) coutfile.open(plot_file + "/celloutput.visit", std::ios_base::out);
974  if (do_node_plotfile) noutfile.open(plot_file + "/nodeoutput.visit", std::ios_base::out);
975  }
976  else
977  {
978  if (do_cell_plotfile) coutfile.open(plot_file + "/celloutput.visit", std::ios_base::app);
979  if (do_node_plotfile) noutfile.open(plot_file + "/nodeoutput.visit", std::ios_base::app);
980  }
981  if (do_cell_plotfile) coutfile << plotfilename[1] + "cell" + "/Header" << std::endl;
982  if (do_node_plotfile) noutfile << plotfilename[1] + "node" + "/Header" << std::endl;
983  }
984 }
985 
986 void
987 Integrator::Evolve()
988 {
989  BL_PROFILE("Integrator::Evolve");
990  amrex::Real cur_time = t_new[0];
991  int last_plot_file_step = 0;
992 
993  for (int step = istep[0]; step < max_step && cur_time < stop_time; ++step)
994  {
995  if (amrex::ParallelDescriptor::IOProcessor()) {
996  std::cout << "\nSTEP " << step + 1 << " starts ..." << std::endl;
997  }
998  int lev = 0;
999  int iteration = 1;
1000  TimeStepBegin(cur_time, step);
1001  if (integrate_variables_before_advance) IntegrateVariables(cur_time, step);
1002  TimeStep(lev, cur_time, iteration);
1003  if (integrate_variables_after_advance) IntegrateVariables(cur_time, step);
1004  TimeStepComplete(cur_time, step);
1005  cur_time += dt[0];
1006 
1007  if (amrex::ParallelDescriptor::IOProcessor()) {
1008  std::cout << "STEP " << step + 1 << " ends."
1009  << " TIME = " << cur_time << " DT = " << dt[0]
1010  << std::endl;
1011  }
1012 
1013  // sync up time
1014  for (int lev = 0; lev <= finest_level; ++lev) {
1015  t_new[lev] = cur_time;
1016  }
1017 
1018  if (plot_int > 0 && (step + 1) % plot_int == 0) {
1019  last_plot_file_step = step + 1;
1020  WritePlotFile();
1021  IO::WriteMetaData(plot_file, IO::Status::Running, (int)(100.0 * cur_time / stop_time));
1022  }
1023  else if (std::fabs(std::remainder(cur_time, plot_dt)) < 0.5 * dt[0])
1024  {
1025  last_plot_file_step = step + 1;
1026  WritePlotFile();
1027  IO::WriteMetaData(plot_file, IO::Status::Running, (int)(100.0 * cur_time / stop_time));
1028  }
1029 
1030  if (cur_time >= stop_time - 1.e-6 * dt[0]) break;
1031  }
1032  if (plot_int > 0 && istep[0] > last_plot_file_step) {
1033  WritePlotFile();
1034  }
1035 }
1036 
1037 void
1038 Integrator::IntegrateVariables(amrex::Real time, int step)
1039 {
1040  BL_PROFILE("Integrator::IntegrateVariables");
1041  if (!thermo.number) return;
1042 
1043  if ((thermo.interval > 0 && (step) % thermo.interval == 0) ||
1044  ((thermo.dt > 0.0) && (std::fabs(std::remainder(time, plot_dt)) < 0.5 * dt[0])))
1045  {
1046  // Zero out all variables
1047  for (int i = 0; i < thermo.number; i++)
1048  {
1049  if (thermo.extensives[i]) *thermo.vars[i] = 0;
1050  }
1051 
1052  // All levels except the finest
1053  for (int ilev = 0; ilev < max_level; ilev++)
1054  {
1055  const amrex::BoxArray& cfba = amrex::coarsen(grids[ilev + 1], refRatio(ilev));
1056 
1057 #ifdef OMP
1058 #pragma omp parallel
1059 #endif
1060  for (amrex::MFIter mfi(grids[ilev], dmap[ilev], true); mfi.isValid(); ++mfi)
1061  {
1062  const amrex::Box& box = mfi.tilebox();
1063  const amrex::BoxArray& comp = amrex::complementIn(box, cfba);
1064 
1065  for (int i = 0; i < comp.size(); i++)
1066  {
1067  Integrate(ilev, time, step,
1068  mfi, comp[i]);
1069  }
1070  }
1071  }
1072  // Now do the finest level
1073  {
1074 #ifdef OMP
1075 #pragma omp parallel
1076 #endif
1077  for (amrex::MFIter mfi(grids[max_level], dmap[max_level], true); mfi.isValid(); ++mfi)
1078  {
1079  const amrex::Box& box = mfi.tilebox();
1080  Integrate(max_level, time, step, mfi, box);
1081  }
1082  }
1083 
1084  // Sum up across all processors
1085  for (int i = 0; i < thermo.number; i++)
1086  {
1087  if (thermo.extensives[i])
1088  amrex::ParallelDescriptor::ReduceRealSum(*thermo.vars[i]);
1089  }
1090  }
1091  if (amrex::ParallelDescriptor::IOProcessor() &&
1092  (
1093  (thermo.plot_int > 0 && step % thermo.plot_int == 0) ||
1094  (thermo.plot_dt > 0.0 && std::fabs(std::remainder(time, thermo.plot_dt)) < 0.5 * dt[0])
1095  ))
1096  {
1097  std::ofstream outfile;
1098  if (step == 0)
1099  {
1100  outfile.open(plot_file + "/thermo.dat", std::ios_base::out);
1101  outfile << "time";
1102  for (int i = 0; i < thermo.number; i++)
1103  outfile << "\t" << thermo.names[i];
1104  outfile << std::endl;
1105  }
1106  else outfile.open(plot_file + "/thermo.dat", std::ios_base::app);
1107  outfile << time;
1108  for (int i = 0; i < thermo.number; i++)
1109  outfile << "\t" << *thermo.vars[i];
1110  outfile << std::endl;
1111  outfile.close();
1112  }
1113 
1114 }
1115 
1116 
1117 void
1118 Integrator::TimeStep(int lev, amrex::Real time, int /*iteration*/)
1119 {
1120  BL_PROFILE("Integrator::TimeStep");
1121  if (base_regrid_int <= 0 || istep[0] % base_regrid_int == 0)
1122  {
1123  if (regrid_int > 0 || base_regrid_int > 0) // We may need to regrid
1124  {
1125  static amrex::Vector<int> last_regrid_step(max_level + 1, 0);
1126 
1127  // regrid doesn't change the base level, so we don't regrid on max_level
1128  if (lev < max_level && istep[lev] > last_regrid_step[lev])
1129  {
1130  if (istep[lev] % regrid_int == 0)
1131  {
1132  regrid(lev, time, false);
1133  }
1134  }
1135  }
1136  }
1137  SetFinestLevel(finest_level);
1138 
1139  if (Verbose() && amrex::ParallelDescriptor::IOProcessor()) {
1140  std::cout << "[Level " << lev
1141  << " step " << istep[lev] + 1 << "] ";
1142  std::cout << "ADVANCE with dt = "
1143  << dt[lev]
1144  << std::endl;
1145  }
1146 
1147  for (int n = 0; n < cell.number_of_fabs; n++)
1148  FillPatch(lev, time, *cell.fab_array[n], *(*cell.fab_array[n])[lev], *cell.physbc_array[n], 0);
1149  for (int n = 0; n < node.number_of_fabs; n++)
1150  FillPatch(lev, time, *node.fab_array[n], *(*node.fab_array[n])[lev], *node.physbc_array[n], 0);
1151  for (unsigned int n = 0; n < m_basefields_cell.size(); n++)
1152  if (m_basefields_cell[n]->evolving) m_basefields_cell[n]->FillPatch(lev, time);
1153  for (unsigned int n = 0; n < m_basefields.size(); n++)
1154  if (m_basefields[n]->evolving) m_basefields[n]->FillPatch(lev, time);
1155 
1156  Advance(lev, time, dt[lev]);
1157  ++istep[lev];
1158 
1159  if (Verbose() && amrex::ParallelDescriptor::IOProcessor())
1160  {
1161  std::cout << "[Level " << lev
1162  << " step " << istep[lev] << "] ";
1163  std::cout << "Advanced "
1164  << CountCells(lev)
1165  << " cells"
1166  << std::endl;
1167  }
1168 
1169  if (lev < finest_level)
1170  {
1171  for (int i = 1; i <= nsubsteps[lev + 1]; ++i)
1172  TimeStep(lev + 1, time + (i - 1) * dt[lev + 1], i);
1173 
1174  for (int n = 0; n < cell.number_of_fabs; n++)
1175  {
1176  amrex::average_down(*(*cell.fab_array[n])[lev + 1], *(*cell.fab_array[n])[lev],
1177  geom[lev + 1], geom[lev],
1178  0, (*cell.fab_array[n])[lev]->nComp(), refRatio(lev));
1179  }
1180  for (int n = 0; n < node.number_of_fabs; n++)
1181  {
1182  amrex::average_down(*(*node.fab_array[n])[lev + 1], *(*node.fab_array[n])[lev],
1183  0, (*node.fab_array[n])[lev]->nComp(), refRatio(lev));
1184  }
1185  for (unsigned int n = 0; n < m_basefields_cell.size(); n++)
1186  {
1187  if (m_basefields_cell[n]->evolving)
1188  m_basefields_cell[n]->AverageDown(lev, refRatio(lev));
1189  }
1190  for (unsigned int n = 0; n < m_basefields.size(); n++)
1191  {
1192  if (m_basefields[n]->evolving)
1193  m_basefields[n]->AverageDown(lev, refRatio(lev));
1194  }
1195 
1196  }
1197 }
1198 }
IO::WriteMetaData
void WriteMetaData(std::string plot_file, Status status, int per)
Definition: WriteMetaData.cpp:17
Util::filename
std::string filename
Definition: Util.cpp:19
Util::Initialize
void Initialize()
Definition: Util.cpp:126
Util::RealFillBoundary
AMREX_FORCE_INLINE void RealFillBoundary(amrex::FabArray< amrex::BaseFab< T >> &a_mf, const amrex::Geometry &)
Definition: Util.H:319
BC::BC< Set::Scalar >
Util::GetFileName
std::string GetFileName()
Definition: Util.cpp:23
FileNameParse.H
BC::AMREX_D_DECL
@ AMREX_D_DECL
Definition: BC.H:34
BC::BC::define
void define(const amrex::Geometry &a_geom)
Definition: BC.H:49
Util.H
Util::AverageCellcenterToNode
void AverageCellcenterToNode(amrex::MultiFab &node_mf, const int &dcomp, const amrex::MultiFab &cell_mf, const int &scomp, const int &ncomp)
Definition: Util.cpp:405
IO::FileNameParse
void FileNameParse(std::string &filename)
Definition: FileNameParse.cpp:14
BC::BC::GetBCRec
virtual amrex::BCRec GetBCRec()=0
TEST
#define TEST(x)
Definition: Util.H:21
Util::String::Split
std::vector< std::string > Split(std::string &str, const char delim)
Definition: Util.cpp:292
Integrator.H
t
std::time_t t
Definition: FileNameParse.cpp:12
Set::Field< Set::Scalar >
Definition: Set.H:236
Integrator::Integrator
Definition: Integrator.H:73
Util::AssertException
AMREX_FORCE_INLINE void AssertException(std::string file, std::string func, int line, std::string smt, bool pass, Args const &... args)
Definition: Util.H:230
Set::Vector
Eigen::Matrix< amrex::Real, AMREX_SPACEDIM, 1 > Vector
Definition: Base.H:20
ParmParse.H
pp_query
#define pp_query(...)
Definition: ParmParse.H:105
Set::Scalar
amrex::Real Scalar
Definition: Base.H:19
IO::Running
@ Running
Definition: WriteMetaData.H:30
IO::Complete
@ Complete
Definition: WriteMetaData.H:31
IO::ParmParse::contains
bool contains(std::string name)
Definition: ParmParse.H:153
Util::Assert
AMREX_FORCE_INLINE void Assert(std::string file, std::string func, int line, std::string smt, bool pass, Args const &... args)
Definition: Util.H:67
pp_query_default
#define pp_query_default(...)
Definition: ParmParse.H:100
Util::Abort
void Abort(const char *msg)
Definition: Util.cpp:166
Integrator
Collection of numerical integrator objects.
Definition: AllenCahn.H:40
pp_query_validate
#define pp_query_validate(...)
Definition: ParmParse.H:101
Util::Warning
void Warning(std::string file, std::string func, int line, Args const &... args)
Definition: Util.H:178
pp_query_required
#define pp_query_required(...)
Definition: ParmParse.H:99
IO::ParmParse
Definition: ParmParse.H:112
INFO
#define INFO
Definition: Util.H:20
Util::Message
void Message(std::string file, std::string func, int line, Args const &... args)
Definition: Util.H:138
pp_queryarr
#define pp_queryarr(...)
Definition: ParmParse.H:103