Castro
Castro copied to clipboard
create ability to initialize 3d simulation from 2d axisymmetric
It would be great to have the ability to take a 2d axisymmetric simulation and use it to initialize a 3d calculation by rotating it about the vertical axis. This can be a nice way to start a simulation in 2d and once it evolves enough, transfer it to 3d.
the Maestro to Castro code uses a plotfile to initialize, but I am not sure if we can leverage this if the plotfile is 2d but our simulation is 3d.
Weiqun made changes to AMReX that should allow this. His example:
#include <AMReX.H>
#include <AMReX_Print.H>
#include <AMReX_VisMF.H>
#include <AMReX_MultiFab.H>
using namespace amrex;
int main(int argc, char* argv[])
{
amrex::Initialize(argc,argv);
{
std::string file_name{"Dust-2d-P_plt00020"};
// read header
std::string header_file_name = file_name+"/Header";
Vector<char> filechar;
ParallelDescriptor::ReadAndBcastFile(header_file_name, filechar);
std::string header_file_string{filechar.data()};
std::istringstream is(header_file_string, std::istringstream::in);
std::string line;
std::getline(is, line);
amrex::Print() << "Plotfile Type: " << line << "\n";
int nvars;
is >> nvars;
amrex::Print() << "# of variables: " << nvars << "\n";
Vector<std::string> var_names(nvars);
for (auto& vn : var_names) {
is >> vn;
amrex::Print() << " " << vn << "\n";
}
int plotfile_spacedim;
is >> plotfile_spacedim;
amrex::Print() << "Space Dimension: " << plotfile_spacedim << "\n";
Real t;
is >> t;
amrex::Print() << "Time: " << t << "\n";
int flev;
is >> flev;
amrex::Print() << "Finest Level: " << flev << "\n";
Vector<Real> problo(plotfile_spacedim);
amrex::Print() << " Problo:";
for (int i = 0; i < plotfile_spacedim; ++i) {
is >> problo[i];
amrex::Print() << " " << problo[i];
}
amrex::Print() << "\n";
Vector<Real> probhi(plotfile_spacedim);
amrex::Print() << " Probhi:";
for (int i = 0; i < plotfile_spacedim; ++i) {
is >> probhi[i];
amrex::Print() << " " << probhi[i];
}
amrex::Print() << "\n";
Vector<int> ref_ratio(flev);
if (flev > 0) {
amrex::Print() << "Refinement Ratio:";
for (int lev = 0; lev < flev; ++lev) {
is >> ref_ratio[lev];
amrex::Print() << " " << ref_ratio[lev];
}
amrex::Print() << "\n";
}
Vector<Box> domain(flev+1);
amrex::Print() << "Domain Box:\n";
for (auto& d : domain) {
is >> d;
amrex::Print() << " " << d << "\n";
}
Vector<int> level_steps(flev+1);
amrex::Print() << "Level Steps:\n";
for (auto& ls : level_steps) {
is >> ls;
amrex::Print() << " " << ls << "\n";
}
Vector<Array<Real,AMREX_SPACEDIM> > cell_size(flev+1,{AMREX_D_DECL(1.,1.,1.)});
for (int lev = 0; lev <= flev; ++lev) {
amrex::Print() << "Cell Size on Level " << lev << ":";
for (int i = 0; i < plotfile_spacedim; ++i) {
is >> cell_size[lev][i];
amrex::Print() << " " << cell_size[lev][i];
}
amrex::Print() << "\n";
}
int coord;
is >> coord;
amrex::Print() << "Coordinate Type: " << coord << "\n";
int bndry_data;
is >> bndry_data;
// ... there are more data in Header...
Vector<MultiFab> plotfile_data(flev+1);
for (int lev = 0; lev <= flev; ++lev) {
std::string mf_file_string = file_name + "/Level_"+std::to_string(lev)+"/Cell";
VisMF::Read(plotfile_data[lev], mf_file_string);
amrex::Print() << "Level " << std::to_string(lev) << " Plotfile_data BoxArray: "
<< plotfile_data[lev].boxArray();
const int ncomp = plotfile_data[lev].nComp();
for (int icomp = 0; icomp < ncomp; ++icomp) {
amrex::Print() << " Component " << icomp << " min and max = "
<< plotfile_data[lev].min(icomp) << ", "
<< plotfile_data[lev].max(icomp) << "\n";
}
}
}
amrex::Finalize();
}
if we read in a multilevel 2d plotfile, we need to somehow already have a multilevel 3d MF that matches the gridding, so there is data everywhere we need to map.
Andrew and I were thinking we could do the following:
- Load the 2d data into a 3d MultiFab (and the other information into fake versions of the Amr, AmrLevel, and StateData classes)
- Create a second 3d MultiFab to store the 3d data
- Distribute particles in the MultiFab with the uninitialized 3d data (one to each grid cell)
- Transform the particles into 2d axisymmetric coords, and
redistribute
them in the 2d MultiFab - Sample from the 2d data using the particles (using them like tracer particles)
- Transform back into 3d Cartesian, and
redistribute
them again in the 3d MultiFab - Initialize each cell with the data sampled by its particle