aboutsummaryrefslogtreecommitdiff
path: root/Source/Utils/WarpXUtil.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Utils/WarpXUtil.cpp')
-rw-r--r--Source/Utils/WarpXUtil.cpp80
1 files changed, 80 insertions, 0 deletions
diff --git a/Source/Utils/WarpXUtil.cpp b/Source/Utils/WarpXUtil.cpp
index 952982c47..c7949925c 100644
--- a/Source/Utils/WarpXUtil.cpp
+++ b/Source/Utils/WarpXUtil.cpp
@@ -213,6 +213,86 @@ WarpXParser makeParser (std::string const& parse_function, std::vector<std::stri
return parser;
}
+/**
+ * \brief Ensures that the blocks are setup correctly for the RZ spectral solver
+ * When using the RZ spectral solver, the Hankel transform cannot be
+ * divided among multiple blocks. Each block must extend over the
+ * entire radial extent.
+ * The grid can be divided up along z, but the number of blocks
+ * must be >= the number of processors.
+ */
+void CheckGriddingForRZSpectral ()
+{
+#if (defined WARPX_DIM_RZ) && (defined WARPX_USE_PSATD)
+
+ int max_level;
+ Vector<int> n_cell(AMREX_SPACEDIM, -1);
+
+ ParmParse pp_amr("amr");
+
+ pp_amr.get("max_level",max_level);
+ pp_amr.getarr("n_cell",n_cell,0,AMREX_SPACEDIM);
+
+ Vector<int> blocking_factor_x(max_level+1);
+ Vector<int> max_grid_size_x(max_level+1);
+
+ // Set the radial block size to be equal to the radial grid size.
+ blocking_factor_x[0] = n_cell[0];
+ max_grid_size_x[0] = n_cell[0];
+
+ for (int lev=1 ; lev <= max_level ; lev++) {
+ // For this to be correct, this needs to read in any user specified refinement ratios.
+ // But since that is messy and unlikely to be needed anytime soon, the ratio is
+ // fixed to 2 which will be the most likely value.
+ blocking_factor_x[lev] = blocking_factor_x[lev-1]*2; // refRatio(lev-1);
+ max_grid_size_x[lev] = max_grid_size_x[lev-1]*2; // refRatio(lev-1);
+ }
+
+ // Note that any user input values for these parameters are discarded.
+ pp_amr.addarr("blocking_factor_x", blocking_factor_x);
+ pp_amr.addarr("max_grid_size_x", max_grid_size_x);
+
+ // Adjust the longitudinal block sizes, making sure that there are
+ // more blocks than processors.
+ // The factor of 8 is there to make some room for higher order
+ // shape factors and filtering.
+ int nprocs = ParallelDescriptor::NProcs();
+ AMREX_ALWAYS_ASSERT_WITH_MESSAGE(n_cell[1] >= 8*nprocs,
+ "With RZ spectral, there must be at least eight z-cells per processor so that there can be at least one block per processor.");
+
+ // Get the longitudinal blocking factor in case it was set by the user.
+ // If not set, use the default value of 8.
+ Vector<int> bf;
+ pp_amr.queryarr("blocking_factor",bf);
+ pp_amr.queryarr("blocking_factor_y",bf);
+ bf.resize(std::max(static_cast<int>(bf.size()),1),8);
+
+ // Modify the default or any user input, making sure that the blocking factor
+ // is small enough so that there will be at least as many blocks as there are
+ // processors. Because of the ASSERT above, bf will never be less than 8.
+ while (n_cell[1] < nprocs*bf[0]) {
+ bf[0] /= 2;
+ }
+ pp_amr.addarr("blocking_factor_y", bf);
+
+ // Get the longitudinal max grid size in case it was set by the user.
+ // If not set, use the default value of 128.
+ Vector<int> mg;
+ pp_amr.queryarr("max_grid_size",mg);
+ pp_amr.queryarr("max_grid_size_y",mg);
+ mg.resize(std::max(static_cast<int>(mg.size()),1),128);
+
+ // Modify the default or any user input, making sure that the max grid size
+ // (of the coarsest level) is small enough so that there will be at least
+ // as many blocks as there are processors.
+ while (n_cell[1] < nprocs*mg[0]) {
+ mg[0] /= 2;
+ }
+ pp_amr.addarr("max_grid_size_y", mg);
+
+#endif
+}
+
namespace WarpXUtilMsg{
void AlwaysAssert(bool is_expression_true, const std::string& msg = "ERROR!")