aboutsummaryrefslogtreecommitdiff
path: root/Source/Particles/MultiParticleContainer.cpp
diff options
context:
space:
mode:
authorGravatar NeilZaim <49716072+NeilZaim@users.noreply.github.com> 2020-12-01 20:41:00 +0100
committerGravatar GitHub <noreply@github.com> 2020-12-01 11:41:00 -0800
commite044430eb54cea9c2b8fb9ccfb6d54d1976ab4c8 (patch)
tree0db1046ca0acf928704074dbacc5d86465c0d23b /Source/Particles/MultiParticleContainer.cpp
parent89c371557a9ff271a35ec337046757a2d18f71b5 (diff)
downloadWarpX-e044430eb54cea9c2b8fb9ccfb6d54d1976ab4c8.tar.gz
WarpX-e044430eb54cea9c2b8fb9ccfb6d54d1976ab4c8.tar.zst
WarpX-e044430eb54cea9c2b8fb9ccfb6d54d1976ab4c8.zip
Add the possibility to disable Schwinger in part of the domain (#1524)
* Add the possibility to disable Schwinger in part of the domain * Update checksum benchmarks * Only query ymin and ymax in 3D
Diffstat (limited to 'Source/Particles/MultiParticleContainer.cpp')
-rw-r--r--Source/Particles/MultiParticleContainer.cpp86
1 files changed, 82 insertions, 4 deletions
diff --git a/Source/Particles/MultiParticleContainer.cpp b/Source/Particles/MultiParticleContainer.cpp
index 2b1f310b0..1f9bb8337 100644
--- a/Source/Particles/MultiParticleContainer.cpp
+++ b/Source/Particles/MultiParticleContainer.cpp
@@ -277,8 +277,15 @@ MultiParticleContainer::ReadParameters ()
#if (AMREX_SPACEDIM == 2)
ppq.get("y_size",m_qed_schwinger_y_size);
#endif
- ppq.query("threshold_poisson_gaussian",
- m_qed_schwinger_threshold_poisson_gaussian);
+ ppq.query("threshold_poisson_gaussian", m_qed_schwinger_threshold_poisson_gaussian);
+ ppq.query("xmin", m_qed_schwinger_xmin);
+ ppq.query("xmax", m_qed_schwinger_xmax);
+#if (AMREX_SPACEDIM == 3)
+ ppq.query("ymin", m_qed_schwinger_ymin);
+ ppq.query("ymax", m_qed_schwinger_ymax);
+#endif
+ ppq.query("zmin", m_qed_schwinger_zmin);
+ ppq.query("zmax", m_qed_schwinger_zmax);
}
#endif
initialized = true;
@@ -1099,7 +1106,7 @@ MultiParticleContainer::doQEDSchwinger ()
"ERROR: Schwinger process only implemented for warpx.do_nodal = 1"
"or algo.field_gathering = momentum-conserving");
- const int level_0 = 0;
+ constexpr int level_0 = 0;
AMREX_ALWAYS_ASSERT_WITH_MESSAGE(warpx.maxLevel() == level_0,
"ERROR: Schwinger process not implemented with mesh refinement");
@@ -1143,7 +1150,15 @@ MultiParticleContainer::doQEDSchwinger ()
for (MFIter mfi(Ex, TilingIfNotGPU()); mfi.isValid(); ++mfi )
{
// Make the box cell centered to avoid creating particles twice on the tile edges
- const Box& box = enclosedCells(mfi.nodaltilebox());
+ amrex::Box box = enclosedCells(mfi.nodaltilebox());
+
+ // Get the box representing global Schwinger boundaries
+ const amrex::Box global_schwinger_box = ComputeSchwingerGlobalBox();
+
+ // If Schwinger process is not activated anywhere in the current box, we move to the next
+ // one. Otherwise we use the intersection of current box with global Schwinger box.
+ if (!box.intersects(global_schwinger_box)) {continue;}
+ box &= global_schwinger_box;
const auto& arrEx = Ex[mfi].array();
const auto& arrEy = Ey[mfi].array();
@@ -1184,6 +1199,69 @@ MultiParticleContainer::doQEDSchwinger ()
}
}
+amrex::Box
+MultiParticleContainer::ComputeSchwingerGlobalBox () const
+{
+ auto & warpx = WarpX::GetInstance();
+ constexpr int level_0 = 0;
+ amrex::Geometry const & geom = warpx.Geom(level_0);
+
+#if (AMREX_SPACEDIM == 3)
+ const amrex::Array<amrex::Real,3> schwinger_min{m_qed_schwinger_xmin,
+ m_qed_schwinger_ymin,
+ m_qed_schwinger_zmin};
+ const amrex::Array<amrex::Real,3> schwinger_max{m_qed_schwinger_xmax,
+ m_qed_schwinger_ymax,
+ m_qed_schwinger_zmax};
+#else
+ const amrex::Array<amrex::Real,2> schwinger_min{m_qed_schwinger_xmin,
+ m_qed_schwinger_zmin};
+ const amrex::Array<amrex::Real,2> schwinger_max{m_qed_schwinger_xmax,
+ m_qed_schwinger_zmax};
+#endif
+
+ // Box inside which Schwinger is activated
+ amrex::Box schwinger_global_box;
+
+ for (int dir=0; dir<AMREX_SPACEDIM; dir++)
+ {
+ // Dealing with these corner cases should ensure that we don't overflow on the integers
+ if (schwinger_min[dir] < geom.ProbLo(dir))
+ {
+ schwinger_global_box.setSmall(dir, std::numeric_limits<int>::lowest());
+ }
+ else if (schwinger_min[dir] > geom.ProbHi(dir))
+ {
+ schwinger_global_box.setSmall(dir, std::numeric_limits<int>::max());
+ }
+ else
+ {
+ // Schwinger pairs are currently created on the lower nodes of a cell. Using ceil here
+ // excludes all cells whose lower node is strictly lower than schwinger_min[dir].
+ schwinger_global_box.setSmall(dir, static_cast<int>(std::ceil(
+ (schwinger_min[dir] - geom.ProbLo(dir)) / geom.CellSize(dir))));
+ }
+
+ if (schwinger_max[dir] < geom.ProbLo(dir))
+ {
+ schwinger_global_box.setBig(dir, std::numeric_limits<int>::lowest());
+ }
+ else if (schwinger_max[dir] > geom.ProbHi(dir))
+ {
+ schwinger_global_box.setBig(dir, std::numeric_limits<int>::max());
+ }
+ else
+ {
+ // Schwinger pairs are currently created on the lower nodes of a cell. Using floor here
+ // excludes all cells whose lower node is strictly higher than schwinger_max[dir].
+ schwinger_global_box.setBig(dir, static_cast<int>(std::floor(
+ (schwinger_max[dir] - geom.ProbLo(dir)) / geom.CellSize(dir))));
+ }
+ }
+
+ return schwinger_global_box;
+}
+
void MultiParticleContainer::doQedEvents (int lev,
const MultiFab& Ex,
const MultiFab& Ey,