aboutsummaryrefslogtreecommitdiff
path: root/Source/Particles/Sorting/Partition.cpp
diff options
context:
space:
mode:
authorGravatar Remi Lehe <remi.lehe@normalesup.org> 2019-09-23 16:24:57 -0700
committerGravatar Remi Lehe <remi.lehe@normalesup.org> 2019-09-23 16:24:57 -0700
commitb4c4315c77ade3ebb4b11e137ddfe354f1c95d23 (patch)
tree3467b5bf1867371dfa1ad3348a96d37f93fa455a /Source/Particles/Sorting/Partition.cpp
parent7acdcf342f21d89ed4616c05536ba05485629f45 (diff)
downloadWarpX-b4c4315c77ade3ebb4b11e137ddfe354f1c95d23.tar.gz
WarpX-b4c4315c77ade3ebb4b11e137ddfe354f1c95d23.tar.zst
WarpX-b4c4315c77ade3ebb4b11e137ddfe354f1c95d23.zip
Create dedicated method for partition in buffers
Diffstat (limited to 'Source/Particles/Sorting/Partition.cpp')
-rw-r--r--Source/Particles/Sorting/Partition.cpp115
1 files changed, 115 insertions, 0 deletions
diff --git a/Source/Particles/Sorting/Partition.cpp b/Source/Particles/Sorting/Partition.cpp
new file mode 100644
index 000000000..d000a2c04
--- /dev/null
+++ b/Source/Particles/Sorting/Partition.cpp
@@ -0,0 +1,115 @@
+#include <WarpX.H>
+#include <PhysicalParticleContainer.H>
+#include <AMReX_Particles.H>
+
+using namespace amrex;
+
+/* \brief
+*/
+void
+PhysicalParticleContainer::PartitionParticlesInBuffers(
+ long& nfine_current, long& nfine_gather, long const np,
+ WarpXParIter& pti, int const lev,
+ iMultiFab const* current_masks,
+ iMultiFab const* gather_masks,
+ RealVector& uxp, RealVector& uyp, RealVector& uzp, RealVector& wp)
+{
+ BL_PROFILE("PPC::Evolve::partition");
+
+ std::vector<bool> inexflag;
+ inexflag.resize(np);
+
+ auto& aos = pti.GetArrayOfStructs();
+
+ // We need to partition the large buffer first
+ iMultiFab const* bmasks =
+ (WarpX::n_field_gather_buffer >= WarpX::n_current_deposition_buffer) ?
+ gather_masks : current_masks;
+ int i = 0;
+ const auto& msk = (*bmasks)[pti];
+ for (const auto& p : aos) {
+ const IntVect& iv = Index(p, lev);
+ inexflag[i++] = msk(iv);
+ }
+
+ Vector<long> pid;
+ pid.resize(np);
+ std::iota(pid.begin(), pid.end(), 0L);
+ auto sep = std::stable_partition(pid.begin(), pid.end(),
+ [&inexflag](long id) { return inexflag[id]; });
+
+ if (WarpX::n_current_deposition_buffer == WarpX::n_field_gather_buffer) {
+ nfine_current = nfine_gather = std::distance(pid.begin(), sep);
+ } else if (sep != pid.end()) {
+ int n_buf;
+ if (bmasks == gather_masks) {
+ nfine_gather = std::distance(pid.begin(), sep);
+ bmasks = current_masks;
+ n_buf = WarpX::n_current_deposition_buffer;
+ } else {
+ nfine_current = std::distance(pid.begin(), sep);
+ bmasks = gather_masks;
+ n_buf = WarpX::n_field_gather_buffer;
+ }
+ if (n_buf > 0)
+ {
+ const auto& msk2 = (*bmasks)[pti];
+ for (auto it = sep; it != pid.end(); ++it) {
+ const long id = *it;
+ const IntVect& iv = Index(aos[id], lev);
+ inexflag[id] = msk2(iv);
+ }
+
+ auto sep2 = std::stable_partition(sep, pid.end(),
+ [&inexflag](long id) {return inexflag[id];});
+ if (bmasks == gather_masks) {
+ nfine_gather = std::distance(pid.begin(), sep2);
+ } else {
+ nfine_current = std::distance(pid.begin(), sep2);
+ }
+ }
+ }
+
+ // only deposit / gather to coarsest grid
+ if (m_deposit_on_main_grid && lev > 0) {
+ nfine_current = 0;
+ }
+ if (m_gather_from_main_grid && lev > 0) {
+ nfine_gather = 0;
+ }
+
+ if (nfine_current != np || nfine_gather != np)
+ {
+ RealVector tmp;
+ ParticleVector particle_tmp;
+
+ particle_tmp.resize(np);
+ for (long ip = 0; ip < np; ++ip) {
+ particle_tmp[ip] = aos[pid[ip]];
+ }
+ std::swap(aos(), particle_tmp);
+
+ tmp.resize(np);
+
+ for (long ip = 0; ip < np; ++ip) {
+ tmp[ip] = wp[pid[ip]];
+ }
+ std::swap(wp, tmp);
+
+ for (long ip = 0; ip < np; ++ip) {
+ tmp[ip] = uxp[pid[ip]];
+ }
+ std::swap(uxp, tmp);
+
+ for (long ip = 0; ip < np; ++ip) {
+ tmp[ip] = uyp[pid[ip]];
+ }
+ std::swap(uyp, tmp);
+
+ for (long ip = 0; ip < np; ++ip) {
+ tmp[ip] = uzp[pid[ip]];
+ }
+ std::swap(uzp, tmp);
+ }
+
+}