diff options
-rw-r--r-- | Source/EmbeddedBoundary/ParticleScraper.H | 21 | ||||
-rw-r--r-- | Source/Particles/ParticleBoundaryBuffer.cpp | 5 | ||||
-rw-r--r-- | Source/ablastr/particles/DepositCharge.H | 7 | ||||
-rw-r--r-- | Source/ablastr/particles/NodalFieldGather.H (renamed from Source/Particles/Gather/ScalarFieldGather.H) | 64 |
4 files changed, 78 insertions, 19 deletions
diff --git a/Source/EmbeddedBoundary/ParticleScraper.H b/Source/EmbeddedBoundary/ParticleScraper.H index cb3386c5f..b723fd2ce 100644 --- a/Source/EmbeddedBoundary/ParticleScraper.H +++ b/Source/EmbeddedBoundary/ParticleScraper.H @@ -7,12 +7,23 @@ #ifndef PARTICLESCRAPER_H_ #define PARTICLESCRAPER_H_ +#include "EmbeddedBoundary/DistanceToEB.H" +#include "Particles/Pusher/GetAndSetPosition.H" + +#include <ablastr/particles/NodalFieldGather.H> + #include <AMReX.H> -#include <AMReX_Vector.H> #include <AMReX_MultiFab.H> +#include <AMReX_Particle.H> +#include <AMReX_RandomEngine.H> +#include <AMReX_REAL.H> +#include <AMReX_TypeTraits.H> +#include <AMReX_Vector.H> + +#include <type_traits> +#include <utility> + -#include <EmbeddedBoundary/DistanceToEB.H> -#include "Particles/Gather/ScalarFieldGather.H" /** * \brief Interact particles with the embedded boundary walls. @@ -169,9 +180,9 @@ scrapeParticles (PC& pc, const amrex::Vector<const amrex::MultiFab*>& distance_t int i, j, k; amrex::Real W[AMREX_SPACEDIM][2]; - compute_weights_nodal(xp, yp, zp, plo, dxi, i, j, k, W); + ablastr::particles::compute_weights_nodal(xp, yp, zp, plo, dxi, i, j, k, W); - amrex::Real phi_value = interp_field_nodal(i, j, k, W, phi); + amrex::Real phi_value = ablastr::particles::interp_field_nodal(i, j, k, W, phi); if (phi_value < 0.0) { diff --git a/Source/Particles/ParticleBoundaryBuffer.cpp b/Source/Particles/ParticleBoundaryBuffer.cpp index 0eecbe0d3..7877e33d3 100644 --- a/Source/Particles/ParticleBoundaryBuffer.cpp +++ b/Source/Particles/ParticleBoundaryBuffer.cpp @@ -9,10 +9,11 @@ #include "EmbeddedBoundary/DistanceToEB.H" #include "Particles/ParticleBoundaryBuffer.H" #include "Particles/MultiParticleContainer.H" -#include "Particles/Gather/ScalarFieldGather.H" #include "Utils/TextMsg.H" #include "Utils/WarpXProfilerWrapper.H" +#include <ablastr/particles/NodalFieldGather.H> + #include <AMReX_Geometry.H> #include <AMReX_ParmParse.H> #include <AMReX_Reduce.H> @@ -296,7 +297,7 @@ void ParticleBoundaryBuffer::gatherParticles (MultiParticleContainer& mypc, amrex::ParticleReal xp, yp, zp; getPosition(ip, xp, yp, zp); - amrex::Real phi_value = doGatherScalarFieldNodal( + amrex::Real phi_value = ablastr::particles::doGatherScalarFieldNodal( xp, yp, zp, phiarr, dxi, plo ); return phi_value < 0.0 ? 1 : 0; diff --git a/Source/ablastr/particles/DepositCharge.H b/Source/ablastr/particles/DepositCharge.H index 5eb66be60..e2e27c756 100644 --- a/Source/ablastr/particles/DepositCharge.H +++ b/Source/ablastr/particles/DepositCharge.H @@ -22,8 +22,8 @@ #include <optional> -namespace ablastr { -namespace particles { +namespace ablastr::particles +{ /** Perform charge deposition for the particles on a tile. * @@ -208,7 +208,6 @@ deposit_charge (typename T_PC::ParIterType& pti, #endif } -} // namespace particles -} // namespace ablastr +} // namespace ablastr::particles #endif // ABLASTR_DEPOSIT_CHARGE_H_ diff --git a/Source/Particles/Gather/ScalarFieldGather.H b/Source/ablastr/particles/NodalFieldGather.H index 31ee35bd0..53c329604 100644 --- a/Source/Particles/Gather/ScalarFieldGather.H +++ b/Source/ablastr/particles/NodalFieldGather.H @@ -1,19 +1,30 @@ -/* Copyright 2021 Modern Electron +/* Copyright 2019-2022 Modern Electron, Axel Huebl, Remi Lehe * * This file is part of WarpX. * * License: BSD-3-Clause-LBNL */ -#ifndef SCALARFIELDGATHER_H_ -#define SCALARFIELDGATHER_H_ +#ifndef ABLASTR_NODALFIELDGATHER_H_ +#define ABLASTR_NODALFIELDGATHER_H_ +#include <AMReX_Array.H> +#include <AMReX_Extension.H> +#include <AMReX_GpuQualifiers.H> +#include <AMReX_Math.H> +#include <AMReX_REAL.H> + + +namespace ablastr::particles +{ /** * \brief Compute weight of each surrounding node in interpolating a nodal field * to the given coordinates. * + * This currently only does linear order. + * * \param xp,yp,zp Particle position coordinates * \param plo Index lower bounds of domain. - * \param dxi 3D cell spacing + * \param dxi inverse 3D cell spacing * \param i,j,k Variables to store indices of position on grid * \param W 2D array of weights to store each neighbouring node */ @@ -21,8 +32,8 @@ 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, + 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 { using namespace amrex::literals; @@ -110,7 +121,7 @@ amrex::Real interp_field_nodal (int i, int j, int k, * * \param xp,yp,zp Particle position coordinates * \param scalar_field Array4 of the nodal scalar field, either full array or tile. - * \param dxi 3D cell spacing + * \param dxi inverse 3D cell spacing * \param lo Index lower bounds of domain. */ AMREX_GPU_HOST_DEVICE AMREX_INLINE @@ -128,4 +139,41 @@ amrex::Real doGatherScalarFieldNodal (const amrex::ParticleReal xp, return interp_field_nodal(ii, jj, kk, W, scalar_field); } -#endif // SCALARFIELDGATHER_H_ + +/** + * \brief Vector field gather for a single particle. The field has to be defined + * at the cell nodes (see https://amrex-codes.github.io/amrex/docs_html/Basics.html#id2) + * + * \param xp,yp,zp Particle position coordinates + * \param vector_field_x,vector_field_y,vector_field_z Array4 of nodal scalar fields, either full array or tile. + * \param dxi inverse 3D cell spacing + * \param lo Index lower bounds of domain. + */ +AMREX_GPU_HOST_DEVICE AMREX_INLINE +amrex::GpuArray<amrex::Real, 3> +doGatherVectorFieldNodal (const amrex::ParticleReal xp, + const amrex::ParticleReal yp, + const amrex::ParticleReal zp, + amrex::Array4<const amrex::Real> const& vector_field_x, + amrex::Array4<const amrex::Real> const& vector_field_y, + amrex::Array4<const amrex::Real> const& vector_field_z, + amrex::GpuArray<amrex::Real, AMREX_SPACEDIM> const& dxi, + amrex::GpuArray<amrex::Real, AMREX_SPACEDIM> const& lo) noexcept +{ + // first find the weight of surrounding nodes to use during interpolation + int ii, jj, kk; + amrex::Real W[AMREX_SPACEDIM][2]; + compute_weights_nodal(xp, yp, zp, lo, dxi, ii, jj, kk, W); + + amrex::GpuArray<amrex::Real, 3> const field_interp = { + interp_field_nodal(ii, jj, kk, W, vector_field_x), + interp_field_nodal(ii, jj, kk, W, vector_field_y), + interp_field_nodal(ii, jj, kk, W, vector_field_z) + }; + + return field_interp; +} + +} // namespace ablastr::particles + +#endif // ABLASTR_NODALFIELDGATHER_H_ |