From 2a3955a5f5aac1aef6e6e72687f182331e049c39 Mon Sep 17 00:00:00 2001 From: Max Katz Date: Mon, 8 Apr 2024 12:00:17 -0400 Subject: [PATCH] Allow plotting only a subset of Amr levels (#2825) If the user would like to limit plotfile size on disk, they can plot only a subset of the levels -- this should still be an accurate (though lower resolution) representation of the fluid state since the state is averaged down at the end of the timestep. fcompare is also updated to allow comparing between plotfiles with different numbers of levels. --- Src/Amr/AMReX_Amr.H | 3 +++ Src/Amr/AMReX_Amr.cpp | 15 ++++++++++----- Src/Amr/AMReX_AmrLevel.cpp | 9 +++++---- Tools/Plotfile/fcompare.cpp | 17 +++++++++++++---- 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/Src/Amr/AMReX_Amr.H b/Src/Amr/AMReX_Amr.H index bb18ec9d160..3d9df9484ec 100644 --- a/Src/Amr/AMReX_Amr.H +++ b/Src/Amr/AMReX_Amr.H @@ -121,6 +121,8 @@ public: Real plotPer () const noexcept { return plot_per; } //! Spacing in log10(time) of logarithmically spaced plot files Real plotLogPer () const noexcept { return plot_log_per; } + //! Maximum level to plot + int plotMaxLevel () const noexcept { return plot_max_level; } //! Number of time steps between small plot files. int smallplotInt () const noexcept { return small_plot_int; } //! Time between plot files. @@ -424,6 +426,7 @@ protected: int plot_int; //!< How often plotfile (# of time steps) Real plot_per; //!< How often plotfile (in units of time) Real plot_log_per; //!< How often plotfile (in units of log10(time)) + int plot_max_level; //!< Maximum AMR level to write to a plotfile int small_plot_int; //!< How often small plotfile (# of time steps) Real small_plot_per; //!< How often small plotfile (in units of time) Real small_plot_log_per; //!< How often small plotfile (in units of log10(time)) diff --git a/Src/Amr/AMReX_Amr.cpp b/Src/Amr/AMReX_Amr.cpp index e8696aaaab8..eeeae2ba861 100644 --- a/Src/Amr/AMReX_Amr.cpp +++ b/Src/Amr/AMReX_Amr.cpp @@ -920,6 +920,8 @@ Amr::writePlotFileDoit (std::string const& pltfile, bool regular) { auto dPlotFileTime0 = amrex::second(); + int max_level_to_plot = std::min(plot_max_level, finest_level); + VisMF::SetNOutFiles(plot_nfiles); VisMF::Header::Version currentVersion(VisMF::GetHeaderVersion()); VisMF::SetHeaderVersion(plot_headerversion); @@ -941,7 +943,7 @@ Amr::writePlotFileDoit (std::string const& pltfile, bool regular) if (precreateDirectories) { // ---- make all directories at once amrex::UtilRenameDirectoryToOld(pltfile, false); // dont call barrier amrex::UtilCreateCleanDirectory(pltfileTemp, false); // dont call barrier - for(int i(0); i <= finest_level; ++i) { + for(int i(0); i <= max_level_to_plot; ++i) { amr_level[i]->CreateLevelDirectory(pltfileTemp); } ParallelDescriptor::Barrier("Amr::writePlotFile:PCD"); @@ -973,17 +975,17 @@ Amr::writePlotFileDoit (std::string const& pltfile, bool regular) } if (regular) { - for (int k(0); k <= finest_level; ++k) { + for (int k(0); k <= max_level_to_plot; ++k) { amr_level[k]->writePlotFilePre(pltfileTemp, HeaderFile); } - for (int k(0); k <= finest_level; ++k) { + for (int k(0); k <= max_level_to_plot; ++k) { amr_level[k]->writePlotFile(pltfileTemp, HeaderFile); } - for (int k(0); k <= finest_level; ++k) { + for (int k(0); k <= max_level_to_plot; ++k) { amr_level[k]->writePlotFilePost(pltfileTemp, HeaderFile); } } else { - for (int k(0); k <= finest_level; ++k) { + for (int k(0); k <= max_level_to_plot; ++k) { amr_level[k]->writeSmallPlotFile(pltfileTemp, HeaderFile); } } @@ -3268,6 +3270,9 @@ Amr::initPltAndChk () } } + plot_max_level = max_level; + pp.queryAdd("plot_max_level",plot_max_level); + small_plot_file_root = "smallplt"; pp.queryAdd("small_plot_file",small_plot_file_root); diff --git a/Src/Amr/AMReX_AmrLevel.cpp b/Src/Amr/AMReX_AmrLevel.cpp index dff9c88b61c..f0a54cac62a 100644 --- a/Src/Amr/AMReX_AmrLevel.cpp +++ b/Src/Amr/AMReX_AmrLevel.cpp @@ -179,6 +179,8 @@ AmrLevel::writePlotFile (const std::string& dir, // if the State_Type is ::Interval, this will get t^{n+1/2} instead of t^n Real cur_time = state[0].curTime(); + int f_lev = std::min(parent->plotMaxLevel(), parent->finestLevel()); + if (level == 0 && ParallelDescriptor::IOProcessor()) { // @@ -218,7 +220,6 @@ AmrLevel::writePlotFile (const std::string& dir, os << AMREX_SPACEDIM << '\n'; os << parent->cumTime() << '\n'; - int f_lev = parent->finestLevel(); os << f_lev << '\n'; for (i = 0; i < AMREX_SPACEDIM; i++) { os << Geom().ProbLo(i) << ' '; @@ -290,7 +291,7 @@ AmrLevel::writePlotFile (const std::string& dir, RealBox gridloc = RealBox(grids[i],geom.CellSize(),geom.ProbLo()); for (n = 0; n < AMREX_SPACEDIM; n++) { os << gridloc.lo(n) << ' ' << gridloc.hi(n) << '\n'; -} + } } // // The full relative pathname of the MultiFabs at this level. @@ -307,8 +308,8 @@ AmrLevel::writePlotFile (const std::string& dir, #ifdef AMREX_USE_EB if (EB2::TopIndexSpaceIfPresent()) { // volfrac threshold for amrvis - if (level == parent->finestLevel()) { - for (int lev = 0; lev <= parent->finestLevel(); ++lev) { + if (level == f_lev) { + for (int lev = 0; lev <= f_lev; ++lev) { os << "1.0e-6\n"; } } diff --git a/Tools/Plotfile/fcompare.cpp b/Tools/Plotfile/fcompare.cpp index 025df0075ce..87f4d83cb88 100644 --- a/Tools/Plotfile/fcompare.cpp +++ b/Tools/Plotfile/fcompare.cpp @@ -24,7 +24,7 @@ void PrintUsage() << " variable.\n" << "\n" << " usage:\n" - << " fcompare [-n|--norm num] [-d|--diffvar var] [-z|--zone_info var] [-a|--allow_diff_grids] [-r|rel_tol] [--abs_tol] [--abort_if_not_all_found] file1 file2\n" + << " fcompare [-n|--norm num] [-d|--diffvar var] [-z|--zone_info var] [-a|--allow_diff_grids] [-l|--allow_diff_num_levels] [-r|rel_tol] [--abs_tol] [--abort_if_not_all_found] file1 file2\n" << "\n" << " optional arguments:\n" << " -n|--norm num : what norm to use (default is 0 for inf norm)\n" @@ -33,6 +33,7 @@ void PrintUsage() << " -z|--zone_info var : output the information for a zone corresponding\n" << " to the maximum error for the given variable\n" << " -a|--allow_diff_grids : allow different BoxArrays covering the same domain\n" + << " -l|--allow_diff_num_levels : allow different number of levels (only the levels in common will be compared)\n" << " -r|--rel_tol rtol : relative tolerance (default is 0)\n" << " --abs_tol atol : absolute tolerance (default is 0)\n" << " --abort_if_not_all_found : abort if not all variables are present in both files\n" @@ -56,6 +57,7 @@ int main_main() std::string diffvar; int zone_info = false; int allow_diff_grids = false; + int allow_diff_num_levels = false; Real rtol = 0.0; Real atol = 0.0; std::string zone_info_var_name; @@ -82,6 +84,8 @@ int main_main() plot_names[0] = diffvar; } else if (fname == "-a" || fname == "--allow_diff_grids") { allow_diff_grids = true; + } else if (fname == "-l" || fname == "--allow_diff_num_levels") { + allow_diff_num_levels = true; } else if (fname == "-r" || fname == "--rel_tol") { rtol = Real(std::stod(amrex::get_command_argument(++farg))); } else if (fname == "--abs_tol") { @@ -114,10 +118,15 @@ int main_main() AMREX_ALWAYS_ASSERT_WITH_MESSAGE(pf_a.spaceDim() == pf_b.spaceDim(), "ERROR: plotfiles have different numbers of spatial dimensions"); - const int finest_level = pf_a.finestLevel(); + const int finest_level = std::min(pf_a.finestLevel(), pf_b.finestLevel()); const int nlevels = finest_level+1; - AMREX_ALWAYS_ASSERT_WITH_MESSAGE(pf_a.finestLevel() == pf_b.finestLevel(), - "ERROR: number of levels do not match"); + if (allow_diff_num_levels && pf_a.finestLevel() != pf_b.finestLevel()) { + amrex::Print() << "\n WARNING: number of levels do not match\n"; + } + else { + AMREX_ALWAYS_ASSERT_WITH_MESSAGE(pf_a.finestLevel() == pf_b.finestLevel(), + "ERROR: number of levels do not match"); + } const int ncomp_a = pf_a.nComp(); const int ncomp_b = pf_b.nComp();