diff options
-rw-r--r-- | Source/Diagnostics/ParticleIO.cpp | 46 | ||||
-rw-r--r-- | Source/Particles/ParticleIO.H | 72 | ||||
-rw-r--r-- | Source/Particles/PhysicalParticleContainer.H | 6 | ||||
-rw-r--r-- | Source/Particles/WarpXParticleContainer.H | 32 | ||||
-rw-r--r-- | Source/Particles/WarpXParticleContainer_fwd.H | 39 |
5 files changed, 121 insertions, 74 deletions
diff --git a/Source/Diagnostics/ParticleIO.cpp b/Source/Diagnostics/ParticleIO.cpp index e391cbf8b..d89b58ce1 100644 --- a/Source/Diagnostics/ParticleIO.cpp +++ b/Source/Diagnostics/ParticleIO.cpp @@ -7,7 +7,9 @@ * License: BSD-3-Clause-LBNL */ +#include "Particles/ParticleIO.H" #include "Particles/MultiParticleContainer.H" +#include "Particles/ParticleBuffer.H" #include "Particles/PhysicalParticleContainer.H" #include "Particles/RigidInjectedParticleContainer.H" #include "Particles/SpeciesPhysicalProperties.H" @@ -121,52 +123,14 @@ MultiParticleContainer::WriteHeader (std::ostream& os) const } } -// Particle momentum is defined as gamma*velocity, which is neither -// SI mass*gamma*velocity nor normalized gamma*velocity/c. -// This converts momentum to SI units (or vice-versa) to write SI data -// to file. -// Photons are a special case, since particle momentum is defined as -// (photon_energy/(m_e * c) ) * u, where u is the photon direction (a -// unit vector). void -PhysicalParticleContainer::ConvertUnits(ConvertDirection convert_direction) +PhysicalParticleContainer::ConvertUnits (ConvertDirection convert_direction) { WARPX_PROFILE("PhysicalParticleContainer::ConvertUnits()"); - // Compute conversion factor - auto factor = 1_rt; - // Account for the special case of photons const auto t_mass = - AmIA<PhysicalSpecies::photon>() ? PhysConst::m_e : mass; - - if (convert_direction == ConvertDirection::WarpX_to_SI){ - factor = t_mass; - } else if (convert_direction == ConvertDirection::SI_to_WarpX){ - factor = 1._rt/t_mass; - } + this->AmIA<PhysicalSpecies::photon>() ? PhysConst::m_e : this->getMass(); - const int nLevels = finestLevel(); - for (int lev=0; lev<=nLevels; lev++){ -#ifdef AMREX_USE_OMP -#pragma omp parallel if (Gpu::notInLaunchRegion()) -#endif - for (WarpXParIter pti(*this, lev); pti.isValid(); ++pti) - { - // - momenta are stored as a struct of array, in `attribs` - auto& attribs = pti.GetAttribs(); - ParticleReal* AMREX_RESTRICT ux = attribs[PIdx::ux].dataPtr(); - ParticleReal* AMREX_RESTRICT uy = attribs[PIdx::uy].dataPtr(); - ParticleReal* AMREX_RESTRICT uz = attribs[PIdx::uz].dataPtr(); - // Loop over the particles and convert momentum - const long np = pti.numParticles(); - ParallelFor( np, - [=] AMREX_GPU_DEVICE (long i) { - ux[i] *= factor; - uy[i] *= factor; - uz[i] *= factor; - } - ); - } - } + particlesConvertUnits(convert_direction, this, t_mass); } diff --git a/Source/Particles/ParticleIO.H b/Source/Particles/ParticleIO.H new file mode 100644 index 000000000..fb60d7a5f --- /dev/null +++ b/Source/Particles/ParticleIO.H @@ -0,0 +1,72 @@ +/* Copyright 2021 Axel Huebl + * + * This file is part of WarpX. + * + * License: BSD-3-Clause-LBNL + */ +#ifndef PARTICLEIO_H_ +#define PARTICLEIO_H_ + +#include "Particles/WarpXParticleContainer.H" + +#include <AMReX_AmrParticles.H> +#include <AMReX_Gpu.H> +#include <AMReX_REAL.H> + + +/** Convert particle momentum to/from SI + * + * Particle momentum is defined as gamma*velocity, which is neither + * SI mass*gamma*velocity nor normalized gamma*velocity/c. + * This converts momentum to SI units (or vice-versa) to write SI data + * to file. + * Photons are a special case, since particle momentum is defined as + * (photon_energy/(m_e * c) ) * u, where u is the photon direction (a + * unit vector). + * + * @tparam T_ParticleContainer a WarpX particle container or AmrParticleContainer + * @param convert_dir convert to or from SI + * @param pc the particle container to manipulate + * @param mass the particle rest mass to use for conversion + */ +template< typename T_ParticleContainer > +void +particlesConvertUnits (ConvertDirection convert_direction, T_ParticleContainer* pc, amrex::ParticleReal const mass ) +{ + using namespace amrex; + + // Compute conversion factor + auto factor = 1_rt; + + if (convert_direction == ConvertDirection::WarpX_to_SI){ + factor = mass; + } else if (convert_direction == ConvertDirection::SI_to_WarpX){ + factor = 1._rt/mass; + } + + const int nLevels = pc->finestLevel(); + for (int lev=0; lev<=nLevels; lev++){ +#ifdef AMREX_USE_OMP +#pragma omp parallel if (Gpu::notInLaunchRegion()) +#endif + for (WarpXParIter pti(*pc, lev); pti.isValid(); ++pti) + { + // - momenta are stored as a struct of array, in `attribs` + auto& attribs = pti.GetAttribs(); + ParticleReal* AMREX_RESTRICT ux = attribs[PIdx::ux].dataPtr(); + ParticleReal* AMREX_RESTRICT uy = attribs[PIdx::uy].dataPtr(); + ParticleReal* AMREX_RESTRICT uz = attribs[PIdx::uz].dataPtr(); + // Loop over the particles and convert momentum + const long np = pti.numParticles(); + ParallelFor( np, + [=] AMREX_GPU_DEVICE (long i) { + ux[i] *= factor; + uy[i] *= factor; + uz[i] *= factor; + } + ); + } + } +} + +#endif /* PARTICLEIO_H_ */ diff --git a/Source/Particles/PhysicalParticleContainer.H b/Source/Particles/PhysicalParticleContainer.H index 3d92242fa..f3cd91f18 100644 --- a/Source/Particles/PhysicalParticleContainer.H +++ b/Source/Particles/PhysicalParticleContainer.H @@ -234,6 +234,12 @@ public: const amrex::Real t_lab, const amrex::Real dt, DiagnosticParticles& diagnostic_particles) final; + /** Convert particle momentum to/from SI + * + * @see particlesConvertUnits + * + * @param convert_dir convert to or from SI + */ virtual void ConvertUnits (ConvertDirection convert_dir) override; /** diff --git a/Source/Particles/WarpXParticleContainer.H b/Source/Particles/WarpXParticleContainer.H index 9922ca9e5..10f3ddc5e 100644 --- a/Source/Particles/WarpXParticleContainer.H +++ b/Source/Particles/WarpXParticleContainer.H @@ -42,38 +42,6 @@ #include <string> #include <utility> -enum struct ConvertDirection{WarpX_to_SI, SI_to_WarpX}; - -struct PIdx -{ - enum { // Particle Attributes stored in amrex::ParticleContainer's struct of array - w = 0, // weight - ux, uy, uz, -#ifdef WARPX_DIM_RZ - theta, // RZ needs all three position components -#endif - nattribs - }; -}; - -struct DiagIdx -{ - enum { - w = 0, - x, y, z, ux, uy, uz, - nattribs - }; -}; - -struct TmpIdx -{ - enum { - xold = 0, - yold, zold, uxold, uyold, uzold, - nattribs - }; -}; - namespace ParticleStringNames { const std::map<std::string, int> to_index = { diff --git a/Source/Particles/WarpXParticleContainer_fwd.H b/Source/Particles/WarpXParticleContainer_fwd.H index 4228892e6..cf007475c 100644 --- a/Source/Particles/WarpXParticleContainer_fwd.H +++ b/Source/Particles/WarpXParticleContainer_fwd.H @@ -1,10 +1,13 @@ -/* Copyright 2021 Luca Fedeli +/* Copyright 2021 Luca Fedeli, Axel Huebl * * This file is part of WarpX. * * License: BSD-3-Clause-LBNL */ +#ifndef WARPX_WarpXParticleContainer_fwd_H_ +#define WARPX_WarpXParticleContainer_fwd_H_ + enum struct ParticleBC; enum struct ConvertDirection; @@ -15,3 +18,37 @@ struct TmpIdx; class WarpXParIter; class WarpXParticleContainer; + +enum struct ConvertDirection{WarpX_to_SI, SI_to_WarpX}; + +struct PIdx +{ + enum { // Particle Attributes stored in amrex::ParticleContainer's struct of array + w = 0, // weight + ux, uy, uz, +#ifdef WARPX_DIM_RZ +theta, // RZ needs all three position components +#endif +nattribs + }; +}; + +struct DiagIdx +{ + enum { + w = 0, + x, y, z, ux, uy, uz, + nattribs + }; +}; + +struct TmpIdx +{ + enum { + xold = 0, + yold, zold, uxold, uyold, uzold, + nattribs + }; +}; + +#endif /* WARPX_WarpXParticleContainer_fwd_H_ */ |