@@ -277,8 +277,15 @@ MultiParticleContainer::ReadParameters ()
277277#if (AMREX_SPACEDIM == 2)
278278 ppq.get (" y_size" ,m_qed_schwinger_y_size);
279279#endif
280- ppq.query (" threshold_poisson_gaussian" ,
281- m_qed_schwinger_threshold_poisson_gaussian);
280+ ppq.query (" threshold_poisson_gaussian" , m_qed_schwinger_threshold_poisson_gaussian);
281+ ppq.query (" xmin" , m_qed_schwinger_xmin);
282+ ppq.query (" xmax" , m_qed_schwinger_xmax);
283+ #if (AMREX_SPACEDIM == 3)
284+ ppq.query (" ymin" , m_qed_schwinger_ymin);
285+ ppq.query (" ymax" , m_qed_schwinger_ymax);
286+ #endif
287+ ppq.query (" zmin" , m_qed_schwinger_zmin);
288+ ppq.query (" zmax" , m_qed_schwinger_zmax);
282289 }
283290#endif
284291 initialized = true ;
@@ -1099,7 +1106,7 @@ MultiParticleContainer::doQEDSchwinger ()
10991106 " ERROR: Schwinger process only implemented for warpx.do_nodal = 1"
11001107 " or algo.field_gathering = momentum-conserving" );
11011108
1102- const int level_0 = 0 ;
1109+ constexpr int level_0 = 0 ;
11031110
11041111 AMREX_ALWAYS_ASSERT_WITH_MESSAGE (warpx.maxLevel () == level_0,
11051112 " ERROR: Schwinger process not implemented with mesh refinement" );
@@ -1143,7 +1150,15 @@ MultiParticleContainer::doQEDSchwinger ()
11431150 for (MFIter mfi (Ex, TilingIfNotGPU ()); mfi.isValid (); ++mfi )
11441151 {
11451152 // Make the box cell centered to avoid creating particles twice on the tile edges
1146- const Box& box = enclosedCells (mfi.nodaltilebox ());
1153+ amrex::Box box = enclosedCells (mfi.nodaltilebox ());
1154+
1155+ // Get the box representing global Schwinger boundaries
1156+ const amrex::Box global_schwinger_box = ComputeSchwingerGlobalBox ();
1157+
1158+ // If Schwinger process is not activated anywhere in the current box, we move to the next
1159+ // one. Otherwise we use the intersection of current box with global Schwinger box.
1160+ if (!box.intersects (global_schwinger_box)) {continue ;}
1161+ box &= global_schwinger_box;
11471162
11481163 const auto & arrEx = Ex[mfi].array ();
11491164 const auto & arrEy = Ey[mfi].array ();
@@ -1184,6 +1199,69 @@ MultiParticleContainer::doQEDSchwinger ()
11841199 }
11851200}
11861201
1202+ amrex::Box
1203+ MultiParticleContainer::ComputeSchwingerGlobalBox () const
1204+ {
1205+ auto & warpx = WarpX::GetInstance ();
1206+ constexpr int level_0 = 0 ;
1207+ amrex::Geometry const & geom = warpx.Geom (level_0);
1208+
1209+ #if (AMREX_SPACEDIM == 3)
1210+ const amrex::Array<amrex::Real,3 > schwinger_min{m_qed_schwinger_xmin,
1211+ m_qed_schwinger_ymin,
1212+ m_qed_schwinger_zmin};
1213+ const amrex::Array<amrex::Real,3 > schwinger_max{m_qed_schwinger_xmax,
1214+ m_qed_schwinger_ymax,
1215+ m_qed_schwinger_zmax};
1216+ #else
1217+ const amrex::Array<amrex::Real,2 > schwinger_min{m_qed_schwinger_xmin,
1218+ m_qed_schwinger_zmin};
1219+ const amrex::Array<amrex::Real,2 > schwinger_max{m_qed_schwinger_xmax,
1220+ m_qed_schwinger_zmax};
1221+ #endif
1222+
1223+ // Box inside which Schwinger is activated
1224+ amrex::Box schwinger_global_box;
1225+
1226+ for (int dir=0 ; dir<AMREX_SPACEDIM; dir++)
1227+ {
1228+ // Dealing with these corner cases should ensure that we don't overflow on the integers
1229+ if (schwinger_min[dir] < geom.ProbLo (dir))
1230+ {
1231+ schwinger_global_box.setSmall (dir, std::numeric_limits<int >::lowest ());
1232+ }
1233+ else if (schwinger_min[dir] > geom.ProbHi (dir))
1234+ {
1235+ schwinger_global_box.setSmall (dir, std::numeric_limits<int >::max ());
1236+ }
1237+ else
1238+ {
1239+ // Schwinger pairs are currently created on the lower nodes of a cell. Using ceil here
1240+ // excludes all cells whose lower node is strictly lower than schwinger_min[dir].
1241+ schwinger_global_box.setSmall (dir, static_cast <int >(std::ceil (
1242+ (schwinger_min[dir] - geom.ProbLo (dir)) / geom.CellSize (dir))));
1243+ }
1244+
1245+ if (schwinger_max[dir] < geom.ProbLo (dir))
1246+ {
1247+ schwinger_global_box.setBig (dir, std::numeric_limits<int >::lowest ());
1248+ }
1249+ else if (schwinger_max[dir] > geom.ProbHi (dir))
1250+ {
1251+ schwinger_global_box.setBig (dir, std::numeric_limits<int >::max ());
1252+ }
1253+ else
1254+ {
1255+ // Schwinger pairs are currently created on the lower nodes of a cell. Using floor here
1256+ // excludes all cells whose lower node is strictly higher than schwinger_max[dir].
1257+ schwinger_global_box.setBig (dir, static_cast <int >(std::floor (
1258+ (schwinger_max[dir] - geom.ProbLo (dir)) / geom.CellSize (dir))));
1259+ }
1260+ }
1261+
1262+ return schwinger_global_box;
1263+ }
1264+
11871265void MultiParticleContainer::doQedEvents (int lev,
11881266 const MultiFab& Ex,
11891267 const MultiFab& Ey,
0 commit comments