void main_main () { // What time is it now? We'll use this to compute total run time. Real strt_time = ParallelDescriptor::second(); // AMREX_SPACEDIM: number of dimensions int n_cell, max_grid_size; Vector<int> bc_lo(AMREX_SPACEDIM,0); Vector<int> bc_hi(AMREX_SPACEDIM,0); // inputs parameters { // ParmParse is way of reading inputs from the inputs file ParmParse pp; // We need to get n_cell from the inputs file - this is the // number of cells on each side of a square (or cubic) domain. pp.get("n_cell", n_cell); // The domain is broken into boxes of size max_grid_size max_grid_size = 32; pp.query("max_grid_size", max_grid_size); } Vector<int> is_periodic(AMREX_SPACEDIM,0); for (int idim=0; idim < AMREX_SPACEDIM; ++idim) { is_periodic[idim] = 1; } // make BoxArray and Geometry BoxArray ba; Geometry geom; { IntVect dom_lo(AMREX_D_DECL( 0, 0, 0)); IntVect dom_hi(AMREX_D_DECL(n_cell-1, n_cell-1, n_cell-1)); Box domain(dom_lo, dom_hi); // Initialize the boxarray "ba" from the single box "bx" ba.define(domain); // Break up boxarray "ba" into chunks no larger than // "max_grid_size" along a direction ba.maxSize(max_grid_size); // This defines the physical box, [0, 1] in each direction. RealBox real_box({AMREX_D_DECL(0.0, 0.0, 0.0)}, {AMREX_D_DECL(1.0, 1.0, 1.0)}); // This defines a Geometry object geom.define(domain, &real_box, CoordSys::cartesian, is_periodic.data()); } // Nghost = number of ghost cells for each array int Nghost = 0; // do the runtime parameter initializations and microphysics inits if (ParallelDescriptor::IOProcessor()) { std::cout << "reading extern runtime parameters ..." << std::endl; } ParmParse ppa("amr"); std::string probin_file = "probin"; ppa.query("probin_file", probin_file); const int probin_file_length = probin_file.length(); Vector<int> probin_file_name(probin_file_length); for (int i = 0; i < probin_file_length; i++) probin_file_name[i] = probin_file[i]; init_unit_test(probin_file_name.dataPtr(), &probin_file_length); // Ncomp = number of components for each array int Ncomp = -1; init_variables(); get_ncomp(&Ncomp); int name_len = -1; get_name_len(&name_len); // get the variable names Vector<std::string> varnames; for (int i=0; i<Ncomp; i++) { char* cstring[name_len+1]; get_var_name(cstring, &i); std::string name(*cstring); varnames.push_back(name); } // time = starting time in the simulation Real time = 0.0; // How Boxes are distrubuted among MPI processes DistributionMapping dm(ba); // we allocate our main multifabs MultiFab state(ba, dm, Ncomp, Nghost); // Initialize the state and compute the different thermodynamics // by inverting the EOS for ( MFIter mfi(state); mfi.isValid(); ++mfi ) { const Box& bx = mfi.validbox(); #pragma gpu do_eos(AMREX_INT_ANYD(bx.loVect()), AMREX_INT_ANYD(bx.hiVect()), BL_TO_FORTRAN_ANYD(state[mfi]), n_cell); } std::string name = "test_eos."; // get the name of the EOS int eos_len = -1; get_eos_len(&eos_len); char* eos_string[eos_len+1]; get_eos_name(eos_string); std::string eos(*eos_string); // Write a plotfile WriteSingleLevelPlotfile(name + eos, state, varnames, geom, time, 0); // Call the timer again and compute the maximum difference between // the start time and stop time over all processors Real stop_time = ParallelDescriptor::second() - strt_time; const int IOProc = ParallelDescriptor::IOProcessorNumber(); ParallelDescriptor::ReduceRealMax(stop_time, IOProc); // Tell the I/O Processor to write out the "run time" amrex::Print() << "Run time = " << stop_time << std::endl; }
void main_main () { // What time is it now? We'll use this to compute total run time. Real strt_time = ParallelDescriptor::second(); std::cout << std::setprecision(15); int n_cell, max_grid_size, nsteps, plot_int, is_periodic[BL_SPACEDIM]; // Boundary conditions Array<int> lo_bc(BL_SPACEDIM), hi_bc(BL_SPACEDIM); // inputs parameters { // ParmParse is way of reading inputs from the inputs file ParmParse pp; // We need to get n_cell from the inputs file - this is the number of cells on each side of // a square (or cubic) domain. pp.get("n_cell",n_cell); // Default nsteps to 0, allow us to set it to something else in the inputs file pp.get("max_grid_size",max_grid_size); // Default plot_int to 1, allow us to set it to something else in the inputs file // If plot_int < 0 then no plot files will be written plot_int = 1; pp.query("plot_int",plot_int); // Default nsteps to 0, allow us to set it to something else in the inputs file nsteps = 0; pp.query("nsteps",nsteps); // Boundary conditions - default is periodic (INT_DIR) for (int i = 0; i < BL_SPACEDIM; ++i) { lo_bc[i] = hi_bc[i] = INT_DIR; // periodic boundaries are interior boundaries } pp.queryarr("lo_bc",lo_bc,0,BL_SPACEDIM); pp.queryarr("hi_bc",hi_bc,0,BL_SPACEDIM); } // make BoxArray and Geometry BoxArray ba; Geometry geom; { IntVect dom_lo(IntVect(D_DECL(0,0,0))); IntVect dom_hi(IntVect(D_DECL(n_cell-1, n_cell-1, n_cell-1))); Box domain(dom_lo, dom_hi); // Initialize the boxarray "ba" from the single box "bx" ba.define(domain); // Break up boxarray "ba" into chunks no larger than "max_grid_size" along a direction ba.maxSize(max_grid_size); // This defines the physical size of the box. Right now the box is [-1,1] in each direction. RealBox real_box; for (int n = 0; n < BL_SPACEDIM; n++) { real_box.setLo(n,-1.0); real_box.setHi(n, 1.0); } // This says we are using Cartesian coordinates int coord = 0; // This sets the boundary conditions to be doubly or triply periodic int is_periodic[BL_SPACEDIM]; for (int i = 0; i < BL_SPACEDIM; i++) { is_periodic[i] = 0; if (lo_bc[i] == 0 && hi_bc[i] == 0) { is_periodic[i] = 1; } } // This defines a Geometry object geom.define(domain,&real_box,coord,is_periodic); } // Boundary conditions PhysBCFunct physbcf; BCRec bcr(&lo_bc[0], &hi_bc[0]); physbcf.define(geom, bcr, BndryFunctBase(phifill)); // phifill is a fortran function // define dx[] const Real* dx = geom.CellSize(); // Nghost = number of ghost cells for each array int Nghost = 1; // Ncomp = number of components for each array int Ncomp = 1; // time = starting time in the simulation Real time = 0.0; // we allocate two phi multifabs; one will store the old state, the other the new // we swap the indices each time step to avoid copies of new into old PArray<MultiFab> phi(2, PArrayManage); phi.set(0, new MultiFab(ba, Ncomp, Nghost)); phi.set(1, new MultiFab(ba, Ncomp, Nghost)); // Initialize both to zero (just because) phi[0].setVal(0.0); phi[1].setVal(0.0); // Initialize phi[init_index] by calling a Fortran routine. // MFIter = MultiFab Iterator int init_index = 0; for ( MFIter mfi(phi[init_index]); mfi.isValid(); ++mfi ) { const Box& bx = mfi.validbox(); init_phi(phi[init_index][mfi].dataPtr(), bx.loVect(), bx.hiVect(), &Nghost, geom.CellSize(), geom.ProbLo(), geom.ProbHi()); } // compute the time step Real dt = 0.9*dx[0]*dx[0] / (2.0*BL_SPACEDIM); // Write a plotfile of the initial data if plot_int > 0 (plot_int was defined in the inputs file) if (plot_int > 0) { int n = 0; const std::string& pltfile = BoxLib::Concatenate("plt",n,5); writePlotFile(pltfile, phi[init_index], geom, time); } // build the flux multifabs PArray<MultiFab> flux(BL_SPACEDIM, PArrayManage); for (int dir = 0; dir < BL_SPACEDIM; dir++) { // flux(dir) has one component, zero ghost cells, and is nodal in direction dir BoxArray edge_ba = ba; edge_ba.surroundingNodes(dir); flux.set(dir, new MultiFab(edge_ba, 1, 0)); } int old_index = init_index; for (int n = 1; n <= nsteps; n++, old_index = 1 - old_index) { int new_index = 1 - old_index; // new_phi = old_phi + dt * (something) advance(phi[old_index], phi[new_index], flux, time, dt, geom, physbcf, bcr); time = time + dt; // Tell the I/O Processor to write out which step we're doing if (ParallelDescriptor::IOProcessor()) std::cout << "Advanced step " << n << std::endl; // Write a plotfile of the current data (plot_int was defined in the inputs file) if (plot_int > 0 && n%plot_int == 0) { const std::string& pltfile = BoxLib::Concatenate("plt",n,5); writePlotFile(pltfile, phi[new_index], geom, time); } } // Call the timer again and compute the maximum difference between the start time and stop time // over all processors Real stop_time = ParallelDescriptor::second() - strt_time; const int IOProc = ParallelDescriptor::IOProcessorNumber(); ParallelDescriptor::ReduceRealMax(stop_time,IOProc); // Tell the I/O Processor to write out the "run time" if (ParallelDescriptor::IOProcessor()) { std::cout << "Run time = " << stop_time << std::endl; } }