aboutsummaryrefslogtreecommitdiff
path: root/Source/WarpX.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WarpX.cpp')
-rw-r--r--Source/WarpX.cpp185
1 files changed, 133 insertions, 52 deletions
diff --git a/Source/WarpX.cpp b/Source/WarpX.cpp
index b425fba19..377d103d1 100644
--- a/Source/WarpX.cpp
+++ b/Source/WarpX.cpp
@@ -24,7 +24,11 @@
using namespace amrex;
-Vector<Real> WarpX::B_external(3, 0.0);
+Vector<Real> WarpX::B_external_particle(3, 0.0);
+Vector<Real> WarpX::E_external_particle(3, 0.0);
+
+Vector<Real> WarpX::E_external_grid(3, 0.0);
+Vector<Real> WarpX::B_external_grid(3, 0.0);
int WarpX::do_moving_window = 0;
int WarpX::moving_window_dir = -1;
@@ -60,12 +64,16 @@ int WarpX::num_mirrors = 0;
int WarpX::sort_int = -1;
-bool WarpX::do_boosted_frame_diagnostic = false;
+bool WarpX::do_back_transformed_diagnostics = false;
std::string WarpX::lab_data_directory = "lab_frame_data";
int WarpX::num_snapshots_lab = std::numeric_limits<int>::lowest();
Real WarpX::dt_snapshots_lab = std::numeric_limits<Real>::lowest();
-bool WarpX::do_boosted_frame_fields = true;
-bool WarpX::do_boosted_frame_particles = true;
+bool WarpX::do_back_transformed_fields = true;
+bool WarpX::do_back_transformed_particles = true;
+
+int WarpX::num_slice_snapshots_lab = 0;
+Real WarpX::dt_slice_snapshots_lab;
+Real WarpX::particle_slice_width_lab = 0.0;
bool WarpX::do_dynamic_scheduling = true;
@@ -76,9 +84,9 @@ IntVect WarpX::Bx_nodal_flag(1,0,0);
IntVect WarpX::By_nodal_flag(0,1,0);
IntVect WarpX::Bz_nodal_flag(0,0,1);
#elif (AMREX_SPACEDIM == 2)
-IntVect WarpX::Bx_nodal_flag(1,0); // x is the first dimension to AMReX
-IntVect WarpX::By_nodal_flag(0,0); // y is the missing dimension to 2D AMReX
-IntVect WarpX::Bz_nodal_flag(0,1); // z is the second dimension to 2D AMReX
+IntVect WarpX::Bx_nodal_flag(1,0);// x is the first dimension to AMReX
+IntVect WarpX::By_nodal_flag(0,0);// y is the missing dimension to 2D AMReX
+IntVect WarpX::Bz_nodal_flag(0,1);// z is the second dimension to 2D AMReX
#endif
#if (AMREX_SPACEDIM == 3)
@@ -86,9 +94,9 @@ IntVect WarpX::Ex_nodal_flag(0,1,1);
IntVect WarpX::Ey_nodal_flag(1,0,1);
IntVect WarpX::Ez_nodal_flag(1,1,0);
#elif (AMREX_SPACEDIM == 2)
-IntVect WarpX::Ex_nodal_flag(0,1); // x is the first dimension to AMReX
-IntVect WarpX::Ey_nodal_flag(1,1); // y is the missing dimension to 2D AMReX
-IntVect WarpX::Ez_nodal_flag(1,0); // z is the second dimension to 2D AMReX
+IntVect WarpX::Ex_nodal_flag(0,1);// x is the first dimension to AMReX
+IntVect WarpX::Ey_nodal_flag(1,1);// y is the missing dimension to 2D AMReX
+IntVect WarpX::Ez_nodal_flag(1,0);// z is the second dimension to 2D AMReX
#endif
#if (AMREX_SPACEDIM == 3)
@@ -96,9 +104,9 @@ IntVect WarpX::jx_nodal_flag(0,1,1);
IntVect WarpX::jy_nodal_flag(1,0,1);
IntVect WarpX::jz_nodal_flag(1,1,0);
#elif (AMREX_SPACEDIM == 2)
-IntVect WarpX::jx_nodal_flag(0,1); // x is the first dimension to AMReX
-IntVect WarpX::jy_nodal_flag(1,1); // y is the missing dimension to 2D AMReX
-IntVect WarpX::jz_nodal_flag(1,0); // z is the second dimension to 2D AMReX
+IntVect WarpX::jx_nodal_flag(0,1);// x is the first dimension to AMReX
+IntVect WarpX::jy_nodal_flag(1,1);// y is the missing dimension to 2D AMReX
+IntVect WarpX::jz_nodal_flag(1,0);// z is the second dimension to 2D AMReX
#endif
IntVect WarpX::filter_npass_each_dir(1);
@@ -168,7 +176,7 @@ WarpX::WarpX ()
current_injection_position = geom[0].ProbLo(moving_window_dir);
}
}
- do_boosted_frame_particles = mypc->doBoostedFrameDiags();
+ do_back_transformed_particles = mypc->doBackTransformedDiagnostics();
Efield_aux.resize(nlevs_max);
Bfield_aux.resize(nlevs_max);
@@ -261,13 +269,13 @@ void
WarpX::ReadParameters ()
{
{
- ParmParse pp; // Traditionally, max_step and stop_time do not have prefix.
+ ParmParse pp;// Traditionally, max_step and stop_time do not have prefix.
pp.query("max_step", max_step);
pp.query("stop_time", stop_time);
}
{
- ParmParse pp("amr"); // Traditionally, these have prefix, amr.
+ ParmParse pp("amr");// Traditionally, these have prefix, amr.
pp.query("check_file", check_file);
pp.query("check_int", check_int);
@@ -298,7 +306,11 @@ WarpX::ReadParameters ()
pp.query("zmax_plasma_to_compute_max_step",
zmax_plasma_to_compute_max_step);
- pp.queryarr("B_external", B_external);
+ pp.queryarr("B_external_particle", B_external_particle);
+ pp.queryarr("E_external_particle", E_external_particle);
+
+ pp.queryarr("E_external_grid", E_external_grid);
+ pp.queryarr("B_external_grid", B_external_grid);
pp.query("do_moving_window", do_moving_window);
if (do_moving_window)
@@ -321,14 +333,17 @@ WarpX::ReadParameters ()
amrex::Abort(msg.c_str());
}
+ AMREX_ALWAYS_ASSERT_WITH_MESSAGE(Geom(0).isPeriodic(moving_window_dir) == 0,
+ "The problem must be non-periodic in the moving window direction");
+
moving_window_x = geom[0].ProbLo(moving_window_dir);
pp.get("moving_window_v", moving_window_v);
moving_window_v *= PhysConst::c;
}
- pp.query("do_boosted_frame_diagnostic", do_boosted_frame_diagnostic);
- if (do_boosted_frame_diagnostic) {
+ pp.query("do_back_transformed_diagnostics", do_back_transformed_diagnostics);
+ if (do_back_transformed_diagnostics) {
AMREX_ALWAYS_ASSERT_WITH_MESSAGE(gamma_boost > 1.0,
"gamma_boost must be > 1 to use the boosted frame diagnostic.");
@@ -356,7 +371,7 @@ WarpX::ReadParameters ()
pp.get("gamma_boost", gamma_boost);
- pp.query("do_boosted_frame_fields", do_boosted_frame_fields);
+ pp.query("do_back_transformed_fields", do_back_transformed_fields);
AMREX_ALWAYS_ASSERT_WITH_MESSAGE(do_moving_window,
"The moving window should be on if using the boosted frame diagnostic.");
@@ -372,7 +387,7 @@ WarpX::ReadParameters ()
// Read filter and fill IntVect filter_npass_each_dir with
// proper size for AMREX_SPACEDIM
- pp.query("use_filter", use_filter);
+ pp.query("use_filter", use_filter);
Vector<int> parse_filter_npass_each_dir(AMREX_SPACEDIM,1);
pp.queryarr("filter_npass_each_dir", parse_filter_npass_each_dir);
filter_npass_each_dir[0] = parse_filter_npass_each_dir[0];
@@ -430,6 +445,7 @@ WarpX::ReadParameters ()
pp.query("openpmd_tspf", openpmd_tspf);
#endif
pp.query("dump_plotfiles", dump_plotfiles);
+ pp.query("plot_costs", plot_costs);
pp.query("plot_raw_fields", plot_raw_fields);
pp.query("plot_raw_fields_guards", plot_raw_fields_guards);
pp.query("plot_coarsening_ratio", plot_coarsening_ratio);
@@ -547,9 +563,13 @@ WarpX::ReadParameters ()
ParmParse pp("algo");
current_deposition_algo = GetAlgorithmInteger(pp, "current_deposition");
charge_deposition_algo = GetAlgorithmInteger(pp, "charge_deposition");
- field_gathering_algo = GetAlgorithmInteger(pp, "field_gathering");
particle_pusher_algo = GetAlgorithmInteger(pp, "particle_pusher");
maxwell_fdtd_solver_id = GetAlgorithmInteger(pp, "maxwell_fdtd_solver");
+ field_gathering_algo = GetAlgorithmInteger(pp, "field_gathering");
+ if (field_gathering_algo == GatheringAlgo::MomentumConserving) {
+ // Use same shape factors in all directions, for gathering
+ l_lower_order_in_v = false;
+ }
}
#ifdef WARPX_USE_PSATD
@@ -602,6 +622,16 @@ WarpX::ReadParameters ()
}
}
+ if (do_back_transformed_diagnostics) {
+ AMREX_ALWAYS_ASSERT_WITH_MESSAGE(gamma_boost > 1.0,
+ "gamma_boost must be > 1 to use the boost frame diagnostic");
+ pp.query("num_slice_snapshots_lab", num_slice_snapshots_lab);
+ if (num_slice_snapshots_lab > 0) {
+ pp.get("dt_slice_snapshots_lab", dt_slice_snapshots_lab );
+ pp.get("particle_slice_width_lab",particle_slice_width_lab);
+ }
+ }
+
}
}
@@ -808,16 +838,19 @@ WarpX::AllocLevelMFs (int lev, const BoxArray& ba, const DistributionMapping& dm
ncomps = n_rz_azimuthal_modes*2 - 1;
#endif
+ bool aux_is_nodal = (field_gathering_algo == GatheringAlgo::MomentumConserving);
+ IntVect ngextra(static_cast<int>(aux_is_nodal and !do_nodal));
+
//
// The fine patch
//
- Bfield_fp[lev][0].reset( new MultiFab(amrex::convert(ba,Bx_nodal_flag),dm,ncomps,ngE));
- Bfield_fp[lev][1].reset( new MultiFab(amrex::convert(ba,By_nodal_flag),dm,ncomps,ngE));
- Bfield_fp[lev][2].reset( new MultiFab(amrex::convert(ba,Bz_nodal_flag),dm,ncomps,ngE));
+ Bfield_fp[lev][0].reset( new MultiFab(amrex::convert(ba,Bx_nodal_flag),dm,ncomps,ngE+ngextra));
+ Bfield_fp[lev][1].reset( new MultiFab(amrex::convert(ba,By_nodal_flag),dm,ncomps,ngE+ngextra));
+ Bfield_fp[lev][2].reset( new MultiFab(amrex::convert(ba,Bz_nodal_flag),dm,ncomps,ngE+ngextra));
- Efield_fp[lev][0].reset( new MultiFab(amrex::convert(ba,Ex_nodal_flag),dm,ncomps,ngE));
- Efield_fp[lev][1].reset( new MultiFab(amrex::convert(ba,Ey_nodal_flag),dm,ncomps,ngE));
- Efield_fp[lev][2].reset( new MultiFab(amrex::convert(ba,Ez_nodal_flag),dm,ncomps,ngE));
+ Efield_fp[lev][0].reset( new MultiFab(amrex::convert(ba,Ex_nodal_flag),dm,ncomps,ngE+ngextra));
+ Efield_fp[lev][1].reset( new MultiFab(amrex::convert(ba,Ey_nodal_flag),dm,ncomps,ngE+ngextra));
+ Efield_fp[lev][2].reset( new MultiFab(amrex::convert(ba,Ez_nodal_flag),dm,ncomps,ngE+ngextra));
current_fp[lev][0].reset( new MultiFab(amrex::convert(ba,jx_nodal_flag),dm,ncomps,ngJ));
current_fp[lev][1].reset( new MultiFab(amrex::convert(ba,jy_nodal_flag),dm,ncomps,ngJ));
@@ -864,7 +897,19 @@ WarpX::AllocLevelMFs (int lev, const BoxArray& ba, const DistributionMapping& dm
//
// The Aux patch (i.e., the full solution)
//
- if (lev == 0)
+ if (aux_is_nodal and !do_nodal)
+ {
+ // Create aux multifabs on Nodal Box Array
+ BoxArray const nba = amrex::convert(ba,IntVect::TheNodeVector());
+ Bfield_aux[lev][0].reset( new MultiFab(nba,dm,ncomps,ngE));
+ Bfield_aux[lev][1].reset( new MultiFab(nba,dm,ncomps,ngE));
+ Bfield_aux[lev][2].reset( new MultiFab(nba,dm,ncomps,ngE));
+
+ Efield_aux[lev][0].reset( new MultiFab(nba,dm,ncomps,ngE));
+ Efield_aux[lev][1].reset( new MultiFab(nba,dm,ncomps,ngE));
+ Efield_aux[lev][2].reset( new MultiFab(nba,dm,ncomps,ngE));
+ }
+ else if (lev == 0)
{
for (int idir = 0; idir < 3; ++idir) {
Efield_aux[lev][idir].reset(new MultiFab(*Efield_fp[lev][idir], amrex::make_alias, 0, ncomps));
@@ -926,8 +971,8 @@ WarpX::AllocLevelMFs (int lev, const BoxArray& ba, const DistributionMapping& dm
RealVect cdx_vect(cdx[0], cdx[2]);
#endif
// Get the cell-centered box, with guard cells
- BoxArray realspace_ba = cba; // Copy box
- realspace_ba.enclosedCells().grow(ngE); // cell-centered + guard cells
+ BoxArray realspace_ba = cba;// Copy box
+ realspace_ba.enclosedCells().grow(ngE);// cell-centered + guard cells
// Define spectral solver
spectral_solver_cp[lev].reset( new SpectralSolver( realspace_ba, dm,
nox_fft, noy_fft, noz_fft, do_nodal, cdx_vect, dt[lev] ) );
@@ -945,15 +990,25 @@ WarpX::AllocLevelMFs (int lev, const BoxArray& ba, const DistributionMapping& dm
cba.coarsen(refRatio(lev-1));
if (n_field_gather_buffer > 0 || mypc->nSpeciesGatherFromMainGrid() > 0) {
- // Create the MultiFabs for B
- Bfield_cax[lev][0].reset( new MultiFab(amrex::convert(cba,Bx_nodal_flag),dm,ncomps,ngE));
- Bfield_cax[lev][1].reset( new MultiFab(amrex::convert(cba,By_nodal_flag),dm,ncomps,ngE));
- Bfield_cax[lev][2].reset( new MultiFab(amrex::convert(cba,Bz_nodal_flag),dm,ncomps,ngE));
-
- // Create the MultiFabs for E
- Efield_cax[lev][0].reset( new MultiFab(amrex::convert(cba,Ex_nodal_flag),dm,ncomps,ngE));
- Efield_cax[lev][1].reset( new MultiFab(amrex::convert(cba,Ey_nodal_flag),dm,ncomps,ngE));
- Efield_cax[lev][2].reset( new MultiFab(amrex::convert(cba,Ez_nodal_flag),dm,ncomps,ngE));
+ if (aux_is_nodal) {
+ BoxArray const& cnba = amrex::convert(cba,IntVect::TheNodeVector());
+ Bfield_cax[lev][0].reset( new MultiFab(cnba,dm,ncomps,ngE));
+ Bfield_cax[lev][1].reset( new MultiFab(cnba,dm,ncomps,ngE));
+ Bfield_cax[lev][2].reset( new MultiFab(cnba,dm,ncomps,ngE));
+ Efield_cax[lev][0].reset( new MultiFab(cnba,dm,ncomps,ngE));
+ Efield_cax[lev][1].reset( new MultiFab(cnba,dm,ncomps,ngE));
+ Efield_cax[lev][2].reset( new MultiFab(cnba,dm,ncomps,ngE));
+ } else {
+ // Create the MultiFabs for B
+ Bfield_cax[lev][0].reset( new MultiFab(amrex::convert(cba,Bx_nodal_flag),dm,ncomps,ngE));
+ Bfield_cax[lev][1].reset( new MultiFab(amrex::convert(cba,By_nodal_flag),dm,ncomps,ngE));
+ Bfield_cax[lev][2].reset( new MultiFab(amrex::convert(cba,Bz_nodal_flag),dm,ncomps,ngE));
+
+ // Create the MultiFabs for E
+ Efield_cax[lev][0].reset( new MultiFab(amrex::convert(cba,Ex_nodal_flag),dm,ncomps,ngE));
+ Efield_cax[lev][1].reset( new MultiFab(amrex::convert(cba,Ey_nodal_flag),dm,ncomps,ngE));
+ Efield_cax[lev][2].reset( new MultiFab(amrex::convert(cba,Ez_nodal_flag),dm,ncomps,ngE));
+ }
gather_buffer_masks[lev].reset( new iMultiFab(ba, dm, ncomps, 1) );
// Gather buffer masks have 1 ghost cell, because of the fact
@@ -1024,6 +1079,21 @@ WarpX::UpperCorner(const Box& bx, int lev)
#endif
}
+std::array<Real,3>
+WarpX::LowerCornerWithCentering(const Box& bx, int lev)
+{
+ std::array<Real,3> corner = LowerCorner(bx, lev);
+ std::array<Real,3> dx = CellSize(lev);
+ if (!bx.type(0)) corner[0] += 0.5*dx[0];
+#if (AMREX_SPACEDIM == 3)
+ if (!bx.type(1)) corner[1] += 0.5*dx[1];
+ if (!bx.type(2)) corner[2] += 0.5*dx[2];
+#else
+ if (!bx.type(1)) corner[2] += 0.5*dx[2];
+#endif
+ return corner;
+}
+
IntVect
WarpX::RefRatio (int lev)
{
@@ -1046,9 +1116,9 @@ WarpX::Evolve (int numsteps) {
}
void
-WarpX::ComputeDivB (MultiFab& divB, int dcomp,
- const std::array<const MultiFab*, 3>& B,
- const std::array<Real,3>& dx)
+WarpX::ComputeDivB (amrex::MultiFab& divB, int dcomp,
+ const std::array<const amrex::MultiFab*, 3>& B,
+ const std::array<amrex::Real,3>& dx)
{
Real dxinv = 1./dx[0], dyinv = 1./dx[1], dzinv = 1./dx[2];
@@ -1080,9 +1150,9 @@ WarpX::ComputeDivB (MultiFab& divB, int dcomp,
}
void
-WarpX::ComputeDivB (MultiFab& divB, int dcomp,
- const std::array<const MultiFab*, 3>& B,
- const std::array<Real,3>& dx, int ngrow)
+WarpX::ComputeDivB (amrex::MultiFab& divB, int dcomp,
+ const std::array<const amrex::MultiFab*, 3>& B,
+ const std::array<amrex::Real,3>& dx, int ngrow)
{
Real dxinv = 1./dx[0], dyinv = 1./dx[1], dzinv = 1./dx[2];
@@ -1114,9 +1184,9 @@ WarpX::ComputeDivB (MultiFab& divB, int dcomp,
}
void
-WarpX::ComputeDivE (MultiFab& divE, int dcomp,
- const std::array<const MultiFab*, 3>& E,
- const std::array<Real,3>& dx)
+WarpX::ComputeDivE (amrex::MultiFab& divE, int dcomp,
+ const std::array<const amrex::MultiFab*, 3>& E,
+ const std::array<amrex::Real,3>& dx)
{
Real dxinv = 1./dx[0], dyinv = 1./dx[1], dzinv = 1./dx[2];
@@ -1148,9 +1218,9 @@ WarpX::ComputeDivE (MultiFab& divE, int dcomp,
}
void
-WarpX::ComputeDivE (MultiFab& divE, int dcomp,
- const std::array<const MultiFab*, 3>& E,
- const std::array<Real,3>& dx, int ngrow)
+WarpX::ComputeDivE (amrex::MultiFab& divE, int dcomp,
+ const std::array<const amrex::MultiFab*, 3>& E,
+ const std::array<amrex::Real,3>& dx, int ngrow)
{
Real dxinv = 1./dx[0], dyinv = 1./dx[1], dzinv = 1./dx[2];
@@ -1181,6 +1251,17 @@ WarpX::ComputeDivE (MultiFab& divE, int dcomp,
}
}
+PML*
+WarpX::GetPML (int lev)
+{
+ if (do_pml) {
+ // This should check if pml was initialized
+ return pml[lev].get();
+ } else {
+ return nullptr;
+ }
+}
+
void
WarpX::BuildBufferMasks ()
{