WarpX
ParticleScraper.H
Go to the documentation of this file.
1 /* Copyright 2021 Andrew Myers
2  *
3  * This file is part of WarpX.
4  *
5  * License: BSD-3-Clause-LBNL
6  */
7 #ifndef PARTICLESCRAPER_H_
8 #define PARTICLESCRAPER_H_
9 
10 #include <AMReX.H>
11 #include <AMReX_Vector.H>
12 #include <AMReX_MultiFab.H>
13 
16 
55 void
56 scrapeParticles (PC& pc, const amrex::Vector<const amrex::MultiFab*>& distance_to_eb, int lev, F&& f)
57 {
58  scrapeParticles(pc, distance_to_eb, lev, lev, std::forward<F>(f));
59 }
60 
98 void
99 scrapeParticles (PC& pc, const amrex::Vector<const amrex::MultiFab*>& distance_to_eb, F&& f)
100 {
101  scrapeParticles(pc, distance_to_eb, 0, pc.finestLevel(), std::forward<F>(f));
102 }
103 
143 void
144 scrapeParticles (PC& pc, const amrex::Vector<const amrex::MultiFab*>& distance_to_eb,
145  int lev_min, int lev_max, F&& f)
146 {
147  BL_PROFILE("scrapeParticles");
148 
149  for (int lev = lev_min; lev <= lev_max; ++lev)
150  {
151  const auto plo = pc.Geom(lev).ProbLoArray();
152  const auto dxi = pc.Geom(lev).InvCellSizeArray();
153  for(WarpXParIter pti(pc, lev); pti.isValid(); ++pti)
154  {
155  const auto getPosition = GetParticlePosition(pti);
156  auto& tile = pti.GetParticleTile();
157  auto ptd = tile.getParticleTileData();
158  const auto np = tile.numParticles();
159  auto phi = (*distance_to_eb[lev])[pti].array(); // signed distance function
160  amrex::ParallelForRNG( np,
161  [=] AMREX_GPU_DEVICE (const int ip, amrex::RandomEngine const& engine) noexcept
162  {
163  amrex::ParticleReal xp, yp, zp;
164  getPosition(ip, xp, yp, zp);
165 
166  int i, j, k;
167  amrex::Real W[AMREX_SPACEDIM][2];
168  compute_weights_nodal(xp, yp, zp, plo, dxi, i, j, k, W);
169 
170  amrex::Real phi_value = interp_field_nodal(i, j, k, W, phi);
171  amrex::RealVect normal = DistanceToEB::interp_normal(i, j, k, W, phi, dxi);
172 
173  // the closest point on the surface to pos is pos - grad phi(pos) * phi(pos)
174  amrex::RealVect pos;
175  pos[0] = xp - normal[0]*phi_value;
176  pos[1] = yp - normal[1]*phi_value;
177  pos[2] = zp - normal[2]*phi_value;
178 
179  DistanceToEB::normalize(normal);
180 
181  if (phi_value < 0.0) {
182  f(ptd, ip, pos, normal, engine);
183  }
184  });
185  }
186  }
187 }
188 
189 #endif
void scrapeParticles(PC &pc, const amrex::Vector< const amrex::MultiFab *> &distance_to_eb, int lev, F &&f)
Interact particles with the embedded boundary walls.
Definition: ParticleScraper.H:56
f
Definition: write_atomic_data_cpp.py:83
i
Definition: check_interp_points_and_weights.py:171
AMREX_GPU_HOST_DEVICE AMREX_INLINE amrex::Real interp_field_nodal(int i, int j, int k, const amrex::Real W[AMREX_SPACEDIM][2], amrex::Array4< const amrex::Real > const &scalar_field) noexcept
Interpolate nodal field value based on surrounding indices and weights.
Definition: ScalarFieldGather.H:74
AMREX_GPU_HOST_DEVICE AMREX_INLINE void compute_weights_nodal(const amrex::ParticleReal xp, const amrex::ParticleReal yp, const amrex::ParticleReal zp, amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > const &plo, amrex::GpuArray< amrex::Real, AMREX_SPACEDIM > const &dxi, int &i, int &j, int &k, amrex::Real W[AMREX_SPACEDIM][2]) noexcept
Compute weight of each surrounding node in interpolating a nodal field to the given coordinates...
Definition: ScalarFieldGather.H:22
Functor that can be used to extract the positions of the macroparticles inside a ParallelFor kernel...
Definition: GetAndSetPosition.H:48
Definition: WarpXParticleContainer.H:58
value
Definition: updateAMReX.py:125