diff options
Diffstat (limited to 'Source/Diagnostics/WarpXIO.cpp')
-rw-r--r-- | Source/Diagnostics/WarpXIO.cpp | 1062 |
1 files changed, 148 insertions, 914 deletions
diff --git a/Source/Diagnostics/WarpXIO.cpp b/Source/Diagnostics/WarpXIO.cpp index d43d74968..ccbdd280c 100644 --- a/Source/Diagnostics/WarpXIO.cpp +++ b/Source/Diagnostics/WarpXIO.cpp @@ -1,9 +1,9 @@ - #include <AMReX_MultiFabUtil.H> #include <AMReX_PlotFileUtil.H> #include <AMReX_FillPatchUtil_F.H> #include <WarpX.H> +#include <FieldIO.H> #include "AMReX_buildInfo.H" @@ -11,6 +11,11 @@ #include <AMReX_AmrMeshInSituBridge.H> #endif +#ifdef AMREX_USE_ASCENT +#include <ascent.hpp> +#include <AMReX_Conduit_Blueprint.H> +#endif + using namespace amrex; namespace @@ -175,12 +180,11 @@ WarpX::WriteCheckPointFile() const } } - mypc->Checkpoint(checkpointname, true); + mypc->Checkpoint(checkpointname); VisMF::SetHeaderVersion(current_version); } - void WarpX::InitFromCheckpoint () { @@ -366,7 +370,7 @@ WarpX::InitFromCheckpoint () } if (costs[lev]) { - const auto& cost_mf_name = + const auto& cost_mf_name = amrex::MultiFabFileFullPrefix(lev, restart_chkfile, level_prefix, "costs"); if (VisMF::Exist(cost_mf_name)) { VisMF::Read(*costs[lev], cost_mf_name); @@ -408,335 +412,52 @@ WarpX::GetCellCenteredData() { const int nc = 10; Vector<std::unique_ptr<MultiFab> > cc(finest_level+1); - + for (int lev = 0; lev <= finest_level; ++lev) { cc[lev].reset( new MultiFab(grids[lev], dmap[lev], nc, ng) ); - - Vector<const MultiFab*> srcmf(AMREX_SPACEDIM); + int dcomp = 0; - // first the electric field - PackPlotDataPtrs(srcmf, Efield_aux[lev]); - amrex::average_edge_to_cellcenter(*cc[lev], dcomp, srcmf); -#if (AMREX_SPACEDIM == 2) - MultiFab::Copy(*cc[lev], *cc[lev], dcomp+1, dcomp+2, 1, ng); - amrex::average_node_to_cellcenter(*cc[lev], dcomp+1, *Efield_aux[lev][1], 0, 1); -#endif + AverageAndPackVectorField( *cc[lev], Efield_aux[lev], dcomp, ng ); dcomp += 3; - // then the magnetic field - PackPlotDataPtrs(srcmf, Bfield_aux[lev]); - amrex::average_face_to_cellcenter(*cc[lev], dcomp, srcmf); -#if (AMREX_SPACEDIM == 2) - MultiFab::Copy(*cc[lev], *cc[lev], dcomp+1, dcomp+2, 1, ng); - MultiFab::Copy(*cc[lev], *Bfield_aux[lev][1], 0, dcomp+1, 1, ng); -#endif + AverageAndPackVectorField( *cc[lev], Efield_aux[lev], dcomp, ng ); dcomp += 3; - // then the current density - PackPlotDataPtrs(srcmf, current_fp[lev]); - amrex::average_edge_to_cellcenter(*cc[lev], dcomp, srcmf); -#if (AMREX_SPACEDIM == 2) - MultiFab::Copy(*cc[lev], *cc[lev], dcomp+1, dcomp+2, 1, ng); - amrex::average_node_to_cellcenter(*cc[lev], dcomp+1, *current_fp[lev][1], 0, 1); -#endif + AverageAndPackVectorField( *cc[lev], current_fp[lev], dcomp, ng ); dcomp += 3; - const std::unique_ptr<MultiFab>& charge_density = mypc->GetChargeDensity(lev); - amrex::average_node_to_cellcenter(*cc[lev], dcomp, *charge_density, 0, 1); - + AverageAndPackScalarField( *cc[lev], *charge_density, dcomp, ng ); + cc[lev]->FillBoundary(geom[lev].periodicity()); } - + for (int lev = finest_level; lev > 0; --lev) { amrex::average_down(*cc[lev], *cc[lev-1], 0, nc, refRatio(lev-1)); } - + return std::move(cc[0]); } void WarpX::UpdateInSitu () const { -#ifdef BL_USE_SENSEI_INSITU +#if defined(BL_USE_SENSEI_INSITU) || defined(AMREX_USE_ASCENT) BL_PROFILE("WarpX::UpdateInSitu()"); - int numLevels = finest_level + 1; - Vector<std::string> varnames; - Vector<MultiFab> mf; - - const int ncomp = 3*3 - + static_cast<int>(plot_part_per_cell) - + static_cast<int>(plot_part_per_grid) - + static_cast<int>(plot_part_per_proc) - + static_cast<int>(plot_proc_number) - + static_cast<int>(plot_divb) - + static_cast<int>(plot_dive) - + static_cast<int>(plot_rho) - + static_cast<int>(plot_F) - + static_cast<int>(plot_finepatch)*6 - + static_cast<int>(plot_crsepatch)*6 - + static_cast<int>(costs[0] != nullptr); - - for (int lev = 0; lev <= finest_level; ++lev) - { - const int ngrow = 1; - mf.push_back(MultiFab(grids[lev], dmap[lev], ncomp, ngrow)); - - Vector<const MultiFab*> srcmf(AMREX_SPACEDIM); - PackPlotDataPtrs(srcmf, current_fp[lev]); - int dcomp = 0; - amrex::average_edge_to_cellcenter(mf[lev], dcomp, srcmf, ngrow); - -#if (AMREX_SPACEDIM == 2) - MultiFab::Copy(mf[lev], mf[lev], dcomp+1, dcomp+2, 1, ngrow); - amrex::average_node_to_cellcenter(mf[lev], dcomp+1, *current_fp[lev][1], 0, 1, ngrow); -#endif - if (lev == 0) - { - varnames.push_back("jx"); - varnames.push_back("jy"); - varnames.push_back("jz"); - } - dcomp += 3; - - PackPlotDataPtrs(srcmf, Efield_aux[lev]); - amrex::average_edge_to_cellcenter(mf[lev], dcomp, srcmf, ngrow); -#if (AMREX_SPACEDIM == 2) - MultiFab::Copy(mf[lev], mf[lev], dcomp+1, dcomp+2, 1, ngrow); - amrex::average_node_to_cellcenter(mf[lev], dcomp+1, *Efield_aux[lev][1], 0, 1, ngrow); -#endif - if (lev == 0) - { - varnames.push_back("Ex"); - varnames.push_back("Ey"); - varnames.push_back("Ez"); - } - dcomp += 3; - - PackPlotDataPtrs(srcmf, Bfield_aux[lev]); - amrex::average_face_to_cellcenter(mf[lev], dcomp, srcmf, ngrow); -#if (AMREX_SPACEDIM == 2) - MultiFab::Copy(mf[lev], mf[lev], dcomp+1, dcomp+2, 1, ngrow); - MultiFab::Copy(mf[lev], *Bfield_aux[lev][1], 0, dcomp+1, 1, ngrow); -#endif - if (lev == 0) - { - varnames.push_back("Bx"); - varnames.push_back("By"); - varnames.push_back("Bz"); - } - dcomp += 3; - - if (plot_part_per_cell) - { - MultiFab temp_dat(grids[lev], mf[lev].DistributionMap(), 1, ngrow); - temp_dat.setVal(0, ngrow); - - // MultiFab containing number of particles in each cell - mypc->Increment(temp_dat, lev); - MultiFab::Copy(mf[lev], temp_dat, 0, dcomp, 1, ngrow); - if (lev == 0) - varnames.push_back("part_per_cell"); - dcomp += 1; - } - - if (plot_part_per_grid || plot_part_per_proc) - { - const Vector<long>& npart_in_grid = mypc->NumberOfParticlesInGrid(lev); - - if (plot_part_per_grid) - { -#ifdef _OPENMP -#pragma omp parallel -#endif - for (MFIter mfi(mf[lev]); mfi.isValid(); ++mfi) - (mf[lev])[mfi].setVal(static_cast<Real>(npart_in_grid[mfi.index()]), dcomp); - - if (lev == 0) - varnames.push_back("part_per_grid"); - - dcomp += 1; - } - - if (plot_part_per_proc) - { - long n_per_proc = 0; -#ifdef _OPENMP -#pragma omp parallel reduction(+:n_per_proc) -#endif - for (MFIter mfi(mf[lev]); mfi.isValid(); ++mfi) - n_per_proc += npart_in_grid[mfi.index()]; - - mf[lev].setVal(static_cast<Real>(n_per_proc), dcomp, ngrow); - - if (lev == 0) - varnames.push_back("part_per_proc"); - - dcomp += 1; - } - } - - if (plot_proc_number) - { - Real procid = static_cast<Real>(ParallelDescriptor::MyProc()); -#ifdef _OPENMP -#pragma omp parallel -#endif - for (MFIter mfi(mf[lev]); mfi.isValid(); ++mfi) - (mf[lev])[mfi].setVal(procid, dcomp); - - if (lev == 0) - varnames.push_back("proc_number"); - - dcomp += 1; - } - - if (plot_divb) - { - ComputeDivB(mf[lev], dcomp, - {Bfield_aux[lev][0].get(),Bfield_aux[lev][1].get(),Bfield_aux[lev][2].get()}, - WarpX::CellSize(lev), ngrow); - if (lev == 0) - varnames.push_back("divB"); - - dcomp += 1; - } - - if (plot_dive) - { - const BoxArray& ba = amrex::convert(boxArray(lev),IntVect::TheUnitVector()); - MultiFab dive(ba, DistributionMap(lev), 1, ngrow); - - ComputeDivE(dive, 0, - {Efield_aux[lev][0].get(), Efield_aux[lev][1].get(), Efield_aux[lev][2].get()}, - WarpX::CellSize(lev), ngrow); - - amrex::average_node_to_cellcenter(mf[lev], dcomp, dive, 0, 1, ngrow); - - if (lev == 0) - varnames.push_back("divE"); - - dcomp += 1; - } - - if (plot_rho) - { - amrex::average_node_to_cellcenter(mf[lev], dcomp, *rho_fp[lev], 0, 1, ngrow); - if (lev == 0) - varnames.push_back("rho"); - - dcomp += 1; - } - - if (plot_F) - { - amrex::average_node_to_cellcenter(mf[lev], dcomp, *F_fp[lev], 0, 1, ngrow); - - if (lev == 0) - varnames.push_back("F"); - - dcomp += 1; - } - - if (plot_finepatch) - { - PackPlotDataPtrs(srcmf, Efield_fp[lev]); - amrex::average_edge_to_cellcenter(mf[lev], dcomp, srcmf, ngrow); -#if (AMREX_SPACEDIM == 2) - MultiFab::Copy(mf[lev], mf[lev], dcomp+1, dcomp+2, 1, ngrow); - amrex::average_node_to_cellcenter(mf[lev], dcomp+1, *Efield_fp[lev][1], 0, 1, ngrow); -#endif - if (lev == 0) - { - varnames.push_back("Ex_fp"); - varnames.push_back("Ey_fp"); - varnames.push_back("Ez_fp"); - } - dcomp += 3; - - PackPlotDataPtrs(srcmf, Bfield_fp[lev]); - amrex::average_face_to_cellcenter(mf[lev], dcomp, srcmf, ngrow); -#if (AMREX_SPACEDIM == 2) - MultiFab::Copy(mf[lev], mf[lev], dcomp+1, dcomp+2, 1, ngrow); - MultiFab::Copy(mf[lev], *Bfield_fp[lev][1], 0, dcomp+1, 1, ngrow); -#endif - if (lev == 0) - { - varnames.push_back("Bx_fp"); - varnames.push_back("By_fp"); - varnames.push_back("Bz_fp"); - } - dcomp += 3; - } - - if (plot_crsepatch) - { - // First the electric field - if (lev == 0) - { - mf[lev].setVal(0.0, dcomp, 3, ngrow); - } - else - { - std::array<std::unique_ptr<MultiFab>, 3> E = getInterpolatedE(lev); - PackPlotDataPtrs(srcmf, E); - amrex::average_edge_to_cellcenter(mf[lev], dcomp, srcmf, ngrow); -#if (AMREX_SPACEDIM == 2) - MultiFab::Copy(mf[lev], mf[lev], dcomp+1, dcomp+2, 1, ngrow); - amrex::average_node_to_cellcenter(mf[lev], dcomp+1, *E[1], 0, 1, ngrow); -#endif - } - if (lev == 0) - { - varnames.push_back("Ex_cp"); - varnames.push_back("Ey_cp"); - varnames.push_back("Ez_cp"); - } - dcomp += 3; - - // now the magnetic field - if (lev == 0) - { - mf[lev].setVal(0.0, dcomp, 3, ngrow); - } - else - { - std::array<std::unique_ptr<MultiFab>, 3> B = getInterpolatedB(lev); - PackPlotDataPtrs(srcmf, B); - amrex::average_face_to_cellcenter(mf[lev], dcomp, srcmf, ngrow); -#if (AMREX_SPACEDIM == 2) - MultiFab::Copy(mf[lev], mf[lev], dcomp+1, dcomp+2, 1, ngrow); - MultiFab::Copy(mf[lev], *B[1], 0, dcomp+1, 1, ngrow); -#endif - } - if (lev == 0) - { - varnames.push_back("Bx_cp"); - varnames.push_back("By_cp"); - varnames.push_back("Bz_cp"); - } - dcomp += 3; - } - - if (costs[0] != nullptr) - { - MultiFab::Copy(mf[lev], *costs[lev], 0, dcomp, 1, ngrow); - if (lev == 0) - { - varnames.push_back("costs"); - } - dcomp += 1; - } - - BL_ASSERT(dcomp == ncomp); - } + // Average the fields from the simulation to the cell centers + const int ngrow = 1; + Vector<std::string> varnames; // Name of the written fields + // mf_avg will contain the averaged, cell-centered fields + Vector<MultiFab> mf_avg; + WarpX::AverageAndPackFields( varnames, mf_avg, ngrow ); +#ifdef BL_USE_SENSEI_INSITU if (insitu_bridge->update(istep[0], t_new[0], dynamic_cast<amrex::AmrMesh*>(const_cast<WarpX*>(this)), - {&mf}, {varnames})) + {&mf_avg}, {varnames})) { amrex::ErrorStream() << "WarpXIO::UpdateInSitu : Failed to update the in situ bridge." @@ -745,6 +466,30 @@ WarpX::UpdateInSitu () const amrex::Abort(); } #endif + +#ifdef AMREX_USE_ASCENT + conduit::Node bp_mesh; + MultiLevelToBlueprint(finest_level+1, + amrex::GetVecOfConstPtrs(mf_avg), + varnames, + Geom(), + t_new[0], + istep, + refRatio(), + bp_mesh); + + ascent::Ascent ascent; + conduit::Node opts; + opts["exceptions"] = "catch"; + opts["mpi_comm"] = MPI_Comm_c2f(ParallelDescriptor::Communicator()); + ascent.open(opts); + ascent.publish(bp_mesh); + conduit::Node actions; + ascent.execute(actions); + ascent.close(); +#endif + +#endif } void @@ -752,489 +497,118 @@ WarpX::WritePlotFile () const { BL_PROFILE("WarpX::WritePlotFile()"); - VisMF::Header::Version current_version = VisMF::GetHeaderVersion(); - VisMF::SetHeaderVersion(plotfile_headerversion); - const std::string& plotfilename = amrex::Concatenate(plot_file,istep[0]); - amrex::Print() << " Writing plotfile " << plotfilename << "\n"; - { - Vector<std::string> varnames; - Vector<std::unique_ptr<MultiFab> > mf(finest_level+1); - - const int ncomp = 3*3 - + static_cast<int>(plot_part_per_cell) - + static_cast<int>(plot_part_per_grid) - + static_cast<int>(plot_part_per_proc) - + static_cast<int>(plot_proc_number) - + static_cast<int>(plot_divb) - + static_cast<int>(plot_dive) - + static_cast<int>(plot_rho) - + static_cast<int>(plot_F) - + static_cast<int>(plot_finepatch)*6 - + static_cast<int>(plot_crsepatch)*6 - + static_cast<int>(costs[0] != nullptr); - - for (int lev = 0; lev <= finest_level; ++lev) - { - const int ngrow = 0; - mf[lev].reset(new MultiFab(grids[lev], dmap[lev], ncomp, ngrow)); - - Vector<const MultiFab*> srcmf(AMREX_SPACEDIM); - int dcomp = 0; - - // j - if (do_nodal) - { - amrex::average_node_to_cellcenter(*mf[lev], dcomp , *current_fp[lev][0], 0, 1); - amrex::average_node_to_cellcenter(*mf[lev], dcomp+1, *current_fp[lev][1], 0, 1); - amrex::average_node_to_cellcenter(*mf[lev], dcomp+2, *current_fp[lev][2], 0, 1); - } - else - { - PackPlotDataPtrs(srcmf, current_fp[lev]); - amrex::average_edge_to_cellcenter(*mf[lev], dcomp, srcmf); -#if (AMREX_SPACEDIM == 2) - MultiFab::Copy(*mf[lev], *mf[lev], dcomp+1, dcomp+2, 1, ngrow); - amrex::average_node_to_cellcenter(*mf[lev], dcomp+1, *current_fp[lev][1], 0, 1); -#endif - } - if (lev == 0) - { - varnames.push_back("jx"); - varnames.push_back("jy"); - varnames.push_back("jz"); - } - dcomp += 3; - - // E - if (do_nodal) - { - amrex::average_node_to_cellcenter(*mf[lev], dcomp , *Efield_aux[lev][0], 0, 1); - amrex::average_node_to_cellcenter(*mf[lev], dcomp+1, *Efield_aux[lev][1], 0, 1); - amrex::average_node_to_cellcenter(*mf[lev], dcomp+2, *Efield_aux[lev][2], 0, 1); - } - else - { - PackPlotDataPtrs(srcmf, Efield_aux[lev]); - amrex::average_edge_to_cellcenter(*mf[lev], dcomp, srcmf); -#if (AMREX_SPACEDIM == 2) - MultiFab::Copy(*mf[lev], *mf[lev], dcomp+1, dcomp+2, 1, ngrow); - amrex::average_node_to_cellcenter(*mf[lev], dcomp+1, *Efield_aux[lev][1], 0, 1); -#endif - } - if (lev == 0) - { - varnames.push_back("Ex"); - varnames.push_back("Ey"); - varnames.push_back("Ez"); - } - dcomp += 3; - - // B - if (do_nodal) - { - amrex::average_node_to_cellcenter(*mf[lev], dcomp , *Bfield_aux[lev][0], 0, 1); - amrex::average_node_to_cellcenter(*mf[lev], dcomp+1, *Bfield_aux[lev][1], 0, 1); - amrex::average_node_to_cellcenter(*mf[lev], dcomp+2, *Bfield_aux[lev][2], 0, 1); - } - else - { - PackPlotDataPtrs(srcmf, Bfield_aux[lev]); - amrex::average_face_to_cellcenter(*mf[lev], dcomp, srcmf); -#if (AMREX_SPACEDIM == 2) - MultiFab::Copy(*mf[lev], *mf[lev], dcomp+1, dcomp+2, 1, ngrow); - MultiFab::Copy(*mf[lev], *Bfield_aux[lev][1], 0, dcomp+1, 1, ngrow); -#endif - } - if (lev == 0) - { - varnames.push_back("Bx"); - varnames.push_back("By"); - varnames.push_back("Bz"); - } - dcomp += 3; - - if (plot_part_per_cell) - { - MultiFab temp_dat(grids[lev],mf[lev]->DistributionMap(),1,0); - temp_dat.setVal(0); - - // MultiFab containing number of particles in each cell - mypc->Increment(temp_dat, lev); - MultiFab::Copy(*mf[lev], temp_dat, 0, dcomp, 1, 0); - if (lev == 0) - { - varnames.push_back("part_per_cell"); - } - dcomp += 1; - } - - if (plot_part_per_grid || plot_part_per_proc) - { - const Vector<long>& npart_in_grid = mypc->NumberOfParticlesInGrid(lev); - - if (plot_part_per_grid) - { - // MultiFab containing number of particles per grid (stored as constant for all cells in each grid) -#ifdef _OPENMP -#pragma omp parallel -#endif - for (MFIter mfi(*mf[lev]); mfi.isValid(); ++mfi) { - (*mf[lev])[mfi].setVal(static_cast<Real>(npart_in_grid[mfi.index()]), dcomp); - } - if (lev == 0) - { - varnames.push_back("part_per_grid"); - } - dcomp += 1; - } - - if (plot_part_per_proc) - { - // MultiFab containing number of particles per process (stored as constant for all cells in each grid) - long n_per_proc = 0; -#ifdef _OPENMP -#pragma omp parallel reduction(+:n_per_proc) -#endif - for (MFIter mfi(*mf[lev]); mfi.isValid(); ++mfi) { - n_per_proc += npart_in_grid[mfi.index()]; - } - mf[lev]->setVal(static_cast<Real>(n_per_proc), dcomp,1); - if (lev == 0) - { - varnames.push_back("part_per_proc"); - } - dcomp += 1; - } - } - - if (plot_proc_number) - { - // MultiFab containing the Processor ID -#ifdef _OPENMP -#pragma omp parallel -#endif - for (MFIter mfi(*mf[lev]); mfi.isValid(); ++mfi) { - (*mf[lev])[mfi].setVal(static_cast<Real>(ParallelDescriptor::MyProc()), dcomp); - } - if (lev == 0) - { - varnames.push_back("proc_number"); - } - dcomp += 1; - } - - if (plot_divb) - { - if (do_nodal) amrex::Abort("TODO: do_nodal && plot_divb"); - ComputeDivB(*mf[lev], dcomp, - {Bfield_aux[lev][0].get(),Bfield_aux[lev][1].get(),Bfield_aux[lev][2].get()}, - WarpX::CellSize(lev)); - if (lev == 0) - { - varnames.push_back("divB"); - } - dcomp += 1; - } - - if (plot_dive) - { - if (do_nodal) amrex::Abort("TODO: do_nodal && plot_dive"); - const BoxArray& ba = amrex::convert(boxArray(lev),IntVect::TheUnitVector()); - MultiFab dive(ba,DistributionMap(lev),1,0); - ComputeDivE(dive, 0, - {Efield_aux[lev][0].get(), Efield_aux[lev][1].get(), Efield_aux[lev][2].get()}, - WarpX::CellSize(lev)); - amrex::average_node_to_cellcenter(*mf[lev], dcomp, dive, 0, 1); - if (lev == 0) - { - varnames.push_back("divE"); - } - dcomp += 1; - } - - if (plot_rho) - { - amrex::average_node_to_cellcenter(*mf[lev], dcomp, *rho_fp[lev], 0, 1); - if (lev == 0) - { - varnames.push_back("rho"); - } - dcomp += 1; - } - - if (plot_F) - { - amrex::average_node_to_cellcenter(*mf[lev], dcomp, *F_fp[lev], 0, 1); - if (lev == 0) - { - varnames.push_back("F"); - } - dcomp += 1; - } - - if (plot_finepatch) - { - if (do_nodal) - { - amrex::average_node_to_cellcenter(*mf[lev], dcomp , *Efield_fp[lev][0], 0, 1); - amrex::average_node_to_cellcenter(*mf[lev], dcomp+1, *Efield_fp[lev][1], 0, 1); - amrex::average_node_to_cellcenter(*mf[lev], dcomp+2, *Efield_fp[lev][2], 0, 1); - } - else - { - PackPlotDataPtrs(srcmf, Efield_fp[lev]); - amrex::average_edge_to_cellcenter(*mf[lev], dcomp, srcmf); -#if (AMREX_SPACEDIM == 2) - MultiFab::Copy(*mf[lev], *mf[lev], dcomp+1, dcomp+2, 1, ngrow); - amrex::average_node_to_cellcenter(*mf[lev], dcomp+1, *Efield_fp[lev][1], 0, 1); -#endif - } - if (lev == 0) - { - varnames.push_back("Ex_fp"); - varnames.push_back("Ey_fp"); - varnames.push_back("Ez_fp"); - } - dcomp += 3; - - if (do_nodal) - { - amrex::average_node_to_cellcenter(*mf[lev], dcomp , *Bfield_fp[lev][0], 0, 1); - amrex::average_node_to_cellcenter(*mf[lev], dcomp+1, *Bfield_fp[lev][1], 0, 1); - amrex::average_node_to_cellcenter(*mf[lev], dcomp+2, *Bfield_fp[lev][2], 0, 1); - } - else - { - PackPlotDataPtrs(srcmf, Bfield_fp[lev]); - amrex::average_face_to_cellcenter(*mf[lev], dcomp, srcmf); -#if (AMREX_SPACEDIM == 2) - MultiFab::Copy(*mf[lev], *mf[lev], dcomp+1, dcomp+2, 1, ngrow); - MultiFab::Copy(*mf[lev], *Bfield_fp[lev][1], 0, dcomp+1, 1, ngrow); -#endif - } - if (lev == 0) - { - varnames.push_back("Bx_fp"); - varnames.push_back("By_fp"); - varnames.push_back("Bz_fp"); - } - dcomp += 3; - } - - if (plot_crsepatch) - { - // First the electric field - if (lev == 0) - { - mf[lev]->setVal(0.0, dcomp, 3, ngrow); - } - else - { - if (do_nodal) amrex::Abort("TODO: do_nodal && plot_crsepatch"); - std::array<std::unique_ptr<MultiFab>, 3> E = getInterpolatedE(lev); - PackPlotDataPtrs(srcmf, E); - amrex::average_edge_to_cellcenter(*mf[lev], dcomp, srcmf); -#if (AMREX_SPACEDIM == 2) - MultiFab::Copy(*mf[lev], *mf[lev], dcomp+1, dcomp+2, 1, ngrow); - amrex::average_node_to_cellcenter(*mf[lev], dcomp+1, *E[1], 0, 1); -#endif - } - if (lev == 0) - { - varnames.push_back("Ex_cp"); - varnames.push_back("Ey_cp"); - varnames.push_back("Ez_cp"); - } - dcomp += 3; + // Average the fields from the simulation grid to the cell centers + const int ngrow = 0; + Vector<std::string> varnames; // Name of the written fields + // mf_avg will contain the averaged, cell-centered fields + Vector<MultiFab> mf_avg; + WarpX::AverageAndPackFields( varnames, mf_avg, ngrow ); + + // Coarsen the fields, if requested by the user + Vector<const MultiFab*> output_mf; // will point to the data to be written + Vector<MultiFab> coarse_mf; // will remain empty if there is no coarsening + Vector<Geometry> output_geom; + if (plot_coarsening_ratio != 1) { + coarsenCellCenteredFields( coarse_mf, output_geom, mf_avg, Geom(), + plot_coarsening_ratio, finest_level ); + output_mf = amrex::GetVecOfConstPtrs(coarse_mf); + } else { // No averaging necessary, simply point to mf_avg + output_mf = amrex::GetVecOfConstPtrs(mf_avg); + output_geom = Geom(); + } - // now the magnetic field - if (lev == 0) - { - mf[lev]->setVal(0.0, dcomp, 3, ngrow); - } - else - { - if (do_nodal) amrex::Abort("TODO: do_nodal && plot_crsepatch"); - std::array<std::unique_ptr<MultiFab>, 3> B = getInterpolatedB(lev); - PackPlotDataPtrs(srcmf, B); - amrex::average_face_to_cellcenter(*mf[lev], dcomp, srcmf); -#if (AMREX_SPACEDIM == 2) - MultiFab::Copy(*mf[lev], *mf[lev], dcomp+1, dcomp+2, 1, ngrow); - MultiFab::Copy(*mf[lev], *B[1], 0, dcomp+1, 1, ngrow); +#ifdef WARPX_USE_OPENPMD + if (dump_openpmd){ + // Write openPMD format: only for level 0 + std::string filename = amrex::Concatenate("diags/hdf5/data", istep[0]); + filename += ".h5"; + WriteOpenPMDFields( filename, varnames, + *output_mf[0], output_geom[0], istep[0], t_new[0] ); + } #endif - } - if (lev == 0) - { - varnames.push_back("Bx_cp"); - varnames.push_back("By_cp"); - varnames.push_back("Bz_cp"); - } - dcomp += 3; - } - - if (costs[0] != nullptr) - { - MultiFab::Copy(*mf[lev], *costs[lev], 0, dcomp, 1, 0); - if (lev == 0) - { - varnames.push_back("costs"); - } - dcomp += 1; - } - BL_ASSERT(dcomp == ncomp); - } + if (dump_plotfiles){ -#if 0 - for (int lev = finest_level; lev > 0; --lev) - { - amrex::average_down(*mf[lev], *mf[lev-1], 0, ncomp, refRatio(lev-1)); - } -#endif + // Write the fields contained in `mf_avg`, and corresponding to the + // names `varnames`, into a plotfile. + // Prepare extra directory (filled later), for the raw fields + Vector<std::string> rfs; + VisMF::Header::Version current_version = VisMF::GetHeaderVersion(); + VisMF::SetHeaderVersion(plotfile_headerversion); + if (plot_raw_fields) rfs.emplace_back("raw_fields"); + amrex::WriteMultiLevelPlotfile(plotfilename, finest_level+1, + output_mf, varnames, output_geom, + t_new[0], istep, refRatio(), + "HyperCLaw-V1.1", + "Level_", + "Cell", + rfs + ); - Vector<std::string> rfs; - if (plot_raw_fields) rfs.emplace_back("raw_fields"); // pre-build raw_fields/ - amrex::WriteMultiLevelPlotfile(plotfilename, finest_level+1, - amrex::GetVecOfConstPtrs(mf), - varnames, Geom(), t_new[0], istep, refRatio(), - "HyperCLaw-V1.1", - "Level_", - "Cell", - rfs); - } if (plot_raw_fields) { const int nlevels = finestLevel()+1; for (int lev = 0; lev < nlevels; ++lev) { - const std::string raw_plotfilename = plotfilename + "/raw_fields"; - // Plot auxilary patch - if (plot_raw_fields_guards) { - VisMF::Write(*Efield_aux[lev][0], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Ex_aux")); - VisMF::Write(*Efield_aux[lev][1], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Ey_aux")); - VisMF::Write(*Efield_aux[lev][2], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Ez_aux")); - VisMF::Write(*Bfield_aux[lev][0], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Bx_aux")); - VisMF::Write(*Bfield_aux[lev][1], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "By_aux")); - VisMF::Write(*Bfield_aux[lev][2], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Bz_aux")); - } else { - const DistributionMapping& dm = DistributionMap(lev); - MultiFab Ex(Efield_aux[lev][0]->boxArray(), dm, 1, 0); - MultiFab Ey(Efield_aux[lev][1]->boxArray(), dm, 1, 0); - MultiFab Ez(Efield_aux[lev][2]->boxArray(), dm, 1, 0); - MultiFab Bx(Bfield_aux[lev][0]->boxArray(), dm, 1, 0); - MultiFab By(Bfield_aux[lev][1]->boxArray(), dm, 1, 0); - MultiFab Bz(Bfield_aux[lev][2]->boxArray(), dm, 1, 0); - MultiFab::Copy(Ex, *Efield_aux[lev][0], 0, 0, 1, 0); - MultiFab::Copy(Ey, *Efield_aux[lev][1], 0, 0, 1, 0); - MultiFab::Copy(Ez, *Efield_aux[lev][2], 0, 0, 1, 0); - MultiFab::Copy(Bx, *Bfield_aux[lev][0], 0, 0, 1, 0); - MultiFab::Copy(By, *Bfield_aux[lev][1], 0, 0, 1, 0); - MultiFab::Copy(Bz, *Bfield_aux[lev][2], 0, 0, 1, 0); - VisMF::Write(Ex, amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Ex_aux")); - VisMF::Write(Ey, amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Ey_aux")); - VisMF::Write(Ez, amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Ez_aux")); - VisMF::Write(Bx, amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Bx_aux")); - VisMF::Write(By, amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "By_aux")); - VisMF::Write(Bz, amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Bz_aux")); - } - - // Plot fine patch + const std::unique_ptr<MultiFab> empty_ptr; + const std::string raw_pltname = plotfilename + "/raw_fields"; + const DistributionMapping& dm = DistributionMap(lev); + + // Auxiliary patch + WriteRawField( *Efield_aux[lev][0], dm, raw_pltname, level_prefix, "Ex_aux", lev, plot_raw_fields_guards); + WriteRawField( *Efield_aux[lev][1], dm, raw_pltname, level_prefix, "Ey_aux", lev, plot_raw_fields_guards); + WriteRawField( *Efield_aux[lev][2], dm, raw_pltname, level_prefix, "Ez_aux", lev, plot_raw_fields_guards); + WriteRawField( *Bfield_aux[lev][0], dm, raw_pltname, level_prefix, "Bx_aux", lev, plot_raw_fields_guards); + WriteRawField( *Bfield_aux[lev][1], dm, raw_pltname, level_prefix, "By_aux", lev, plot_raw_fields_guards); + WriteRawField( *Bfield_aux[lev][2], dm, raw_pltname, level_prefix, "Bz_aux", lev, plot_raw_fields_guards); + + // Fine patch if (plot_finepatch) { - if (plot_raw_fields_guards) { - VisMF::Write(*Efield_fp[lev][0], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Ex_fp")); - VisMF::Write(*Efield_fp[lev][1], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Ey_fp")); - VisMF::Write(*Efield_fp[lev][2], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Ez_fp")); - VisMF::Write(*Bfield_fp[lev][0], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Bx_fp")); - VisMF::Write(*Bfield_fp[lev][1], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "By_fp")); - VisMF::Write(*Bfield_fp[lev][2], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Bz_fp")); - VisMF::Write(*current_fp[lev][0], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "jx_fp")); - VisMF::Write(*current_fp[lev][1], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "jy_fp")); - VisMF::Write(*current_fp[lev][2], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "jz_fp")); - } else { - const DistributionMapping& dm = DistributionMap(lev); - MultiFab Ex(Efield_fp[lev][0]->boxArray(), dm, 1, 0); - MultiFab Ey(Efield_fp[lev][1]->boxArray(), dm, 1, 0); - MultiFab Ez(Efield_fp[lev][2]->boxArray(), dm, 1, 0); - MultiFab Bx(Bfield_fp[lev][0]->boxArray(), dm, 1, 0); - MultiFab By(Bfield_fp[lev][1]->boxArray(), dm, 1, 0); - MultiFab Bz(Bfield_fp[lev][2]->boxArray(), dm, 1, 0); - MultiFab jx(current_fp[lev][0]->boxArray(), dm, 1, 0); - MultiFab jy(current_fp[lev][1]->boxArray(), dm, 1, 0); - MultiFab jz(current_fp[lev][2]->boxArray(), dm, 1, 0); - MultiFab::Copy(Ex, *Efield_fp[lev][0], 0, 0, 1, 0); - MultiFab::Copy(Ey, *Efield_fp[lev][1], 0, 0, 1, 0); - MultiFab::Copy(Ez, *Efield_fp[lev][2], 0, 0, 1, 0); - MultiFab::Copy(Bx, *Bfield_fp[lev][0], 0, 0, 1, 0); - MultiFab::Copy(By, *Bfield_fp[lev][1], 0, 0, 1, 0); - MultiFab::Copy(Bz, *Bfield_fp[lev][2], 0, 0, 1, 0); - MultiFab::Copy(jx, *current_fp[lev][0], 0, 0, 1, 0); - MultiFab::Copy(jy, *current_fp[lev][1], 0, 0, 1, 0); - MultiFab::Copy(jz, *current_fp[lev][2], 0, 0, 1, 0); - VisMF::Write(Ex, amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Ex_fp")); - VisMF::Write(Ey, amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Ey_fp")); - VisMF::Write(Ez, amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Ez_fp")); - VisMF::Write(Bx, amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Bx_fp")); - VisMF::Write(By, amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "By_fp")); - VisMF::Write(Bz, amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Bz_fp")); - VisMF::Write(jx, amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "jx_fp")); - VisMF::Write(jy, amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "jy_fp")); - VisMF::Write(jz, amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "jz_fp")); + WriteRawField( *Efield_fp[lev][0], dm, raw_pltname, level_prefix, "Ex_fp", lev, plot_raw_fields_guards); + WriteRawField( *Efield_fp[lev][1], dm, raw_pltname, level_prefix, "Ey_fp", lev, plot_raw_fields_guards); + WriteRawField( *Efield_fp[lev][2], dm, raw_pltname, level_prefix, "Ez_fp", lev, plot_raw_fields_guards); + WriteRawField( *current_fp[lev][0], dm, raw_pltname, level_prefix, "jx_fp", lev, plot_raw_fields_guards); + WriteRawField( *current_fp[lev][1], dm, raw_pltname, level_prefix, "jy_fp", lev, plot_raw_fields_guards); + WriteRawField( *current_fp[lev][2], dm, raw_pltname, level_prefix, "jz_fp", lev, plot_raw_fields_guards); + WriteRawField( *Bfield_fp[lev][0], dm, raw_pltname, level_prefix, "Bx_fp", lev, plot_raw_fields_guards); + WriteRawField( *Bfield_fp[lev][1], dm, raw_pltname, level_prefix, "By_fp", lev, plot_raw_fields_guards); + WriteRawField( *Bfield_fp[lev][2], dm, raw_pltname, level_prefix, "Bz_fp", lev, plot_raw_fields_guards); + if (F_fp[lev]) WriteRawField( *F_fp[lev], dm, raw_pltname, level_prefix, "F_fp", lev, plot_raw_fields_guards); + if (plot_rho) { + // Use the component 1 of `rho_fp`, i.e. rho_new for time synchronization + MultiFab rho_new(*rho_fp[lev], amrex::make_alias, 1, 1); + WriteRawField( rho_new, dm, raw_pltname, level_prefix, "rho_fp", lev, plot_raw_fields_guards); } } - // Plot coarse patch - if (plot_crsepatch) - { - if (lev == 0) - { - const DistributionMapping& dm = DistributionMap(lev); - MultiFab Ex(Efield_aux[lev][0]->boxArray(), dm, 1, 0); - MultiFab Ey(Efield_aux[lev][1]->boxArray(), dm, 1, 0); - MultiFab Ez(Efield_aux[lev][2]->boxArray(), dm, 1, 0); - MultiFab Bx(Bfield_aux[lev][0]->boxArray(), dm, 1, 0); - MultiFab By(Bfield_aux[lev][1]->boxArray(), dm, 1, 0); - MultiFab Bz(Bfield_aux[lev][2]->boxArray(), dm, 1, 0); - - Ex.setVal(0.0); Ey.setVal(0.0); Ez.setVal(0.0); - Bx.setVal(0.0); By.setVal(0.0); Bz.setVal(0.0); - - VisMF::Write(Ex, amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Ex_cp")); - VisMF::Write(Ey, amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Ey_cp")); - VisMF::Write(Ez, amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Ez_cp")); - VisMF::Write(Bx, amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Bx_cp")); - VisMF::Write(By, amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "By_cp")); - VisMF::Write(Bz, amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Bz_cp")); - } else { - - if (plot_raw_fields_guards) { - VisMF::Write(*Efield_cp[lev][0], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Ex_cp")); - VisMF::Write(*Efield_cp[lev][1], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Ey_cp")); - VisMF::Write(*Efield_cp[lev][2], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Ez_cp")); - VisMF::Write(*Bfield_cp[lev][0], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Bx_cp")); - VisMF::Write(*Bfield_cp[lev][1], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "By_cp")); - VisMF::Write(*Bfield_cp[lev][2], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Bz_cp")); - } else { - std::array<std::unique_ptr<MultiFab>, 3> E = getInterpolatedE(lev); - std::array<std::unique_ptr<MultiFab>, 3> B = getInterpolatedB(lev); - - VisMF::Write(*E[0], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Ex_cp")); - VisMF::Write(*E[1], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Ey_cp")); - VisMF::Write(*E[2], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Ez_cp")); - VisMF::Write(*B[0], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Bx_cp")); - VisMF::Write(*B[1], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "By_cp")); - VisMF::Write(*B[2], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "Bz_cp")); - } - } + // Coarse path + if (plot_crsepatch) { + WriteCoarseVector( "E", + Efield_cp[lev][0], Efield_cp[lev][1], Efield_cp[lev][2], + Efield_fp[lev][0], Efield_fp[lev][1], Efield_fp[lev][2], + dm, raw_pltname, level_prefix, lev, plot_raw_fields_guards); + WriteCoarseVector( "B", + Bfield_cp[lev][0], Bfield_cp[lev][1], Bfield_cp[lev][2], + Bfield_fp[lev][0], Bfield_fp[lev][1], Bfield_fp[lev][2], + dm, raw_pltname, level_prefix, lev, plot_raw_fields_guards); + WriteCoarseVector( "j", + current_cp[lev][0], current_cp[lev][1], current_cp[lev][2], + current_fp[lev][0], current_fp[lev][1], current_fp[lev][2], + dm, raw_pltname, level_prefix, lev, plot_raw_fields_guards); + if (F_cp[lev]) WriteCoarseScalar( + "F", F_cp[lev], F_fp[lev], + dm, raw_pltname, level_prefix, lev, + plot_raw_fields_guards); + if (plot_rho) WriteCoarseScalar( + "rho", rho_cp[lev], rho_fp[lev], + dm, raw_pltname, level_prefix, lev, + plot_raw_fields_guards, 1); + // Use the component 1 of `rho_cp`, i.e. rho_new for time synchronization } - - if (F_fp[lev]) { - VisMF::Write(*F_fp[lev], amrex::MultiFabFileFullPrefix(lev, raw_plotfilename, level_prefix, "F_fp")); - } - } } @@ -1264,16 +638,18 @@ WarpX::WritePlotFile () const particle_varnames.push_back("uxold"); particle_varnames.push_back("uyold"); - particle_varnames.push_back("uzold"); + particle_varnames.push_back("uzold"); #endif - - mypc->Checkpoint(plotfilename, true, particle_varnames); + + mypc->WritePlotFile(plotfilename, particle_plot_flags, particle_varnames); WriteJobInfo(plotfilename); WriteWarpXHeader(plotfilename); VisMF::SetHeaderVersion(current_version); + } // endif: dump_plotfiles + } void @@ -1394,145 +770,3 @@ WarpX::WriteJobInfo (const std::string& dir) const jobInfoFile.close(); } } - -std::array<std::unique_ptr<MultiFab>, 3> WarpX::getInterpolatedE(int lev) const -{ - - const int ngrow = 0; - - std::array<std::unique_ptr<MultiFab>, 3> interpolated_E; - for (int i = 0; i < 3; ++i) { - interpolated_E[i].reset( new MultiFab(Efield_aux[lev][i]->boxArray(), dmap[lev], 1, ngrow) ); - interpolated_E[i]->setVal(0.0); - } - - const int r_ratio = refRatio(lev-1)[0]; - const int use_limiter = 0; -#ifdef _OPEMP -#pragma omp parallel -#endif - { - std::array<FArrayBox,3> efab; - for (MFIter mfi(*interpolated_E[0]); mfi.isValid(); ++mfi) - { - Box ccbx = mfi.fabbox(); - ccbx.enclosedCells(); - ccbx.coarsen(r_ratio).refine(r_ratio); // so that ccbx is coarsenable - - const FArrayBox& cxfab = (*Efield_cp[lev][0])[mfi]; - const FArrayBox& cyfab = (*Efield_cp[lev][1])[mfi]; - const FArrayBox& czfab = (*Efield_cp[lev][2])[mfi]; - - efab[0].resize(amrex::convert(ccbx,Ex_nodal_flag)); - efab[1].resize(amrex::convert(ccbx,Ey_nodal_flag)); - efab[2].resize(amrex::convert(ccbx,Ez_nodal_flag)); - -#if (AMREX_SPACEDIM == 3) - amrex_interp_efield(ccbx.loVect(), ccbx.hiVect(), - BL_TO_FORTRAN_ANYD(efab[0]), - BL_TO_FORTRAN_ANYD(efab[1]), - BL_TO_FORTRAN_ANYD(efab[2]), - BL_TO_FORTRAN_ANYD(cxfab), - BL_TO_FORTRAN_ANYD(cyfab), - BL_TO_FORTRAN_ANYD(czfab), - &r_ratio,&use_limiter); -#else - amrex_interp_efield(ccbx.loVect(), ccbx.hiVect(), - BL_TO_FORTRAN_ANYD(efab[0]), - BL_TO_FORTRAN_ANYD(efab[2]), - BL_TO_FORTRAN_ANYD(cxfab), - BL_TO_FORTRAN_ANYD(czfab), - &r_ratio,&use_limiter); - amrex_interp_nd_efield(ccbx.loVect(), ccbx.hiVect(), - BL_TO_FORTRAN_ANYD(efab[1]), - BL_TO_FORTRAN_ANYD(cyfab), - &r_ratio); -#endif - - for (int i = 0; i < 3; ++i) { - const Box& bx = (*interpolated_E[i])[mfi].box(); - (*interpolated_E[i])[mfi].plus(efab[i], bx, bx, 0, 0, 1); - } - } - } - - return interpolated_E; -} - -std::array<std::unique_ptr<MultiFab>, 3> WarpX::getInterpolatedB(int lev) const -{ - const int ngrow = 0; - - std::array<std::unique_ptr<MultiFab>, 3> interpolated_B; - for (int i = 0; i < 3; ++i) { - interpolated_B[i].reset( new MultiFab(Bfield_aux[lev][i]->boxArray(), dmap[lev], 1, ngrow) ); - interpolated_B[i]->setVal(0.0); - } - - const Real* dx = Geom(lev-1).CellSize(); - const int r_ratio = refRatio(lev-1)[0]; - const int use_limiter = 0; -#ifdef _OPEMP -#pragma omp parallel -#endif - { - std::array<FArrayBox,3> bfab; - for (MFIter mfi(*interpolated_B[0]); mfi.isValid(); ++mfi) - { - Box ccbx = mfi.fabbox(); - ccbx.enclosedCells(); - ccbx.coarsen(r_ratio).refine(r_ratio); // so that ccbx is coarsenable - - const FArrayBox& cxfab = (*Bfield_cp[lev][0])[mfi]; - const FArrayBox& cyfab = (*Bfield_cp[lev][1])[mfi]; - const FArrayBox& czfab = (*Bfield_cp[lev][2])[mfi]; - - bfab[0].resize(amrex::convert(ccbx,Bx_nodal_flag)); - bfab[1].resize(amrex::convert(ccbx,By_nodal_flag)); - bfab[2].resize(amrex::convert(ccbx,Bz_nodal_flag)); - -#if (AMREX_SPACEDIM == 3) - amrex_interp_div_free_bfield(ccbx.loVect(), ccbx.hiVect(), - BL_TO_FORTRAN_ANYD(bfab[0]), - BL_TO_FORTRAN_ANYD(bfab[1]), - BL_TO_FORTRAN_ANYD(bfab[2]), - BL_TO_FORTRAN_ANYD(cxfab), - BL_TO_FORTRAN_ANYD(cyfab), - BL_TO_FORTRAN_ANYD(czfab), - dx, &r_ratio, &use_limiter); -#else - amrex_interp_div_free_bfield(ccbx.loVect(), ccbx.hiVect(), - BL_TO_FORTRAN_ANYD(bfab[0]), - BL_TO_FORTRAN_ANYD(bfab[2]), - BL_TO_FORTRAN_ANYD(cxfab), - BL_TO_FORTRAN_ANYD(czfab), - dx, &r_ratio, &use_limiter); - amrex_interp_cc_bfield(ccbx.loVect(), ccbx.hiVect(), - BL_TO_FORTRAN_ANYD(bfab[1]), - BL_TO_FORTRAN_ANYD(cyfab), - &r_ratio, &use_limiter); -#endif - - for (int i = 0; i < 3; ++i) { - const Box& bx = (*interpolated_B[i])[mfi].box(); - (*interpolated_B[i])[mfi].plus(bfab[i], bx, bx, 0, 0, 1); - } - } - } - return interpolated_B; -} - -void -WarpX::PackPlotDataPtrs (Vector<const MultiFab*>& pmf, - const std::array<std::unique_ptr<MultiFab>,3>& data) -{ - BL_ASSERT(pmf.size() == AMREX_SPACEDIM); -#if (AMREX_SPACEDIM == 3) - pmf[0] = data[0].get(); - pmf[1] = data[1].get(); - pmf[2] = data[2].get(); -#elif (AMREX_SPACEDIM == 2) - pmf[0] = data[0].get(); - pmf[1] = data[2].get(); -#endif -} |