19 BL_PROFILE(
"Integrator::Integrator()");
27 pp_query(
"restart", restart_file_cell);
28 pp_query(
"restart_cell", restart_file_cell);
29 pp_query(
"restart_node", restart_file_node);
39 std::vector<std::string> ignore;
42 for (
unsigned int i = 0; i < ignore.size(); i++)
45 pp.remove(ignore[i].c_str());
72 nsubsteps.resize(maxLevel() + 1, 1);
73 int cnt = pp.countval(
"nsubsteps");
75 if (cnt == maxLevel()) {
77 nsubsteps.insert(nsubsteps.begin(), 1);
84 for (
int lev = 1; lev <= maxLevel(); ++lev) nsubsteps[lev] = nsubsteps_all;
87 Util::Abort(
INFO,
"number of nsubsteps input must equal either 1 or amr.max_level");
89 for (
int lev = 1; lev <= maxLevel(); ++lev)
90 nsubsteps[lev] = MaxRefRatio(lev - 1);
96 if (dynamictimestep.on)
130 for (
int ilev = 0; ilev < maxLevel(); ++ilev)
132 std::string strlo =
"lo" + std::to_string(ilev + 1);
133 std::string strhi =
"hi" + std::to_string(ilev + 1);
138 amrex::Vector<int> lodata, 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]));
144 explicitmesh.box.push_back(amrex::Box(lo, hi));
149 int nlevs_max = maxLevel() + 1;
151 istep.resize(nlevs_max, 0);
153 t_new.resize(nlevs_max, 0.0);
154 t_old.resize(nlevs_max, -1.e100);
155 SetTimestep(timestep);
165 Integrator::~Integrator()
167 BL_PROFILE(
"Integrator::~Integrator");
168 if (amrex::ParallelDescriptor::IOProcessor())
174 BL_PROFILE(
"Integrator::SetTimestep");
175 int nlevs_max = maxLevel() + 1;
176 timestep = _timestep;
177 dt.resize(nlevs_max, 1.e100);
179 for (
int i = 1; i < nlevs_max; i++)
180 dt[i] = dt[i - 1] / (amrex::Real)nsubsteps[i];
182 void Integrator::SetPlotInt(
int a_plot_int)
184 BL_PROFILE(
"Integrator::SetPlotInt");
185 plot_int = a_plot_int;
193 Integrator::MakeNewLevelFromCoarse(
int lev, amrex::Real time,
const amrex::BoxArray& cgrids,
const amrex::DistributionMapping& dm)
195 BL_PROFILE(
"Integrator::MakeNewLevelFromCoarse");
197 for (
int n = 0; n < cell.number_of_fabs; n++)
199 const int ncomp = (*cell.fab_array[n])[lev - 1]->nComp();
200 const int nghost = (*cell.fab_array[n])[lev - 1]->nGrow();
202 (*cell.fab_array[n])[lev].reset(
new amrex::MultiFab(cgrids, dm, ncomp, nghost));
204 (*cell.fab_array[n])[lev]->setVal(0.0);
206 FillCoarsePatch(lev, time, *cell.fab_array[n], *cell.physbc_array[n], 0, ncomp);
209 amrex::BoxArray ngrids = cgrids;
210 ngrids.convert(amrex::IntVect::TheNodeVector());
212 for (
int n = 0; n < node.number_of_fabs; n++)
214 const int ncomp = (*node.fab_array[n])[lev - 1]->nComp();
215 const int nghost = (*node.fab_array[n])[lev - 1]->nGrow();
217 (*node.fab_array[n])[lev].reset(
new amrex::MultiFab(ngrids, dm, ncomp, nghost));
218 (*node.fab_array[n])[lev]->setVal(0.0);
220 FillCoarsePatch(lev, time, *node.fab_array[n], *node.physbc_array[n], 0, ncomp);
223 for (
unsigned int n = 0; n < m_basefields.size(); n++)
225 m_basefields[n]->MakeNewLevelFromCoarse(lev, time, cgrids, dm);
227 for (
unsigned int n = 0; n < m_basefields_cell.size(); n++)
229 m_basefields_cell[n]->MakeNewLevelFromCoarse(lev, time, cgrids, dm);
242 Integrator::RemakeLevel(
int lev,
244 const amrex::BoxArray& cgrids,
245 const amrex::DistributionMapping& dm)
247 BL_PROFILE(
"Integrator::RemakeLevel");
248 for (
int n = 0; n < cell.number_of_fabs; n++)
250 const int ncomp = (*cell.fab_array[n])[lev]->nComp();
251 const int nghost = (*cell.fab_array[n])[lev]->nGrow();
253 amrex::MultiFab new_state(cgrids, dm, ncomp, nghost);
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]);
260 amrex::BoxArray ngrids = cgrids;
261 ngrids.convert(amrex::IntVect::TheNodeVector());
263 for (
int n = 0; n < node.number_of_fabs; n++)
265 const int ncomp = (*node.fab_array[n])[lev]->nComp();
266 const int nghost = (*node.fab_array[n])[lev]->nGrow();
268 amrex::MultiFab new_state(ngrids, dm, ncomp, nghost);
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]);
275 for (
unsigned int n = 0; n < m_basefields_cell.size(); n++)
277 m_basefields_cell[n]->RemakeLevel(lev, time, cgrids, dm);
279 for (
unsigned int n = 0; n < m_basefields.size(); n++)
281 m_basefields[n]->RemakeLevel(lev, time, cgrids, dm);
292 Integrator::ClearLevel(
int lev)
294 BL_PROFILE(
"Integrator::ClearLevel");
295 for (
int n = 0; n < cell.number_of_fabs; n++)
297 (*cell.fab_array[n])[lev].reset(
nullptr);
299 for (
int n = 0; n < node.number_of_fabs; n++)
301 (*node.fab_array[n])[lev].reset(
nullptr);
317 AddField<Set::Scalar, Set::Hypercube::Cell>(new_fab, new_bc, ncomp, nghost, name, writeout,
true, suffix);
320 Integrator::RegisterNewFab(
Set::Field<Set::Scalar>& new_fab,
int ncomp, std::string name,
bool writeout, std::vector<std::string> suffix)
323 AddField<Set::Scalar, Set::Hypercube::Cell>(new_fab,
nullptr, ncomp, 0, name, writeout,
true, suffix);
329 AddField<Set::Scalar, Set::Hypercube::Node>(new_fab, new_bc, ncomp, nghost, name, writeout,
true,suffix);
332 Integrator::RegisterNodalFab(
Set::Field<Set::Scalar>& new_fab,
int ncomp,
int nghost, std::string name,
bool writeout, std::vector<std::string> suffix)
335 AddField<Set::Scalar, Set::Hypercube::Node>(new_fab,
nullptr, ncomp, nghost, name, writeout,
true,suffix);
342 Integrator::RegisterIntegratedVariable(
Set::Scalar *integrated_variable, std::string name,
bool extensive)
344 BL_PROFILE(
"Integrator::RegisterIntegratedVariable");
345 thermo.vars.push_back(integrated_variable);
346 thermo.names.push_back(name);
347 thermo.extensives.push_back(extensive);
352 Integrator::CountCells(
int lev)
354 BL_PROFILE(
"Integrator::CountCells");
355 const int N = grids[lev].size();
359 for (
int i = 0; i < N; ++i)
361 cnt += grids[lev][i].numPts();
368 Integrator::FillPatch(
int lev, amrex::Real time,
370 amrex::MultiFab& destination_mf,
373 BL_PROFILE(
"Integrator::FillPatch");
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);
383 amrex::FillPatchSingleLevel(destination_mf,
389 destination_mf.nComp(),
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);
405 amrex::Interpolater* mapper;
407 if (destination_mf.boxArray().ixType() == amrex::IndexType::TheNodeType())
408 mapper = &amrex::node_bilinear_interp;
410 mapper = &amrex::cell_cons_interp;
412 amrex::Vector<amrex::BCRec> bcs(destination_mf.nComp(), physbc.
GetBCRec());
413 amrex::FillPatchTwoLevels(destination_mf, time, cmf, ctime, fmf, ftime,
414 0, icomp, destination_mf.nComp(), geom[lev - 1], geom[lev],
427 Integrator::FillCoarsePatch(
int lev,
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);
443 amrex::Interpolater* mapper;
444 if (mf[lev]->boxArray().ixType() == amrex::IndexType::TheNodeType())
445 mapper = &amrex::node_bilinear_interp;
447 mapper = &amrex::cell_cons_interp;
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],
458 Integrator::ErrorEst(
int lev, amrex::TagBoxArray& tags, amrex::Real time,
int ngrow)
460 BL_PROFILE(
"Integrator::ErrorEst");
461 TagCellsForRefinement(lev, tags, time, ngrow);
466 Integrator::InitData()
468 BL_PROFILE(
"Integrator::InitData");
470 if (restart_file_cell ==
"" && restart_file_node ==
"")
472 const amrex::Real time = 0.0;
473 InitFromScratch(time);
475 for (
int lev = finest_level - 1; lev >= 0; --lev)
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));
483 SetFinestLevel(finest_level);
485 if (restart_file_cell !=
"")
487 Restart(restart_file_cell,
false);
489 if (restart_file_node !=
"")
491 Restart(restart_file_node,
true);
494 if (plot_int > 0 || plot_dt > 0.0) {
500 Integrator::Restart(
const std::string dirname,
bool a_nodal)
502 BL_PROFILE(
"Integrator::Restart");
504 if (a_nodal && node.fab_array.size() == 0)
509 if (!a_nodal && cell.fab_array.size() == 0)
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);
526 std::string line, word;
529 std::getline(is, line);
534 std::getline(is, line); tmp_numfabs = std::stoi(line);
536 std::vector<std::string> tmp_name_array;
538 for (
int i = 0; i < tmp_numfabs; i++)
540 std::getline(is, line);
541 tmp_name_array.push_back(line);
545 std::getline(is, line);
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++)
553 t_new[i] = tmp_time; t_old[i] = tmp_time;
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;
573 std::getline(is, 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]); }
578 amrex::Vector<amrex::MultiFab> tmpdata(tmp_max_level + 1);
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];
584 int total_nghost = a_nodal ? 0 : cell.nghost_array[0];
586 for (
int lev = 0; lev <= max_level; lev++)
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);
596 amrex::BoxArray ngrids = grids[lev];
597 ngrids.convert(amrex::IntVect::TheNodeVector());
598 tmpdata[lev].define(ngrids, dmap[lev], total_ncomp, total_nghost);
602 tmpdata[lev].define(grids[lev], dmap[lev], total_ncomp, total_nghost);
604 amrex::VisMF::Read(tmpdata[lev],
605 amrex::MultiFabFileFullPrefix(lev, dirname,
"Level_",
"Cell"));
609 for (
int i = 0; i < node.number_of_fabs; i++)
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.);
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++)
624 for (
int j = 0; j < node.number_of_fabs; j++)
626 if (tmp_name_array[i] == node.name_array[i][j])
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);
632 for (
int k = 0; k < node.ncomp_array[j]; k++)
634 if (tmp_name_array[i] == node.name_array[j][k])
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);
646 for (
int j = 0; j < cell.number_of_fabs; j++)
647 for (
int k = 0; k < cell.ncomp_array[j]; k++)
649 if (tmp_name_array[i] == cell.name_array[j][k])
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]);
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.");
660 for (
unsigned int n = 0; n < m_basefields_cell.size(); n++)
662 m_basefields_cell[n]->MakeNewLevelFromScratch(lev, t_new[lev], grids[lev], dmap[lev]);
664 for (
unsigned int n = 0; n < m_basefields.size(); n++)
666 m_basefields[n]->MakeNewLevelFromScratch(lev, t_new[lev], grids[lev], dmap[lev]);
670 SetFinestLevel(max_level);
674 Integrator::MakeNewLevelFromScratch(
int lev, amrex::Real
t,
const amrex::BoxArray& cgrids,
675 const amrex::DistributionMapping& dm)
677 BL_PROFILE(
"Integrator::MakeNewLevelFromScratch");
678 for (
int n = 0; n < cell.number_of_fabs; n++)
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);
684 amrex::BoxArray ngrids = cgrids;
685 ngrids.convert(amrex::IntVect::TheNodeVector());
686 for (
int n = 0; n < node.number_of_fabs; n++)
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);
691 for (
unsigned int n = 0; n < m_basefields_cell.size(); n++)
693 m_basefields_cell[n]->MakeNewLevelFromScratch(lev,
t, cgrids, dm);
695 for (
unsigned int n = 0; n < m_basefields.size(); n++)
697 m_basefields[n]->MakeNewLevelFromScratch(lev,
t, cgrids, dm);
701 t_old[lev] =
t - dt[lev];
705 for (
int n = 0; n < cell.number_of_fabs; n++)
707 cell.physbc_array[n]->define(geom[lev]);
708 cell.physbc_array[n]->FillBoundary(*(*cell.fab_array[n])[lev], 0, 0,
t, 0);
722 for (
unsigned int n = 0; n < m_basefields_cell.size(); n++)
724 m_basefields_cell[n]->FillBoundary(lev,
t);
726 for (
unsigned int n = 0; n < m_basefields.size(); n++)
728 m_basefields[n]->FillBoundary(lev,
t);
732 std::vector<std::string>
733 Integrator::PlotFileName(
int lev, std::string prefix)
const
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));
743 Integrator::WritePlotFile(
bool initial)
const
745 WritePlotFile(t_new[0], istep, initial,
"");
748 Integrator::WritePlotFile(std::string prefix,
Set::Scalar time,
int step)
const
750 amrex::Vector<int> istep(max_level + 1, step);
751 WritePlotFile(time, istep,
false, prefix);
755 Integrator::WritePlotFile(
Set::Scalar time, amrex::Vector<int> iter,
bool initial, std::string prefix)
const
757 BL_PROFILE(
"Integrator::WritePlotFile");
758 int nlevels = finest_level + 1;
759 if (max_plot_level >= 0) nlevels = std::min(nlevels, max_plot_level);
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++)
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]);
771 cnames.push_back(cell.name_array[i][0]);
773 for (
int i = 0; i < node.number_of_fabs; i++)
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]);
781 nnames.push_back(node.name_array[i][0]);
783 for (
unsigned int i = 0; i < m_basefields_cell.size(); i++)
785 if (m_basefields_cell[i]->writeout)
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));
792 for (
unsigned int i = 0; i < m_basefields.size(); i++)
794 if (m_basefields[i]->writeout)
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));
802 amrex::Vector<amrex::MultiFab> cplotmf(nlevels), nplotmf(nlevels);
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;
807 for (
int ilev = 0; ilev < nlevels; ++ilev)
809 if (do_cell_plotfile)
811 int ncomp = ccomponents + bfcomponents_cell;
812 if (cell.all) ncomp += ncomponents + bfcomponents;
813 cplotmf[ilev].define(grids[ilev], dmap[ilev], ncomp, 0);
816 for (
int i = 0; i < cell.number_of_fabs; i++)
818 if (!cell.writeout_array[i])
continue;
819 if ((*cell.fab_array[i])[ilev]->contains_nan())
821 if (abort_on_nan)
Util::Abort(
INFO, cnames[i],
" contains nan (i=", i,
")");
824 if ((*cell.fab_array[i])[ilev]->contains_inf())
826 if (abort_on_nan)
Util::Abort(
INFO, cnames[i],
" contains inf (i=", i,
")");
829 amrex::MultiFab::Copy(cplotmf[ilev], *(*cell.fab_array[i])[ilev], 0, n, cell.ncomp_array[i], 0);
830 n += cell.ncomp_array[i];
832 for (
unsigned int i = 0; i < m_basefields_cell.size(); i++)
834 if (m_basefields_cell[i]->writeout)
836 m_basefields_cell[i]->Copy(ilev, cplotmf[ilev], n, 0);
837 n += m_basefields_cell[i]->NComp();
843 for (
int i = 0; i < node.number_of_fabs; i++)
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];
852 if (bfcomponents > 0)
854 amrex::BoxArray ngrids = grids[ilev];
855 ngrids.convert(amrex::IntVect::TheNodeVector());
856 amrex::MultiFab bfplotmf(ngrids, dmap[ilev], bfcomponents, 0);
858 for (
unsigned int i = 0; i < m_basefields.size(); i++)
860 if (m_basefields[i]->writeout)
862 m_basefields[i]->Copy(ilev, bfplotmf, ctr, 0);
863 ctr += m_basefields[i]->NComp();
866 amrex::average_node_to_cellcenter(cplotmf[ilev], n, bfplotmf, 0, bfcomponents);
872 if (do_node_plotfile)
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);
881 for (
int i = 0; i < node.number_of_fabs; i++)
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];
889 for (
unsigned int i = 0; i < m_basefields.size(); i++)
891 if (m_basefields[i]->writeout)
893 m_basefields[i]->Copy(ilev, nplotmf[ilev], n, 0);
894 n += m_basefields[i]->NComp();
900 for (
int i = 0; i < cell.number_of_fabs; i++)
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)
907 if (initial)
Util::Warning(
INFO, cnames[i],
" has no ghost cells and will not be included in nodal output");
911 n += cell.ncomp_array[i];
914 if (bfcomponents_cell > 0)
916 amrex::BoxArray cgrids = grids[ilev];
917 amrex::MultiFab bfplotmf(cgrids, dmap[ilev], bfcomponents_cell, 0);
919 for (
unsigned int i = 0; i < m_basefields_cell.size(); i++)
921 if (m_basefields_cell[i]->writeout)
923 m_basefields_cell[i]->Copy(ilev, bfplotmf, ctr, 0);
924 ctr += m_basefields_cell[i]->NComp();
928 n += bfcomponents_cell;
934 std::vector<std::string> plotfilename = PlotFileName(istep[0], prefix);
935 if (initial) plotfilename[1] = plotfilename[1] +
"init";
937 if (do_cell_plotfile)
939 amrex::Vector<std::string> allnames = cnames;
940 allnames.insert(allnames.end(), bfnames_cell.begin(), bfnames_cell.end());
942 allnames.insert(allnames.end(), nnames.begin(), nnames.end());
943 allnames.insert(allnames.end(), bfnames.begin(), bfnames.end());
945 WriteMultiLevelPlotfile(plotfilename[0] + plotfilename[1] +
"cell", nlevels, amrex::GetVecOfConstPtrs(cplotmf), allnames,
946 Geom(), time, iter, refRatio());
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);
954 if (do_node_plotfile)
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());
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);
968 if (amrex::ParallelDescriptor::IOProcessor())
970 std::ofstream coutfile, noutfile;
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);
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);
981 if (do_cell_plotfile) coutfile << plotfilename[1] +
"cell" +
"/Header" << std::endl;
982 if (do_node_plotfile) noutfile << plotfilename[1] +
"node" +
"/Header" << std::endl;
989 BL_PROFILE(
"Integrator::Evolve");
990 amrex::Real cur_time = t_new[0];
991 int last_plot_file_step = 0;
993 for (
int step = istep[0]; step < max_step && cur_time < stop_time; ++step)
995 if (amrex::ParallelDescriptor::IOProcessor()) {
996 std::cout <<
"\nSTEP " << step + 1 <<
" starts ..." << std::endl;
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);
1007 if (amrex::ParallelDescriptor::IOProcessor()) {
1008 std::cout <<
"STEP " << step + 1 <<
" ends."
1009 <<
" TIME = " << cur_time <<
" DT = " << dt[0]
1014 for (
int lev = 0; lev <= finest_level; ++lev) {
1015 t_new[lev] = cur_time;
1018 if (plot_int > 0 && (step + 1) % plot_int == 0) {
1019 last_plot_file_step = step + 1;
1023 else if (std::fabs(std::remainder(cur_time, plot_dt)) < 0.5 * dt[0])
1025 last_plot_file_step = step + 1;
1030 if (cur_time >= stop_time - 1.e-6 * dt[0])
break;
1032 if (plot_int > 0 && istep[0] > last_plot_file_step) {
1038 Integrator::IntegrateVariables(amrex::Real time,
int step)
1040 BL_PROFILE(
"Integrator::IntegrateVariables");
1041 if (!thermo.number)
return;
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])))
1047 for (
int i = 0; i < thermo.number; i++)
1049 if (thermo.extensives[i]) *thermo.vars[i] = 0;
1053 for (
int ilev = 0; ilev < max_level; ilev++)
1055 const amrex::BoxArray& cfba = amrex::coarsen(grids[ilev + 1], refRatio(ilev));
1058 #pragma omp parallel
1060 for (amrex::MFIter mfi(grids[ilev], dmap[ilev],
true); mfi.isValid(); ++mfi)
1062 const amrex::Box& box = mfi.tilebox();
1063 const amrex::BoxArray& comp = amrex::complementIn(box, cfba);
1065 for (
int i = 0; i < comp.size(); i++)
1067 Integrate(ilev, time, step,
1075 #pragma omp parallel
1077 for (amrex::MFIter mfi(grids[max_level], dmap[max_level],
true); mfi.isValid(); ++mfi)
1079 const amrex::Box& box = mfi.tilebox();
1080 Integrate(max_level, time, step, mfi, box);
1085 for (
int i = 0; i < thermo.number; i++)
1087 if (thermo.extensives[i])
1088 amrex::ParallelDescriptor::ReduceRealSum(*thermo.vars[i]);
1091 if (amrex::ParallelDescriptor::IOProcessor() &&
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])
1097 std::ofstream outfile;
1100 outfile.open(plot_file +
"/thermo.dat", std::ios_base::out);
1102 for (
int i = 0; i < thermo.number; i++)
1103 outfile <<
"\t" << thermo.names[i];
1104 outfile << std::endl;
1106 else outfile.open(plot_file +
"/thermo.dat", std::ios_base::app);
1108 for (
int i = 0; i < thermo.number; i++)
1109 outfile <<
"\t" << *thermo.vars[i];
1110 outfile << std::endl;
1118 Integrator::TimeStep(
int lev, amrex::Real time,
int )
1120 BL_PROFILE(
"Integrator::TimeStep");
1121 if (base_regrid_int <= 0 || istep[0] % base_regrid_int == 0)
1123 if (regrid_int > 0 || base_regrid_int > 0)
1125 static amrex::Vector<int> last_regrid_step(max_level + 1, 0);
1128 if (lev < max_level && istep[lev] > last_regrid_step[lev])
1130 if (istep[lev] % regrid_int == 0)
1132 regrid(lev, time,
false);
1137 SetFinestLevel(finest_level);
1139 if (Verbose() && amrex::ParallelDescriptor::IOProcessor()) {
1140 std::cout <<
"[Level " << lev
1141 <<
" step " << istep[lev] + 1 <<
"] ";
1142 std::cout <<
"ADVANCE with dt = "
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);
1156 Advance(lev, time, dt[lev]);
1159 if (Verbose() && amrex::ParallelDescriptor::IOProcessor())
1161 std::cout <<
"[Level " << lev
1162 <<
" step " << istep[lev] <<
"] ";
1163 std::cout <<
"Advanced "
1169 if (lev < finest_level)
1171 for (
int i = 1; i <= nsubsteps[lev + 1]; ++i)
1172 TimeStep(lev + 1, time + (i - 1) * dt[lev + 1], i);
1174 for (
int n = 0; n < cell.number_of_fabs; n++)
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));
1180 for (
int n = 0; n < node.number_of_fabs; n++)
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));
1185 for (
unsigned int n = 0; n < m_basefields_cell.size(); n++)
1187 if (m_basefields_cell[n]->evolving)
1188 m_basefields_cell[n]->AverageDown(lev, refRatio(lev));
1190 for (
unsigned int n = 0; n < m_basefields.size(); n++)
1192 if (m_basefields[n]->evolving)
1193 m_basefields[n]->AverageDown(lev, refRatio(lev));