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