From eef12e96149b80f92600654c52994a230658b199 Mon Sep 17 00:00:00 2001 From: Brian Naranjo Date: Sat, 28 Sep 2024 07:37:38 -0700 Subject: [PATCH] General moving-window transformations in boosted-frame simulations (#5226) * General moving-window transformations in boosted-frame simulations * Default speed of moving window to speed of boosted frame * Extend simulation volume enough so that particles don't exit * Include moving window speed in diag_lo and diag_hi transformations * Modify bounds so as to produce the same results as in previous versions --------- Co-authored-by: Remi Lehe --- ...uts_test_3d_hard_edged_quadrupoles_boosted | 4 +- .../inputs_test_3d_plasma_lens_boosted | 4 +- ...est_3d_hard_edged_quadrupoles_boosted.json | 34 +++++++------- .../test_3d_plasma_lens_boosted.json | 32 +++++++------- Source/Diagnostics/Diagnostics.cpp | 5 ++- Source/Utils/WarpXUtil.H | 4 ++ Source/Utils/WarpXUtil.cpp | 44 ++++++++++++++++++- Source/WarpX.cpp | 43 ++++-------------- 8 files changed, 94 insertions(+), 76 deletions(-) diff --git a/Examples/Tests/accelerator_lattice/inputs_test_3d_hard_edged_quadrupoles_boosted b/Examples/Tests/accelerator_lattice/inputs_test_3d_hard_edged_quadrupoles_boosted index 668ec73d2dd..c056ff1fc66 100644 --- a/Examples/Tests/accelerator_lattice/inputs_test_3d_hard_edged_quadrupoles_boosted +++ b/Examples/Tests/accelerator_lattice/inputs_test_3d_hard_edged_quadrupoles_boosted @@ -2,8 +2,8 @@ max_step = 50 amr.n_cell = 16 16 8 amr.max_level = 0 geometry.dims = 3 -geometry.prob_lo = -0.2 -0.2 -0.1 -geometry.prob_hi = +0.2 +0.2 +0.1 +geometry.prob_lo = -0.2 -0.2 -0.1866 +geometry.prob_hi = +0.2 +0.2 +0.1866 # Boundary condition boundary.field_lo = pec pec pec diff --git a/Examples/Tests/plasma_lens/inputs_test_3d_plasma_lens_boosted b/Examples/Tests/plasma_lens/inputs_test_3d_plasma_lens_boosted index fa18ac439c4..b00779bae65 100644 --- a/Examples/Tests/plasma_lens/inputs_test_3d_plasma_lens_boosted +++ b/Examples/Tests/plasma_lens/inputs_test_3d_plasma_lens_boosted @@ -8,8 +8,8 @@ amr.max_level = 0 # Geometry geometry.dims = 3 -geometry.prob_lo = -1.0 -1.0 -1.0 # physical domain -geometry.prob_hi = 1.0 1.0 2.0 +geometry.prob_lo = -1.0 -1.0 -1.866 # physical domain +geometry.prob_hi = 1.0 1.0 3.732 boundary.field_lo = pec pec pec boundary.field_hi = pec pec pec diff --git a/Regression/Checksum/benchmarks_json/test_3d_hard_edged_quadrupoles_boosted.json b/Regression/Checksum/benchmarks_json/test_3d_hard_edged_quadrupoles_boosted.json index acec34286f7..0a601b7b437 100644 --- a/Regression/Checksum/benchmarks_json/test_3d_hard_edged_quadrupoles_boosted.json +++ b/Regression/Checksum/benchmarks_json/test_3d_hard_edged_quadrupoles_boosted.json @@ -1,22 +1,22 @@ { + "lev=0": { + "Bx": 3.254604354043409e-14, + "By": 3.2768679907552955e-14, + "Bz": 1.0615351421410278e-16, + "Ex": 2.3084916770539354e-05, + "Ey": 2.2657235922655432e-05, + "Ez": 1.9978004351148e-05, + "jx": 1.781971994166362e-10, + "jy": 4.2163624424546344e-20, + "jz": 1.0378980680353126e-07 + }, "electron": { - "particle_momentum_x": 5.955475926588059e-26, - "particle_momentum_y": 1.4612764777454504e-35, - "particle_momentum_z": 3.4687284535374423e-23, - "particle_position_x": 0.049960237123814574, - "particle_position_y": 8.397636119991403e-15, - "particle_position_z": 0.10931687737912647, + "particle_momentum_x": 5.955475927655105e-26, + "particle_momentum_y": 1.4613271542201658e-35, + "particle_momentum_z": 3.468728453537439e-23, + "particle_position_x": 0.04996023704063194, + "particle_position_y": 8.398113230295983e-15, + "particle_position_z": 0.10931682580470406, "particle_weight": 1.0 - }, - "lev=0": { - "Bx": 3.254531465641299e-14, - "By": 3.2768092409497234e-14, - "Bz": 1.0615286316115558e-16, - "Ex": 2.30845657253269e-05, - "Ey": 2.2656898931877975e-05, - "Ez": 1.997747654112569e-05, - "jx": 1.7819477343635878e-10, - "jy": 4.2163030523377745e-20, - "jz": 1.0378839382497739e-07 } } diff --git a/Regression/Checksum/benchmarks_json/test_3d_plasma_lens_boosted.json b/Regression/Checksum/benchmarks_json/test_3d_plasma_lens_boosted.json index 6d5eabb492e..e1fa54618ee 100644 --- a/Regression/Checksum/benchmarks_json/test_3d_plasma_lens_boosted.json +++ b/Regression/Checksum/benchmarks_json/test_3d_plasma_lens_boosted.json @@ -1,21 +1,21 @@ { "lev=0": { - "Bx": 1.3073041371012706e-14, - "By": 1.3033038210840872e-14, - "Bz": 5.595105968291083e-17, - "Ex": 2.801134785671445e-06, - "Ey": 2.8088613469887243e-06, - "Ez": 3.343430731047825e-06, - "jx": 2.5155716299904363e-11, - "jy": 2.013718424043256e-11, - "jz": 6.00631499206418e-09 + "Bx": 1.307357220398482e-14, + "By": 1.3033571630685163e-14, + "Bz": 5.594998319468307e-17, + "Ex": 2.8010832905044288e-06, + "Ey": 2.8088096742407935e-06, + "Ez": 3.3433681277560495e-06, + "jx": 2.5151718871714067e-11, + "jy": 2.013398608921663e-11, + "jz": 6.0063967622563335e-09 }, "electrons": { - "particle_momentum_x": 7.437088723328491e-24, - "particle_momentum_y": 5.9495056615288754e-24, - "particle_momentum_z": 5.117548636687908e-22, - "particle_position_x": 0.036489969262013186, - "particle_position_y": 0.029201200231260247, - "particle_position_z": 6.9681085285694095 + "particle_momentum_x": 7.43708887164806e-24, + "particle_momentum_y": 5.949505779760011e-24, + "particle_momentum_z": 5.117548636790359e-22, + "particle_position_x": 0.03648994812700447, + "particle_position_y": 0.029201183320618985, + "particle_position_z": 6.968107021318396 } -} +} \ No newline at end of file diff --git a/Source/Diagnostics/Diagnostics.cpp b/Source/Diagnostics/Diagnostics.cpp index dc28aeda095..fd079479285 100644 --- a/Source/Diagnostics/Diagnostics.cpp +++ b/Source/Diagnostics/Diagnostics.cpp @@ -229,8 +229,9 @@ Diagnostics::BaseReadParameters () if (WarpX::boost_direction[ dim_map[WarpX::moving_window_dir] ] == 1) { // Convert user-defined lo and hi for diagnostics to account for boosted-frame // simulations with moving window - const amrex::Real convert_factor = 1._rt/(WarpX::gamma_boost * (1._rt - WarpX::beta_boost) ); - // Assuming that the window travels with speed c + const amrex::Real beta_window = WarpX::moving_window_v / PhysConst::c; + const amrex::Real convert_factor = 1._rt/( + WarpX::gamma_boost * (1._rt - WarpX::beta_boost * beta_window) ); m_lo[WarpX::moving_window_dir] *= convert_factor; m_hi[WarpX::moving_window_dir] *= convert_factor; } diff --git a/Source/Utils/WarpXUtil.H b/Source/Utils/WarpXUtil.H index e35b0cdb313..46399b439d6 100644 --- a/Source/Utils/WarpXUtil.H +++ b/Source/Utils/WarpXUtil.H @@ -33,6 +33,10 @@ void ParseGeometryInput(); void ReadBoostedFrameParameters(amrex::Real& gamma_boost, amrex::Real& beta_boost, amrex::Vector& boost_direction); +void ReadMovingWindowParameters( + int& do_moving_window, int& start_moving_window_step, int& end_moving_window_step, + int& moving_window_dir, amrex::Real& moving_window_v); + void ConvertLabParamsToBoost(); /** diff --git a/Source/Utils/WarpXUtil.cpp b/Source/Utils/WarpXUtil.cpp index 856e021abb3..d6f465fa901 100644 --- a/Source/Utils/WarpXUtil.cpp +++ b/Source/Utils/WarpXUtil.cpp @@ -140,6 +140,43 @@ void ReadBoostedFrameParameters(Real& gamma_boost, Real& beta_boost, } } +void ReadMovingWindowParameters( + int& do_moving_window, int& start_moving_window_step, int& end_moving_window_step, + int& moving_window_dir, amrex::Real& moving_window_v) +{ + const ParmParse pp_warpx("warpx"); + pp_warpx.query("do_moving_window", do_moving_window); + if (do_moving_window) { + utils::parser::queryWithParser( + pp_warpx, "start_moving_window_step", start_moving_window_step); + utils::parser::queryWithParser( + pp_warpx, "end_moving_window_step", end_moving_window_step); + std::string s; + pp_warpx.get("moving_window_dir", s); + + if (s == "z" || s == "Z") { + moving_window_dir = WARPX_ZINDEX; + } +#if defined(WARPX_DIM_3D) + else if (s == "y" || s == "Y") { + moving_window_dir = 1; + } +#endif +#if defined(WARPX_DIM_XZ) || defined(WARPX_DIM_3D) + else if (s == "x" || s == "X") { + moving_window_dir = 0; + } +#endif + else { + WARPX_ABORT_WITH_MESSAGE("Unknown moving_window_dir: "+s); + } + + utils::parser::getWithParser( + pp_warpx, "moving_window_v", moving_window_v); + moving_window_v *= PhysConst::c; + } +} + void ConvertLabParamsToBoost() { Real gamma_boost = 1., beta_boost = 0.; @@ -196,8 +233,11 @@ void ConvertLabParamsToBoost() { if (boost_direction[dim_map[idim]]) { amrex::Real convert_factor; - // Assume that the window travels with speed +c - convert_factor = 1._rt/( gamma_boost * ( 1 - beta_boost ) ); + amrex::Real beta_window = beta_boost; + if (WarpX::do_moving_window && idim == WarpX::moving_window_dir) { + beta_window = WarpX::moving_window_v / PhysConst::c; + } + convert_factor = 1._rt/( gamma_boost * ( 1 - beta_boost * beta_window ) ); prob_lo[idim] *= convert_factor; prob_hi[idim] *= convert_factor; if (max_level > 0){ diff --git a/Source/WarpX.cpp b/Source/WarpX.cpp index 7f9288debb7..89254e05c98 100644 --- a/Source/WarpX.cpp +++ b/Source/WarpX.cpp @@ -200,6 +200,10 @@ void WarpX::MakeWarpX () { ParseGeometryInput(); + ReadMovingWindowParameters( + do_moving_window, start_moving_window_step, end_moving_window_step, + moving_window_dir, moving_window_v); + ConvertLabParamsToBoost(); ReadBCParams(); @@ -623,42 +627,11 @@ WarpX::ReadParameters () pp_warpx.query("compute_max_step_from_btd", compute_max_step_from_btd); - pp_warpx.query("do_moving_window", do_moving_window); - if (do_moving_window) - { - utils::parser::queryWithParser( - pp_warpx, "start_moving_window_step", start_moving_window_step); - utils::parser::queryWithParser( - pp_warpx, "end_moving_window_step", end_moving_window_step); - std::string s; - pp_warpx.get("moving_window_dir", s); - - if (s == "z" || s == "Z") { - moving_window_dir = WARPX_ZINDEX; - } -#if defined(WARPX_DIM_3D) - else if (s == "y" || s == "Y") { - moving_window_dir = 1; - } -#endif -#if defined(WARPX_DIM_XZ) || defined(WARPX_DIM_3D) - else if (s == "x" || s == "X") { - moving_window_dir = 0; - } -#endif - - else { - WARPX_ABORT_WITH_MESSAGE("Unknown moving_window_dir: "+s); - } - - WARPX_ALWAYS_ASSERT_WITH_MESSAGE(Geom(0).isPeriodic(moving_window_dir) == 0, - "The problem must be non-periodic in the moving window direction"); - + if (do_moving_window) { + WARPX_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); - - utils::parser::getWithParser( - pp_warpx, "moving_window_v", moving_window_v); - moving_window_v *= PhysConst::c; } m_p_ext_field_params = std::make_unique(pp_warpx);