aboutsummaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/Diagnostics/BTDiagnostics.H1
-rw-r--r--Source/Diagnostics/BTDiagnostics.cpp182
-rw-r--r--Source/Diagnostics/ComputeDiagFunctors/BackTransformFunctor.H3
-rw-r--r--Source/Diagnostics/ComputeDiagFunctors/BackTransformFunctor.cpp2
4 files changed, 183 insertions, 5 deletions
diff --git a/Source/Diagnostics/BTDiagnostics.H b/Source/Diagnostics/BTDiagnostics.H
index 5815be63f..3033c86f0 100644
--- a/Source/Diagnostics/BTDiagnostics.H
+++ b/Source/Diagnostics/BTDiagnostics.H
@@ -55,7 +55,6 @@ private:
// boost parameters
amrex::Real m_gamma_boost;
amrex::Real m_beta_boost;
- int m_boost_direction;
int m_moving_window_dir;
/** Number of back-transformed snapshots in the lab-frame requested by the user */
diff --git a/Source/Diagnostics/BTDiagnostics.cpp b/Source/Diagnostics/BTDiagnostics.cpp
index 371a3b1cb..5782cf58e 100644
--- a/Source/Diagnostics/BTDiagnostics.cpp
+++ b/Source/Diagnostics/BTDiagnostics.cpp
@@ -3,6 +3,8 @@
#include "Utils/WarpXConst.H"
#include "ComputeDiagFunctors/ComputeDiagFunctor.H"
#include "ComputeDiagFunctors/CellCenterFunctor.H"
+#include "ComputeDiagFunctors/BackTransformFunctor.H"
+#include "Utils/CoarsenIO.H"
#include <AMReX_ParallelDescriptor.H>
#include <AMReX_PlotFileUtil.H>
#include <AMReX_VisMF.H>
@@ -55,8 +57,8 @@ void BTDiagnostics::DerivedInitData ()
m_file_name[i] = amrex::Concatenate(m_file_prefix +"/snapshots/snapshot",i,5);
}
for (int lev = 0; lev < nmax_lev; ++lev) {
- // Define cell-centered multifab over the whole domain with user-defined crse_ratio
- // for nlevels
+ // Define cell-centered multifab over the whole domain with
+ // user-defined crse_ratio for nlevels
DefineCellCenteredMultiFab(lev);
}
@@ -113,6 +115,28 @@ BTDiagnostics::TMP_writeMetaData ()
// This function will have the same functionality as writeMetaData in
// previously used BackTransformedDiagnostics class to write
// back-transformed data in a customized format
+
+ if (amrex::ParallelDescriptor::IOProcessor()) {
+ const std::string fullpath = m_file_prefix + "/snapshots";
+ if (!amrex::UtilCreateDirectory(fullpath, 0755)) amrex::CreateDirectoryFailed(fullpath);
+
+ amrex::VisMF::IO_Buffer io_buffer(amrex::VisMF::IO_Buffer_Size);
+ std::ofstream HeaderFile;
+ HeaderFile.rdbuf()->pubsetbuf(io_buffer.dataPtr(), io_buffer.size());
+ std::string HeaderFileName(m_file_prefix + "/snapshots/Header");
+ HeaderFile.open(HeaderFileName.c_str(), std::ofstream::out |
+ std::ofstream::trunc |
+ std::ofstream::binary);
+ if (!HeaderFile.good()) amrex::FileOpenFailed( HeaderFileName );
+
+ HeaderFile.precision(17);
+ HeaderFile << m_num_snapshots_lab << "\n";
+ HeaderFile << m_dt_snapshots_lab << "\n";
+ HeaderFile << m_gamma_boost << "\n";
+ HeaderFile << m_beta_boost << "\n";
+
+ }
+
}
bool
@@ -139,17 +163,107 @@ BTDiagnostics::InitializeFieldBufferData ( int i_buffer , int lev)
{
auto & warpx = WarpX::GetInstance();
// 1. Lab-frame time for the i^th snapshot
+ m_t_lab.at(i_buffer) = i_buffer * m_dt_snapshots_lab;
// 2. Define domain in boosted frame at level, lev
+ amrex::RealBox diag_dom;
+ for (int idim = 0; idim < AMREX_SPACEDIM; ++idim ) {
+ // Setting lo-coordinate for the diag domain by taking the max of user-defined
+ // lo-cordinate and lo-coordinat of the simulation domain at level, lev
+ diag_dom.setLo(idim, std::max(m_lo[idim],warpx.Geom(lev).ProbLo(idim)) );
+ // Setting hi-coordinate for the diag domain by taking the max of user-defined
+ // hi-cordinate and hi-coordinate of the simulation domain at level, lev
+ diag_dom.setHi(idim, std::min(m_hi[idim],warpx.Geom(lev).ProbHi(idim)) );
+ }
// 3. Initializing the m_buffer_box for the i^th snapshot.
// At initialization, the Box has the same index space as the boosted-frame
// As time-progresses, the z-dimension indices will be modified based on
// current_z_lab
+ amrex::IntVect lo(0);
+ amrex::IntVect hi(-1);
+ for (int idim=0; idim < AMREX_SPACEDIM; ++idim) {
+ // lo index with same cell-size as simulation at level, lev.
+ const int lo_index = static_cast<int>( floor(
+ ( diag_dom.lo(idim) - warpx.Geom(lev).ProbLo(idim) ) /
+ warpx.Geom(lev).CellSize(idim) ) );
+ // Taking max of (0,lo_index) because lo_index must always be >=0
+ lo[idim] = std::max( 0, lo_index );
+ // hi index with same cell-size as simulation at level, lev.
+ const int hi_index = static_cast<int>( ceil(
+ ( diag_dom.hi(idim) - warpx.Geom(lev).ProbLo(idim) ) /
+ warpx.Geom(lev).CellSize(idim) ) );
+ // Taking max of (0,hi_index) because hi_index must always be >=0
+ // Subtracting by 1 because lo,hi indices are set to cell-centered staggering.
+ hi[idim] = std::max( 0, hi_index) - 1;
+ // if hi<=lo, then hi = lo + 1, to ensure one cell in that dimension
+ if ( hi[idim] <= lo[idim] ) {
+ hi[idim] = lo[idim] + 1;
+ AMREX_ALWAYS_ASSERT_WITH_MESSAGE(
+ m_crse_ratio[idim]==1, "coarsening ratio in reduced dimension must be 1."
+ );
+ }
+ }
+ amrex::Box diag_box( lo, hi );
+ // The box is not coarsened yet. Should this be coarsened here or when
+ // the buffer multifab is initialized?
+ m_buffer_box[i_buffer] = diag_box;
+
// 4. Define buffer_domain in lab-frame for the i^th snapshot.
// Replace z-dimension with lab-frame co-ordinates.
+ amrex::Real zmin_lab = diag_dom.lo(m_moving_window_dir)
+ / ( (1.0_rt + m_beta_boost) * m_gamma_boost);
+ amrex::Real zmax_lab = diag_dom.hi(m_moving_window_dir)
+ / ( (1.0_rt + m_beta_boost) * m_gamma_boost);
+
+
+ m_buffer_domain_lab[i_buffer] = warpx.Geom(lev).ProbDomain();
+ m_buffer_domain_lab[i_buffer].setLo(m_moving_window_dir, zmin_lab + warpx.moving_window_v * m_t_lab[i_buffer]);
+ m_buffer_domain_lab[i_buffer].setHi(m_moving_window_dir, zmin_lab + warpx.moving_window_v * m_t_lab[i_buffer]);
+
// 5. Initialize buffer counter and z-positions of the i^th snapshot in
// boosted-frame and lab-frame
+ m_buffer_counter[i_buffer] = 0;
+ m_current_z_lab[i_buffer] = 0.0_rt;
+ m_current_z_boost[i_buffer] = 0.0_rt;
+ // Now Update Current Z Positions
+ m_current_z_boost[i_buffer] = UpdateCurrentZBoostCoordinate(m_t_lab[i_buffer],
+ warpx.gett_new(lev) );
+ m_current_z_lab[i_buffer] = UpdateCurrentZLabCoordinate(m_t_lab[i_buffer],
+ warpx.gett_new(lev) );
+
+
// 6. Compute ncells_lab required for writing Header file and potentially to generate
// Back-Transform geometry to ensure compatibility with plotfiles //
+ // For the z-dimension, number of cells in the lab-frame is
+ // computed using the coarsened cell-size in the lab-frame obtained using
+ // the ref_ratio at level, lev.
+ amrex::IntVect ref_ratio = WarpX::RefRatio(lev);
+ // Number of lab-frame cells in z-direction at level, lev
+ const int num_zcells_lab = static_cast<int>( floor (
+ ( zmax_lab - zmin_lab)
+ / dz_lab(warpx.getdt(lev), ref_ratio[AMREX_SPACEDIM-1] ) ) );
+ // Take the max of 0 and num_zcells_lab
+ int Nz_lab = std::max( 0, num_zcells_lab );
+ // Number of lab-frame cells in x-direction at level, lev
+ const int num_xcells_lab = static_cast<int>( floor (
+ ( diag_dom.hi(0) - diag_dom.lo(0) )
+ / warpx.Geom(lev).CellSize(0)
+ ) );
+ // Take the max of 0 and num_ycells_lab
+ int Nx_lab = std::max( 0, num_xcells_lab);
+#if (AMREX_SPACEDIM == 3)
+ // Number of lab-frame cells in the y-direction at level, lev
+ const int num_ycells_lab = static_cast<int>( floor (
+ ( diag_dom.hi(1) - diag_dom.lo(1) )
+ / warpx.Geom(lev).CellSize(1)
+ ) );
+ // Take the max of 0 and num_xcells_lab
+ int Ny_lab = std::max( 0, num_ycells_lab );
+ m_buffer_ncells_lab[i_buffer] = {Nx_lab, Ny_lab, Nz_lab};
+#else
+ int Ny_lab = 0;
+ m_buffer_ncells_lab[i_buffer] = {Nx_lab, Nz_lab};
+#endif
+
// 7. Call funtion to create directories for customized output format
TMP_createLabFrameDirectories(i_buffer, lev);
}
@@ -161,6 +275,12 @@ BTDiagnostics::DefineCellCenteredMultiFab(int lev)
// This MultiFab will store all the user-requested fields in the boosted-frame
auto & warpx = WarpX::GetInstance();
// The BoxArray is coarsened based on the user-defined coarsening ratio
+ amrex::BoxArray ba = warpx.boxArray(lev);
+ ba.coarsen(m_crse_ratio);
+ amrex::DistributionMapping dmap = warpx.DistributionMap(lev);
+ int ngrow = 1;
+ m_cell_centered_data[lev].reset( new amrex::MultiFab(ba, dmap, m_varnames.size(), ngrow) );
+
}
void
@@ -177,10 +297,47 @@ BTDiagnostics::InitializeFieldFunctors (int lev)
m_cell_center_functors[lev].clear();
m_cell_center_functors[lev].resize( m_varnames.size() );
// 1. create an object of class BackTransformFunctor
+ for (int i = 0; i < num_BT_functors; ++i)
+ {
+ // coarsening ratio is not provided since the source MultiFab, m_cell_centered_data
+ // is coarsened based on the user-defined m_crse_ratio
+ m_all_field_functors[lev][i] = std::make_unique<BackTransformFunctor>(
+ m_cell_centered_data[lev].get(), lev, m_varnames.size() );
+ }
// 2. Define all cell-centered functors required to compute cell-centere data
// Fill vector of cell-center functors for all components
// Only E,B, j, and rho are included in the cell-center functors for BackTransform Diags
+ for (int comp=0, n=m_cell_center_functors[lev].size(); comp<n; comp++){
+ if ( m_varnames[comp] == "Ex" ){
+ m_cell_center_functors[lev][comp] = std::make_unique<CellCenterFunctor>(warpx.get_pointer_Efield_aux(lev, 0), lev, m_crse_ratio);
+ } else if ( m_varnames[comp] == "Ey" ){
+ m_cell_center_functors[lev][comp] = std::make_unique<CellCenterFunctor>(warpx.get_pointer_Efield_aux(lev, 1), lev, m_crse_ratio);
+ } else if ( m_varnames[comp] == "Ez" ){
+ m_cell_center_functors[lev][comp] = std::make_unique<CellCenterFunctor>(warpx.get_pointer_Efield_aux(lev, 2), lev, m_crse_ratio);
+ } else if ( m_varnames[comp] == "Bx" ){
+ m_cell_center_functors[lev][comp] = std::make_unique<CellCenterFunctor>(warpx.get_pointer_Bfield_aux(lev, 0), lev, m_crse_ratio);
+ } else if ( m_varnames[comp] == "By" ){
+ m_cell_center_functors[lev][comp] = std::make_unique<CellCenterFunctor>(warpx.get_pointer_Bfield_aux(lev, 1), lev, m_crse_ratio);
+ } else if ( m_varnames[comp] == "Bz" ){
+ m_cell_center_functors[lev][comp] = std::make_unique<CellCenterFunctor>(warpx.get_pointer_Bfield_aux(lev, 2), lev, m_crse_ratio);
+ } else if ( m_varnames[comp] == "jx" ){
+ m_cell_center_functors[lev][comp] = std::make_unique<CellCenterFunctor>(warpx.get_pointer_current_fp(lev, 0), lev, m_crse_ratio);
+ } else if ( m_varnames[comp] == "jy" ){
+ m_cell_center_functors[lev][comp] = std::make_unique<CellCenterFunctor>(warpx.get_pointer_current_fp(lev, 1), lev, m_crse_ratio);
+ } else if ( m_varnames[comp] == "jz" ){
+ m_cell_center_functors[lev][comp] = std::make_unique<CellCenterFunctor>(warpx.get_pointer_current_fp(lev, 2), lev, m_crse_ratio);
+ } else if ( m_varnames[comp] == "rho" ){
+ // rho_new is stored in component 1 of rho_fp when using PSATD
+#ifdef WARPX_USE_PSATD
+ amrex::MultiFab* rho_new = new amrex::MultiFab(*warpx.get_pointer_rho_fp(lev), amrex::make_alias, 1, 1);
+ m_cell_center_functors[lev][comp] = std::make_unique<CellCenterFunctor>(rho_new, lev, m_crse_ratio);
+#else
+ m_cell_center_functors[lev][comp] = std::make_unique<CellCenterFunctor>(warpx.get_pointer_rho_fp(lev), lev, m_crse_ratio);
+#endif
+ }
+ }
+
}
// Temporary function only to debug the current implementation.
@@ -197,9 +354,30 @@ BTDiagnostics::TMP_createLabFrameDirectories(int i_buffer, int lev)
void
BTDiagnostics::PrepareFieldDataForOutput ()
{
+ auto & warpx = WarpX::GetInstance();
// In this function, we will get cell-centered data for every level, lev,
// using the cell-center functors and their respective opeators()
// Call m_cell_center_functors->operator
+ for (int lev = 0; lev < nmax_lev; ++lev) {
+ int icomp_dst = 0;
+ for (int icomp = 0, n=m_cell_center_functors[0].size(); icomp<n; ++icomp) {
+ // Call all the cell-center functors in m_cell_center_functors.
+ // Each of them computes cell-centered data for a field and
+ // stores it in cell-centered MultiFab, m_cell_centered_data[lev].
+ m_cell_center_functors[lev][icomp]->operator()(*m_cell_centered_data[lev], icomp_dst);
+ icomp_dst += m_cell_center_functors[lev][icomp]->nComp();
+ }
+ // Check that the proper number of user-requested components are cell-centered
+ AMREX_ALWAYS_ASSERT( icomp_dst == m_varnames.size() );
+ // fill boundary call is required to average_down (flatten) data to
+ // the coarsest level.
+ m_cell_centered_data[lev]->FillBoundary(warpx.Geom(lev).periodicity() );
+ }
+ // Flattening out MF over levels
+
+ for (int lev = warpx.finestLevel(); lev > 0; --lev) {
+ CoarsenIO::Coarsen( *m_cell_centered_data[lev-1], *m_cell_centered_data[lev], 0, 0, m_varnames.size(), 0, WarpX::RefRatio(lev-1) );
+ }
}
diff --git a/Source/Diagnostics/ComputeDiagFunctors/BackTransformFunctor.H b/Source/Diagnostics/ComputeDiagFunctors/BackTransformFunctor.H
index 6903c9e45..b8702e715 100644
--- a/Source/Diagnostics/ComputeDiagFunctors/BackTransformFunctor.H
+++ b/Source/Diagnostics/ComputeDiagFunctors/BackTransformFunctor.H
@@ -33,8 +33,9 @@ public:
// initializing crse_ratio with 1, to accurately initialize ComputeDiagFunctor
BackTransformFunctor( const amrex::MultiFab * const mf_src, const int lev,
- const int ncomp, amrex::IntVect crse_ratio= amrex::IntVect(1));
+ const int ncomp, const amrex::IntVect crse_ratio= amrex::IntVect(1));
+ void operator()(amrex::MultiFab& mf_dst, int dcomp) const override {};
private:
/** pointer to source multifab (cell-centered multi-component multifab) */
amrex::MultiFab const * const m_mf_src = nullptr;
diff --git a/Source/Diagnostics/ComputeDiagFunctors/BackTransformFunctor.cpp b/Source/Diagnostics/ComputeDiagFunctors/BackTransformFunctor.cpp
index 5b049a112..2d8651efe 100644
--- a/Source/Diagnostics/ComputeDiagFunctors/BackTransformFunctor.cpp
+++ b/Source/Diagnostics/ComputeDiagFunctors/BackTransformFunctor.cpp
@@ -1,7 +1,7 @@
#include "BackTransformFunctor.H"
BackTransformFunctor::BackTransformFunctor(amrex::MultiFab const * mf_src, int lev,
- int ncomp, amrex::IntVect crse_ratio)
+ const int ncomp, const amrex::IntVect crse_ratio)
: ComputeDiagFunctor(ncomp, crse_ratio), m_mf_src(mf_src), m_lev(lev)
{
// Get the right slice of each field in the CC MultiFab, transform it and store it in the output.