40 #ifndef INTEGRATOR_INTEGRATOR_H
41 #define INTEGRATOR_INTEGRATOR_H
53 #include <AMReX_ParallelDescriptor.H>
54 #include <AMReX_ParmParse.H>
55 #include <AMReX_MultiFabUtil.H>
56 #include <AMReX_FillPatchUtil.H>
57 #include <AMReX_BC_TYPES.H>
58 #include <AMReX_AmrCore.H>
59 #include <AMReX_FluxRegister.H>
60 #include <AMReX_Utility.H>
61 #include <AMReX_PlotFileUtil.H>
74 :
public amrex::AmrCore
102 void Restart(std::string restartfile,
bool a_node =
false);
108 void SetFilename(std::string _plot_file) { plot_file = _plot_file; };
113 if (!explicitmesh.on)
114 AmrCore::regrid(lbase, time, initial);
119 if (!explicitmesh.on) AmrCore::InitFromScratch(time);
125 const amrex::BoxArray& ba = MakeBaseGrids();
126 amrex::DistributionMapping dm(ba);
127 const auto old_num_setdm = num_setdm;
128 const auto old_num_setba = num_setba;
129 MakeNewLevelFromScratch(0, time, ba, dm);
130 if (old_num_setba == num_setba) SetBoxArray(0, ba);
131 if (old_num_setdm == num_setdm) SetDistributionMap(0, dm);
134 for (
int ilev = 0; ilev < maxLevel(); ++ilev)
136 finest_level = ilev + 1;
137 amrex::BoxArray grids(explicitmesh.box[ilev]);
138 ChopGrids(ilev + 1, grids, amrex::ParallelDescriptor::NProcs());
139 amrex::DistributionMapping dmap(grids);
140 SetBoxArray(ilev + 1, grids);
141 SetDistributionMap(ilev + 1, dmap);
142 MakeNewLevelFromScratch(ilev + 1, time, grids, dmap);
166 virtual void Advance(
int lev,
178 virtual void TagCellsForRefinement(
int lev, amrex::TagBoxArray& tags, amrex::Real time,
214 const amrex::MFIter&,
const amrex::Box&)
216 if (thermo.number > 0)
217 Util::Warning(
INFO,
"integrated variables registered, but no integration implemented!");
229 void RegisterNewFab(
Set::Field<Set::Scalar>& new_fab,
int ncomp, std::string name,
bool writeout,std::vector<std::string> suffix = {});
230 void RegisterNodalFab(
Set::Field<Set::Scalar>& new_fab,
int ncomp,
int nghost, std::string name,
bool writeout,std::vector<std::string> suffix = {});
233 void RegisterGeneralFab(
Set::Field<T>& new_fab,
int ncomp,
int nghost,
bool evolving =
true);
235 void RegisterGeneralFab(
Set::Field<T>& new_fab,
int ncomp,
int nghost, std::string a_name,
bool evolving =
true);
237 void RegisterGeneralFab(
Set::Field<T>& new_fab,
int ncomp,
int nghost,
bool writeout, std::string a_name,
bool evolving =
true);
239 template<
class T,
int d>
241 std::string,
bool writeout,
bool evolving, std::vector<std::string> suffix = {});
245 for (
unsigned int i = 0; i < cell.fab_array.size(); i++)
246 cell.fab_array[i]->finest_level = a_finestlevel;
247 for (
unsigned int i = 0; i < node.fab_array.size(); i++)
248 node.fab_array[i]->finest_level = a_finestlevel;
249 for (
unsigned int i = 0; i < m_basefields_cell.size(); i++)
250 m_basefields_cell[i]->SetFinestLevel(finest_level);
251 for (
unsigned int i = 0; i < m_basefields.size(); i++)
252 m_basefields[i]->SetFinestLevel(finest_level);
255 void RegisterIntegratedVariable(
Set::Scalar* integrated_variable, std::string name,
bool extensive=
true);
258 void SetPlotInt(
int plot_int);
259 void SetThermoInt(
int a_thermo_int) { thermo.interval = a_thermo_int; }
280 if (!dynamictimestep.on)
return;
281 if (!dynamictimestep.dt_limit_min.size())
283 dynamictimestep.dt_limit_min.resize(max_level+1,
284 std::numeric_limits<Set::Scalar>::max());
286 dynamictimestep.dt_limit_min[lev] = std::min(dt_min,
287 dynamictimestep.dt_limit_min[lev]);
289 amrex::ParallelDescriptor::ReduceRealMin(dynamictimestep.dt_limit_min[lev]);
293 if (!dynamictimestep.on)
return;
294 dynamictimestep.previous_timesteps.clear();
298 if (!dynamictimestep.on)
return;
299 if (!dynamictimestep.dt_limit_min.size())
return;
303 if (amrex::ParallelDescriptor::IOProcessor())
306 if (dynamictimestep.previous_timesteps.size() > 0)
308 timestep_average = 0.0;
309 for (
unsigned int d = 0; d < dynamictimestep.previous_timesteps.size(); d++)
310 timestep_average += dynamictimestep.previous_timesteps[d];
311 timestep_average /= dynamictimestep.previous_timesteps.size();
314 Set::Scalar new_timestep = std::numeric_limits<Set::Scalar>::max();
315 for (
int lev = 0; lev <= this->max_level; lev++)
318 Set::Scalar dt_lev = dynamictimestep.dt_limit_min[lev];
322 for (
int ilev = lev; ilev > 0; ilev--) dt_lev *= (
Set::Scalar)(this->nsubsteps[ilev]);
326 new_timestep = std::min(new_timestep,dt_lev);
329 if (new_timestep < timestep_average)
331 dynamictimestep.previous_timesteps.clear();
333 final_timestep = new_timestep;
334 final_timestep = std::max(final_timestep,dynamictimestep.min);
335 final_timestep = std::min(final_timestep,dynamictimestep.max);
337 dynamictimestep.previous_timesteps.push_back(new_timestep);
341 final_timestep = timestep_average;
342 final_timestep = std::max(final_timestep,dynamictimestep.min);
343 final_timestep = std::min(final_timestep,dynamictimestep.max);
345 if ((
int)(dynamictimestep.previous_timesteps.size()) > dynamictimestep.nprevious)
346 dynamictimestep.previous_timesteps.erase(dynamictimestep.previous_timesteps.begin());
347 dynamictimestep.previous_timesteps.push_back(new_timestep);
351 amrex::ParallelDescriptor::Bcast(&final_timestep,1);
352 this->SetTimestep(final_timestep);
353 dynamictimestep.dt_limit_min.clear();
361 std::string plot_file{
"plt" };
364 virtual void MakeNewLevelFromScratch(
int lev, amrex::Real time,
const amrex::BoxArray& ba,
365 const amrex::DistributionMapping& dm)
override;
366 virtual void MakeNewLevelFromCoarse(
int lev, amrex::Real time,
const amrex::BoxArray& ba,
367 const amrex::DistributionMapping& dm)
override;
368 virtual void RemakeLevel(
int lev, amrex::Real time,
const amrex::BoxArray& ba,
369 const amrex::DistributionMapping& dm)
override;
370 virtual void ClearLevel(
int lev)
override;
371 virtual void ErrorEst(
int lev, amrex::TagBoxArray& tags, amrex::Real time,
int ngrow)
override;
374 void FillPatch(
int lev, amrex::Real time,
376 amrex::MultiFab& destination_multifab,
379 long CountCells(
int lev);
380 void TimeStep(
int lev, amrex::Real time,
int iteration);
382 void GetData(
const int lev,
const amrex::Real time, amrex::Vector<amrex::MultiFab*>& data, amrex::Vector<amrex::Real>& datatime);
384 std::vector<std::string> PlotFileName(
int lev, std::string prefix =
"")
const;
386 void IntegrateVariables(
Set::Scalar cur_time,
int step);
387 void WritePlotFile(
bool initial =
false)
const;
388 void WritePlotFile(std::string prefix,
Set::Scalar time,
int step)
const;
389 void WritePlotFile(
Set::Scalar time, amrex::Vector<int> iter,
bool initial =
false, std::string prefix =
"")
const;
397 amrex::Real timestep = NAN;
398 amrex::Vector<amrex::Real>
dt;
401 int max_plot_level = -1;
404 int max_step = std::numeric_limits<int>::max();
405 amrex::Real tstart = 0;
406 amrex::Real stop_time = NAN;
409 bool integrate_variables_before_advance =
true;
410 bool integrate_variables_after_advance =
false;
414 int number_of_fabs = 0;
426 int number_of_fabs = 0;
427 std::vector<Set::Field<Set::Scalar>*> fab_array;
428 std::vector<int> ncomp_array;
429 std::vector<int> nghost_array;
430 std::vector<std::vector<std::string>> name_array;
431 std::vector<BC::BC<Set::Scalar>*> physbc_array;
432 std::vector<bool> writeout_array;
449 std::vector<Set::Scalar*>
vars;
456 int base_regrid_int = -1;
458 std::string restart_file_cell =
"";
459 std::string restart_file_node =
"";
463 std::vector<amrex::Box>
box;
470 int abort_on_nan =
true;
476 void Integrator::AddField<Set::Scalar, Set::Hypercube::Cell>
484 std::vector<std::string> suffix)
486 int nlevs_max = maxLevel() + 1;
487 new_field.resize(nlevs_max);
488 cell.fab_array.push_back(&new_field);
489 if (new_bc !=
nullptr) cell.physbc_array.push_back(new_bc);
490 else cell.physbc_array.push_back(&bcnothing);
491 cell.ncomp_array.push_back(ncomp);
492 cell.nghost_array.push_back(nghost);
494 cell.writeout_array.push_back(writeout);
495 cell.number_of_fabs++;
498 std::vector<std::string> names;
500 names.push_back(name);
503 if (suffix.size() == 0)
504 for (
int j = 0; j < ncomp; j++)
505 names.push_back(amrex::Concatenate(name,j+1,3));
507 for (
int j = 0; j < ncomp; j++)
508 names.push_back(name + suffix[j]);
510 cell.name_array.push_back(names);
515 void Integrator::AddField<Set::Scalar, Set::Hypercube::Node>
523 std::vector<std::string> suffix)
525 BL_PROFILE(
"Integrator::RegisterNodalFab");
527 int nlevs_max = maxLevel() + 1;
528 new_field.resize(nlevs_max);
529 node.fab_array.push_back(&new_field);
530 node.physbc_array.push_back(&bcnothing);
531 node.ncomp_array.push_back(ncomp);
532 node.nghost_array.push_back(nghost);
534 node.writeout_array.push_back(writeout);
535 node.number_of_fabs++;
538 std::vector<std::string> names;
540 names.push_back(name);
543 if (suffix.size() == 0)
544 for (
int j = 0; j < ncomp; j++)
545 names.push_back(amrex::Concatenate(name,j+1,3));
547 for (
int j = 0; j < ncomp; j++)
548 names.push_back(name + suffix[j]);
550 node.name_array.push_back(names);
553 template<
class T,
int d>
555 void Integrator::AddField
557 int nghost, std::string name,
bool writeout,
bool evolving,
558 std::vector<std::string> )
563 int nlevs_max = maxLevel() + 1;
564 new_field.resize(nlevs_max);
565 m_basefields.push_back(
new Field<T>(new_field, geom, refRatio(), ncomp, nghost));
566 m_basefields.back()->evolving = evolving;
567 m_basefields.back()->writeout = writeout;
568 m_basefields.back()->setName(name);
569 m_basefields.back()->evolving = evolving;
574 int nlevs_max = maxLevel() + 1;
575 new_field.resize(nlevs_max);
576 m_basefields_cell.push_back(
new Field<T>(new_field, geom, refRatio(), ncomp, nghost));
577 m_basefields_cell.back()->evolving = evolving;
578 m_basefields_cell.back()->writeout = writeout;
579 m_basefields_cell.back()->setName(name);
580 m_basefields_cell.back()->evolving = evolving;
581 if (new_bc) m_basefields_cell.back()->setBC(new_bc);
582 else m_basefields_cell.back()->setBC(&bcnothing);
587 Util::Abort(
INFO,
"Only node and cell based fields can be added at this time");
595 void Integrator::RegisterGeneralFab(
Set::Field<T>& new_fab,
int ncomp,
int nghost,
bool evolving)
598 AddField<T, Set::Hypercube::Node>(new_fab,
nullptr, ncomp, nghost,
"",
true, evolving);
602 void Integrator::RegisterGeneralFab(
Set::Field<T>& new_fab,
int ncomp,
int nghost, std::string a_name,
bool evolving)
605 AddField<T, Set::Hypercube::Node>(new_fab,
nullptr, ncomp, nghost, a_name,
true, evolving);
609 void Integrator::RegisterGeneralFab(
Set::Field<T>& new_fab,
int ncomp,
int nghost,
bool writeout, std::string a_name,
bool evolving)
612 AddField<T, Set::Hypercube::Node>(new_fab,
nullptr, ncomp, nghost, a_name, writeout, evolving);