diff --git a/Source/Diagnostics/ParticleDiag/ParticleDiag.cpp b/Source/Diagnostics/ParticleDiag/ParticleDiag.cpp index 57c4af4e242..338d90a54d6 100644 --- a/Source/Diagnostics/ParticleDiag/ParticleDiag.cpp +++ b/Source/Diagnostics/ParticleDiag/ParticleDiag.cpp @@ -68,7 +68,7 @@ ParticleDiag::ParticleDiag ( // Always write out theta, whether or not it's requested, // to be consistent with always writing out r and z. // TODO: openPMD does a reconstruction to Cartesian, so we can now skip force-writing this - m_plot_flags[pc->GetRealSoANames().at("theta")] = 1; + m_plot_flags[pc->GetRealCompIndex("theta")] = 1; #endif // build filter functors diff --git a/Source/Particles/AddPlasmaUtilities.H b/Source/Particles/AddPlasmaUtilities.H index 7b8e4e58105..12d964adf64 100644 --- a/Source/Particles/AddPlasmaUtilities.H +++ b/Source/Particles/AddPlasmaUtilities.H @@ -251,8 +251,6 @@ struct PlasmaParserHelper PlasmaParserHelper (SoAType& a_soa, std::size_t old_size, const std::vector& a_user_int_attribs, const std::vector& a_user_real_attribs, - std::map& a_particle_icomps, - std::map& a_particle_comps, const PlasmaParserWrapper& wrapper) : m_wrapper_ptr(&wrapper) { m_pa_user_int_pinned.resize(a_user_int_attribs.size()); @@ -266,10 +264,10 @@ struct PlasmaParserHelper #endif for (std::size_t ia = 0; ia < a_user_int_attribs.size(); ++ia) { - m_pa_user_int_pinned[ia] = a_soa.GetIntData(a_particle_icomps[a_user_int_attribs[ia]]).data() + old_size; + m_pa_user_int_pinned[ia] = a_soa.GetIntData(a_user_int_attribs[ia]).data() + old_size; } for (std::size_t ia = 0; ia < a_user_real_attribs.size(); ++ia) { - m_pa_user_real_pinned[ia] = a_soa.GetRealData(a_particle_comps[a_user_real_attribs[ia]]).data() + old_size; + m_pa_user_real_pinned[ia] = a_soa.GetRealData(a_user_real_attribs[ia]).data() + old_size; } #ifdef AMREX_USE_GPU @@ -308,7 +306,6 @@ struct QEDHelper { template QEDHelper (SoAType& a_soa, std::size_t old_size, - std::map& a_particle_comps, bool a_has_quantum_sync, bool a_has_breit_wheeler, const std::shared_ptr& a_shr_p_qs_engine, const std::shared_ptr& a_shr_p_bw_engine) @@ -317,14 +314,12 @@ struct QEDHelper if(has_quantum_sync){ quantum_sync_get_opt = a_shr_p_qs_engine->build_optical_depth_functor(); - p_optical_depth_QSR = a_soa.GetRealData( - a_particle_comps["opticalDepthQSR"]).data() + old_size; + p_optical_depth_QSR = a_soa.GetRealData("opticalDepthQSR").data() + old_size; } if(has_breit_wheeler){ breit_wheeler_get_opt = a_shr_p_bw_engine->build_optical_depth_functor(); - p_optical_depth_BW = a_soa.GetRealData( - a_particle_comps["opticalDepthBW"]).data() + old_size; + p_optical_depth_BW = a_soa.GetRealData("opticalDepthBW").data() + old_size; } } diff --git a/Source/Particles/ParticleBoundaryBuffer.cpp b/Source/Particles/ParticleBoundaryBuffer.cpp index 674b2daab86..5cb279dce03 100644 --- a/Source/Particles/ParticleBoundaryBuffer.cpp +++ b/Source/Particles/ParticleBoundaryBuffer.cpp @@ -443,11 +443,9 @@ void ParticleBoundaryBuffer::gatherParticlesFromDomainBoundaries (MultiParticleC WARPX_PROFILE("ParticleBoundaryBuffer::gatherParticles::filterAndTransform"); auto& warpx = WarpX::GetInstance(); const auto dt = warpx.getdt(pti.GetLevel()); - auto string_to_index_intcomp = buffer[i].getParticleRuntimeiComps(); - const int step_scraped_index = string_to_index_intcomp.at("stepScraped"); - auto string_to_index_realcomp = buffer[i].getParticleRuntimeComps(); - const int delta_index = string_to_index_realcomp.at("deltaTimeScraped"); - const int normal_index = string_to_index_realcomp.at("nx"); + const int step_scraped_index = buffer[i].GetIntCompIndex("stepScraped"); + const int delta_index = buffer[i].GetRealCompIndex("deltaTimeScraped"); + const int normal_index = buffer[i].GetRealCompIndex("nx"); const int step = warpx_instance.getistep(0); amrex::filterAndTransformParticles(ptile_buffer, ptile, predicate, @@ -546,11 +544,9 @@ void ParticleBoundaryBuffer::gatherParticlesFromEmbeddedBoundaries ( } auto &warpx = WarpX::GetInstance(); const auto dt = warpx.getdt(pti.GetLevel()); - auto string_to_index_intcomp = buffer[i].getParticleRuntimeiComps(); - const int step_scraped_index = string_to_index_intcomp.at("stepScraped"); - auto string_to_index_realcomp = buffer[i].getParticleRuntimeComps(); - const int delta_index = string_to_index_realcomp.at("deltaTimeScraped"); - const int normal_index = string_to_index_realcomp.at("nx"); + const int step_scraped_index = buffer[i].GetIntCompIndex("stepScraped"); + const int delta_index = buffer[i].GetRealCompIndex("deltaTimeScraped"); + const int normal_index = buffer[i].GetRealCompIndex("nx"); const int step = warpx_instance.getistep(0); { diff --git a/Source/Particles/ParticleCreation/DefaultInitialization.H b/Source/Particles/ParticleCreation/DefaultInitialization.H index 88b23905481..1922c829379 100644 --- a/Source/Particles/ParticleCreation/DefaultInitialization.H +++ b/Source/Particles/ParticleCreation/DefaultInitialization.H @@ -102,8 +102,8 @@ namespace ParticleCreation { * These are NOT initialized by this function. * @param[in] user_real_attribs The names of the real components for this particle tile * @param[in] user_int_attribs The names of the int components for this particle tile - * @param[in] particle_comps map between particle component index and component name for real comps - * @param[in] particle_icomps map between particle component index and component name for int comps + * @param[in] particle_comps particle component names for real comps + * @param[in] particle_icomps particle component names for int comps * @param[in] user_real_attrib_parser the parser functions used to initialize the user real components * @param[in] user_int_attrib_parser the parser functions used to initialize the user int components * @param[in] do_qed_comps whether to initialize the qed components (these are usually handled by @@ -120,8 +120,8 @@ void DefaultInitializeRuntimeAttributes (PTile& ptile, const int n_external_attr_int, const std::vector& user_real_attribs, const std::vector& user_int_attribs, - const std::map& particle_comps, - const std::map& particle_icomps, + const std::vector& particle_comps, + const std::vector& particle_icomps, const std::vector& user_real_attrib_parser, const std::vector& user_int_attrib_parser, #ifdef WARPX_QED @@ -151,8 +151,9 @@ void DefaultInitializeRuntimeAttributes (PTile& ptile, auto attr_ptr = ptile.GetStructOfArrays().GetRealData(j).data(); #ifdef WARPX_QED // Current runtime comp is quantum synchrotron optical depth - if (particle_comps.find("opticalDepthQSR") != particle_comps.end() && - particle_comps.at("opticalDepthQSR") == j) + auto const it_qsr = std::find(particle_comps.begin(), particle_comps.end(), "opticalDepthQSR"); + if (it_qsr != particle_comps.end() && + std::distance(particle_comps.begin(), it_qsr) == j) { if (!do_qed_comps) { continue; } const QuantumSynchrotronGetOpticalDepth quantum_sync_get_opt = @@ -172,9 +173,10 @@ void DefaultInitializeRuntimeAttributes (PTile& ptile, } } - // Current runtime comp is Breit-Wheeler optical depth - if (particle_comps.find("opticalDepthBW") != particle_comps.end() && - particle_comps.at("opticalDepthBW") == j) + // Current runtime comp is Breit-Wheeler optical depth + auto const it_bw = std::find(particle_comps.begin(), particle_comps.end(), "opticalDepthBW"); + if (it_bw != particle_comps.end() && + std::distance(particle_comps.begin(), it_bw) == j) { if (!do_qed_comps) { continue; } const BreitWheelerGetOpticalDepth breit_wheeler_get_opt = @@ -198,8 +200,9 @@ void DefaultInitializeRuntimeAttributes (PTile& ptile, for (int ia = 0; ia < n_user_real_attribs; ++ia) { // Current runtime comp is ia-th user defined attribute - if (particle_comps.find(user_real_attribs[ia]) != particle_comps.end() && - particle_comps.at(user_real_attribs[ia]) == j) + auto const it_ura = std::find(particle_comps.begin(), particle_comps.end(), user_real_attribs[ia]); + if (it_ura != particle_comps.end() && + std::distance(particle_comps.begin(), it_ura) == j) { const amrex::ParserExecutor<7> user_real_attrib_parserexec = user_real_attrib_parser[ia]->compile<7>(); @@ -232,8 +235,9 @@ void DefaultInitializeRuntimeAttributes (PTile& ptile, auto attr_ptr = ptile.GetStructOfArrays().GetIntData(j).data(); // Current runtime comp is ionization level - if (particle_icomps.find("ionizationLevel") != particle_icomps.end() && - particle_icomps.at("ionizationLevel") == j) + auto const it_ioniz = std::find(particle_icomps.begin(), particle_icomps.end(), "ionizationLevel"); + if (it_ioniz != particle_icomps.end() && + std::distance(particle_icomps.begin(), it_ioniz) == j) { if constexpr (amrex::RunOnGpu>::value) { amrex::ParallelFor(stop - start, @@ -251,8 +255,9 @@ void DefaultInitializeRuntimeAttributes (PTile& ptile, for (int ia = 0; ia < n_user_int_attribs; ++ia) { // Current runtime comp is ia-th user defined attribute - if (particle_icomps.find(user_int_attribs[ia]) != particle_icomps.end() && - particle_icomps.at(user_int_attribs[ia]) == j) + auto const it_uia = std::find(particle_icomps.begin(), particle_icomps.end(), user_int_attribs[ia]); + if (it_uia != particle_icomps.end() && + std::distance(particle_icomps.begin(), it_uia) == j) { const amrex::ParserExecutor<7> user_int_attrib_parserexec = user_int_attrib_parser[ia]->compile<7>(); diff --git a/Source/Particles/ParticleCreation/SmartUtils.H b/Source/Particles/ParticleCreation/SmartUtils.H index 652a3aecd17..358c2b1a7a9 100644 --- a/Source/Particles/ParticleCreation/SmartUtils.H +++ b/Source/Particles/ParticleCreation/SmartUtils.H @@ -35,9 +35,9 @@ struct SmartCopyTag [[nodiscard]] int size () const noexcept { return static_cast(common_names.size()); } }; -PolicyVec getPolicies (const NameMap& names) noexcept; +PolicyVec getPolicies (std::vector const & names) noexcept; -SmartCopyTag getSmartCopyTag (const NameMap& src, const NameMap& dst) noexcept; +SmartCopyTag getSmartCopyTag (std::vector const & src, std::vector const & dst) noexcept; /** * \brief Sets the ids of newly created particles to the next values. diff --git a/Source/Particles/ParticleCreation/SmartUtils.cpp b/Source/Particles/ParticleCreation/SmartUtils.cpp index 7e79f58c59e..19e5bee8b97 100644 --- a/Source/Particles/ParticleCreation/SmartUtils.cpp +++ b/Source/Particles/ParticleCreation/SmartUtils.cpp @@ -13,8 +13,11 @@ #include #include -PolicyVec getPolicies (const NameMap& names) noexcept +PolicyVec getPolicies (std::vector const & names_vec) noexcept { + NameMap names; + for (auto i = 0u; i < names_vec.size(); ++i) { names.emplace(names_vec[i], i); } + std::vector h_policies; h_policies.resize(names.size()); for (const auto& kv : names) @@ -31,10 +34,16 @@ PolicyVec getPolicies (const NameMap& names) noexcept return policies; } -SmartCopyTag getSmartCopyTag (const NameMap& src, const NameMap& dst) noexcept +SmartCopyTag getSmartCopyTag (std::vector const & src_names, std::vector const & dst_names) noexcept { SmartCopyTag tag; + // We want to avoid running an NxM algorithm to find pairs, so sort the components first. + NameMap src; + NameMap dst; + for (auto i = 0u; i < src_names.size(); ++i) { src.emplace(src_names[i], i); } + for (auto i = 0u; i < dst_names.size(); ++i) { dst.emplace(dst_names[i], i); } + std::vector h_src_comps; std::vector h_dst_comps; diff --git a/Source/Particles/PhysicalParticleContainer.cpp b/Source/Particles/PhysicalParticleContainer.cpp index 0d501c8ff41..655c5aa9563 100644 --- a/Source/Particles/PhysicalParticleContainer.cpp +++ b/Source/Particles/PhysicalParticleContainer.cpp @@ -813,7 +813,7 @@ PhysicalParticleContainer::DefaultInitializeRuntimeAttributes ( ParticleCreation::DefaultInitializeRuntimeAttributes(pinned_tile, n_external_attr_real, n_external_attr_int, m_user_real_attribs, m_user_int_attribs, - particle_comps, particle_icomps, + GetRealSoANames(), GetIntSoANames(), amrex::GetVecOfPtrs(m_user_real_attrib_parser), amrex::GetVecOfPtrs(m_user_int_attrib_parser), #ifdef WARPX_QED @@ -1086,7 +1086,7 @@ PhysicalParticleContainer::AddPlasma (PlasmaInjector const& plasma_injector, int } uint64_t * AMREX_RESTRICT pa_idcpu = soa.GetIdCPUData().data() + old_size; - PlasmaParserHelper plasma_parser_helper (soa, old_size, m_user_int_attribs, m_user_real_attribs, particle_icomps, particle_comps, plasma_parser_wrapper); + PlasmaParserHelper plasma_parser_helper(soa, old_size, m_user_int_attribs, m_user_real_attribs, plasma_parser_wrapper); int** pa_user_int_data = plasma_parser_helper.getUserIntDataPtrs(); ParticleReal** pa_user_real_data = plasma_parser_helper.getUserRealDataPtrs(); amrex::ParserExecutor<7> const* user_int_parserexec_data = plasma_parser_helper.getUserIntParserExecData(); @@ -1094,11 +1094,11 @@ PhysicalParticleContainer::AddPlasma (PlasmaInjector const& plasma_injector, int int* pi = nullptr; if (do_field_ionization) { - pi = soa.GetIntData(particle_icomps["ionizationLevel"]).data() + old_size; + pi = soa.GetIntData("ionizationLevel").data() + old_size; } #ifdef WARPX_QED - const QEDHelper qed_helper(soa, old_size, particle_comps, + const QEDHelper qed_helper(soa, old_size, has_quantum_sync(), has_breit_wheeler(), m_shr_p_qs_engine, m_shr_p_bw_engine); #endif @@ -1522,7 +1522,7 @@ PhysicalParticleContainer::AddPlasmaFlux (PlasmaInjector const& plasma_injector, } uint64_t * AMREX_RESTRICT pa_idcpu = soa.GetIdCPUData().data() + old_size; - PlasmaParserHelper plasma_parser_helper (soa, old_size, m_user_int_attribs, m_user_real_attribs, particle_icomps, particle_comps, plasma_parser_wrapper); + PlasmaParserHelper plasma_parser_helper(soa, old_size, m_user_int_attribs, m_user_real_attribs, plasma_parser_wrapper); int** pa_user_int_data = plasma_parser_helper.getUserIntDataPtrs(); ParticleReal** pa_user_real_data = plasma_parser_helper.getUserRealDataPtrs(); amrex::ParserExecutor<7> const* user_int_parserexec_data = plasma_parser_helper.getUserIntParserExecData(); @@ -1530,11 +1530,11 @@ PhysicalParticleContainer::AddPlasmaFlux (PlasmaInjector const& plasma_injector, int* p_ion_level = nullptr; if (do_field_ionization) { - p_ion_level = soa.GetIntData(particle_icomps["ionizationLevel"]).data() + old_size; + p_ion_level = soa.GetIntData("ionizationLevel").data() + old_size; } #ifdef WARPX_QED - const QEDHelper qed_helper(soa, old_size, particle_comps, + const QEDHelper qed_helper(soa, old_size, has_quantum_sync(), has_breit_wheeler(), m_shr_p_qs_engine, m_shr_p_bw_engine); #endif @@ -1922,7 +1922,7 @@ PhysicalParticleContainer::Evolve (ablastr::fields::MultiFabRegister& fields, // Deposit charge before particle push, in component 0 of MultiFab rho. const int* const AMREX_RESTRICT ion_lev = (do_field_ionization)? - pti.GetiAttribs(particle_icomps["ionizationLevel"]).dataPtr():nullptr; + pti.GetiAttribs("ionizationLevel").dataPtr():nullptr; amrex::MultiFab* rho = fields.get(FieldType::rho_fp, lev); DepositCharge(pti, wp, ion_lev, rho, 0, 0, @@ -2018,7 +2018,7 @@ PhysicalParticleContainer::Evolve (ablastr::fields::MultiFabRegister& fields, const amrex::Real relative_time = (push_type == PushType::Explicit ? -0.5_rt * dt : 0.0_rt); const int* const AMREX_RESTRICT ion_lev = (do_field_ionization)? - pti.GetiAttribs(particle_icomps["ionizationLevel"]).dataPtr():nullptr; + pti.GetiAttribs("ionizationLevel").dataPtr():nullptr; // Deposit inside domains amrex::MultiFab * jx = fields.get(current_fp_string, Direction{0}, lev); @@ -2050,7 +2050,7 @@ PhysicalParticleContainer::Evolve (ablastr::fields::MultiFabRegister& fields, "Cannot deposit charge in rho component 1: only component 0 is allocated!"); const int* const AMREX_RESTRICT ion_lev = (do_field_ionization)? - pti.GetiAttribs(particle_icomps["ionizationLevel"]).dataPtr():nullptr; + pti.GetiAttribs("ionizationLevel").dataPtr():nullptr; DepositCharge(pti, wp, ion_lev, rho, 1, 0, np_current, thread_num, lev, lev); @@ -2424,7 +2424,7 @@ PhysicalParticleContainer::PushP (int lev, Real dt, int* AMREX_RESTRICT ion_lev = nullptr; if (do_field_ionization) { - ion_lev = pti.GetiAttribs(particle_icomps["ionizationLevel"]).dataPtr(); + ion_lev = pti.GetiAttribs("ionizationLevel").dataPtr(); } // Loop over the particles and update their momentum @@ -2620,7 +2620,7 @@ PhysicalParticleContainer::PushPX (WarpXParIter& pti, int* AMREX_RESTRICT ion_lev = nullptr; if (do_field_ionization) { - ion_lev = pti.GetiAttribs(particle_icomps["ionizationLevel"]).dataPtr() + offset; + ion_lev = pti.GetiAttribs("ionizationLevel").dataPtr() + offset; } const bool save_previous_position = m_save_previous_position; @@ -2877,7 +2877,7 @@ PhysicalParticleContainer::ImplicitPushXP (WarpXParIter& pti, int* AMREX_RESTRICT ion_lev = nullptr; if (do_field_ionization) { - ion_lev = pti.GetiAttribs(particle_icomps["ionizationLevel"]).dataPtr() + offset; + ion_lev = pti.GetiAttribs("ionizationLevel").dataPtr() + offset; } // Loop over the particles and update their momentum @@ -3193,7 +3193,7 @@ PhysicalParticleContainer::getIonizationFunc (const WarpXParIter& pti, adk_exp_prefactor.dataPtr(), adk_power.dataPtr(), adk_correction_factors.dataPtr(), - particle_icomps["ionizationLevel"], + GetIntCompIndex("ionizationLevel"), ion_atomic_number, do_adk_correction}; } @@ -3299,14 +3299,14 @@ PhotonEmissionFilterFunc PhysicalParticleContainer::getPhotonEmissionFilterFunc () { WARPX_PROFILE("PhysicalParticleContainer::getPhotonEmissionFunc()"); - return PhotonEmissionFilterFunc{particle_runtime_comps["opticalDepthQSR"]}; + return PhotonEmissionFilterFunc{GetRealCompIndex("opticalDepthQSR")}; } PairGenerationFilterFunc PhysicalParticleContainer::getPairGenerationFilterFunc () { WARPX_PROFILE("PhysicalParticleContainer::getPairGenerationFunc()"); - return PairGenerationFilterFunc{particle_runtime_comps["opticalDepthBW"]}; + return PairGenerationFilterFunc{GetRealCompIndex("opticalDepthBW")}; } #endif diff --git a/Source/Particles/RigidInjectedParticleContainer.cpp b/Source/Particles/RigidInjectedParticleContainer.cpp index 5d8b0111825..420d7599ecb 100644 --- a/Source/Particles/RigidInjectedParticleContainer.cpp +++ b/Source/Particles/RigidInjectedParticleContainer.cpp @@ -345,7 +345,7 @@ RigidInjectedParticleContainer::PushP (int lev, Real dt, int* AMREX_RESTRICT ion_lev = nullptr; if (do_field_ionization) { - ion_lev = pti.GetiAttribs(particle_icomps["ionizationLevel"]).dataPtr(); + ion_lev = pti.GetiAttribs("ionizationLevel").dataPtr(); } // Save the position and momenta, making copies diff --git a/Source/Particles/WarpXParticleContainer.cpp b/Source/Particles/WarpXParticleContainer.cpp index 79cb9124024..8e91093d95b 100644 --- a/Source/Particles/WarpXParticleContainer.cpp +++ b/Source/Particles/WarpXParticleContainer.cpp @@ -94,8 +94,8 @@ WarpXParticleContainer::WarpXParticleContainer (AmrCore* amr_core, int ispecies) { SetParticleSize(); SetSoACompileTimeNames( - {RealSoA::names_s.begin(), RealSoA::names_s.end()}, - {IntSoA::names_s.begin(), IntSoA::names_s.end()} + {PIdx::names.begin(), PIdx::names.end()}, + {IntIdx::names.begin(), IntIdx::names.end()} ); ReadParameters(); @@ -873,7 +873,7 @@ WarpXParticleContainer::DepositCurrent ( int* AMREX_RESTRICT ion_lev = nullptr; if (do_field_ionization) { - ion_lev = pti.GetiAttribs(particle_icomps["ionizationLevel"]).dataPtr(); + ion_lev = pti.GetiAttribs("ionizationLevel").dataPtr(); } DepositCurrent(pti, wp, uxp, uyp, uzp, ion_lev, @@ -1266,7 +1266,7 @@ WarpXParticleContainer::DepositCharge (amrex::MultiFab* rho, int* AMREX_RESTRICT ion_lev = nullptr; if (do_field_ionization) { - ion_lev = pti.GetiAttribs(particle_icomps["ionizationLevel"]).dataPtr(); + ion_lev = pti.GetiAttribs("ionizationLevel").dataPtr(); } DepositCharge(pti, wp, ion_lev, rho, icomp, 0, np, thread_num, lev, lev); @@ -1550,13 +1550,13 @@ WarpXParticleContainer::PushX (int lev, amrex::Real dt) // without runtime component). void WarpXParticleContainer::defineAllParticleTiles () noexcept { - for (int lev = 0; lev <= amrex::ParticleContainerPureSoA::finestLevel(); ++lev) + for (int lev = 0; lev <= finestLevel(); ++lev) { - for (auto mfi = amrex::ParticleContainerPureSoA::MakeMFIter(lev); mfi.isValid(); ++mfi) + for (auto mfi = MakeMFIter(lev); mfi.isValid(); ++mfi) { const int grid_id = mfi.index(); const int tile_id = mfi.LocalTileIndex(); - amrex::ParticleContainerPureSoA::DefineAndReturnParticleTile(lev, grid_id, tile_id); + DefineAndReturnParticleTile(lev, grid_id, tile_id); } } @@ -1582,7 +1582,7 @@ WarpXParticleContainer::particlePostLocate(ParticleType& p, { if (not do_splitting) { return; } - // Tag particle if goes to higher level. + // Tag particle if it goes to a higher level. // It will be split later in the loop if (pld.m_lev == lev+1 and p.id() != amrex::LongParticleIds::NoSplitParticleID