From 0b4a29ede89bb7477f765bc82541f550d22587e6 Mon Sep 17 00:00:00 2001 From: Maxence Thevenet Date: Thu, 24 Nov 2022 11:57:44 +0100 Subject: [PATCH 1/9] Rename laser multilaser --- src/Hipace.H | 4 +- src/Hipace.cpp | 62 +++++++++---------- src/fields/Fields.H | 8 +-- src/fields/Fields.cpp | 6 +- src/laser/CMakeLists.txt | 2 +- src/laser/{Laser.H => MultiLaser.H} | 12 ++-- src/laser/{Laser.cpp => MultiLaser.cpp} | 30 ++++----- src/particles/deposition/ExplicitDeposition.H | 4 +- .../deposition/ExplicitDeposition.cpp | 8 +-- .../deposition/PlasmaDepositCurrent.H | 6 +- .../deposition/PlasmaDepositCurrent.cpp | 8 +-- src/particles/plasma/MultiPlasma.H | 18 +++--- src/particles/plasma/MultiPlasma.cpp | 22 +++---- src/particles/pusher/PlasmaParticleAdvance.H | 6 +- .../pusher/PlasmaParticleAdvance.cpp | 6 +- src/salame/Salame.cpp | 8 +-- 16 files changed, 105 insertions(+), 105 deletions(-) rename src/laser/{Laser.H => MultiLaser.H} (98%) rename src/laser/{Laser.cpp => MultiLaser.cpp} (97%) diff --git a/src/Hipace.H b/src/Hipace.H index 9321646bc4..0adb132d93 100644 --- a/src/Hipace.H +++ b/src/Hipace.H @@ -16,7 +16,7 @@ #include "particles/beam/BeamParticleContainer.H" #include "utils/AdaptiveTimeStep.H" #include "utils/GridCurrent.H" -#include "laser/Laser.H" +#include "laser/MultiLaser.H" #include "utils/Constants.H" #include "utils/Parser.H" #include "diagnostics/Diagnostic.H" @@ -361,7 +361,7 @@ public: /** Adaptive time step instance */ AdaptiveTimeStep m_adaptive_time_step; /** Laser instance (soon to be multi laser container) */ - Laser m_laser; + MultiLaser m_multi_laser; /** GridCurrent instance */ GridCurrent m_grid_current; #ifdef HIPACE_USE_OPENPMD diff --git a/src/Hipace.cpp b/src/Hipace.cpp index 3a7edbf498..f9a7194ce4 100644 --- a/src/Hipace.cpp +++ b/src/Hipace.cpp @@ -99,7 +99,7 @@ Hipace::Hipace () : m_multi_beam(this), m_multi_plasma(this), m_adaptive_time_step(m_multi_beam.get_nbeams()), - m_laser(), + m_multi_laser(), m_diags(this->maxLevel()+1) { amrex::ParmParse pp;// Traditionally, max_step and stop_time do not have prefix. @@ -189,7 +189,7 @@ Hipace::Hipace () : MPI_Comm_split(amrex::ParallelDescriptor::Communicator(), m_rank_xy, myproc, &m_comm_z); #endif - m_use_laser = m_laser.m_use_laser; + m_use_laser = m_multi_laser.m_use_laser; } Hipace::~Hipace () @@ -347,8 +347,8 @@ Hipace::MakeNewLevelFromScratch ( DefineSliceGDB(lev, ba, dm); m_fields.AllocData(lev, Geom(), m_slice_ba[lev], m_slice_dm[lev], m_multi_plasma.m_sort_bin_size); - m_laser.InitData(m_slice_ba[0], m_slice_dm[0]); // laser inits only on level 0 - m_diags.Initialize(lev, m_laser.m_use_laser); + m_multi_laser.InitData(m_slice_ba[0], m_slice_dm[0]); // laser inits only on level 0 + m_diags.Initialize(lev, m_multi_laser.m_use_laser); } void @@ -436,7 +436,7 @@ Hipace::Evolve () /* Store charge density of (immobile) ions into WhichSlice::RhoIons */ if (m_do_tiling) m_multi_plasma.TileSort(boxArray(lev)[0], geom[lev]); - m_multi_plasma.DepositNeutralizingBackground(m_fields, m_laser, WhichSlice::RhoIons, geom[lev], + m_multi_plasma.DepositNeutralizingBackground(m_fields, m_multi_laser, WhichSlice::RhoIons, geom[lev], finestLevel()+1); // Loop over longitudinal boxes on this rank, from head to tail @@ -445,11 +445,11 @@ Hipace::Evolve () { const amrex::Box& bx = boxArray(lev)[it]; - if (m_laser.m_use_laser) { + if (m_multi_laser.m_use_laser) { AMREX_ALWAYS_ASSERT(!m_adaptive_time_step.m_do_adaptive_time_step); AMREX_ALWAYS_ASSERT(m_multi_plasma.GetNPlasmas() <= 1); // Before that, the 3D fields of the envelope are not initialized (not even allocated). - m_laser.Init3DEnvelope(step, bx, Geom(0)); + m_multi_laser.Init3DEnvelope(step, bx, Geom(0)); if (it == n_boxes-1) ResetLaser(); } @@ -547,7 +547,7 @@ Hipace::SolveOneSlice (int islice_coarse, const int ibox, int step, boxArray(0)[ibox].smallEnd(Direction::z), m_box_sorters, ibox); // Get this laser slice from the 3D array - m_laser.Copy(islice_coarse, false); + m_multi_laser.Copy(islice_coarse, false); for (int lev = 0; lev <= finestLevel(); ++lev) { @@ -591,8 +591,8 @@ Hipace::SolveOneSlice (int islice_coarse, const int ibox, int step, } // end for (int isubslice = nsubslice-1; isubslice >= 0; --isubslice) // Advance laser slice by 1 step and store result to 3D array - m_laser.AdvanceSlice(m_fields, Geom(0), m_dt, step); - m_laser.Copy(islice_coarse, true); + m_multi_laser.AdvanceSlice(m_fields, Geom(0), m_dt, step); + m_multi_laser.Copy(islice_coarse, true); // After this, the parallel context is the full 3D communicator again amrex::ParallelContext::pop(); @@ -619,7 +619,7 @@ Hipace::ExplicitSolveOneSubSlice (const int lev, const int step, const int ibox, // deposit jx, jy, jz, rho and chi for all plasmas m_multi_plasma.DepositCurrent( - m_fields, m_laser, WhichSlice::This, false, true, true, true, true, geom[lev], lev); + m_fields, m_multi_laser, WhichSlice::This, false, true, true, true, true, geom[lev], lev); m_fields.setVal(0., lev, WhichSlice::Next, "jx_beam", "jy_beam"); // deposit jx_beam and jy_beam in the Next slice @@ -648,7 +648,7 @@ Hipace::ExplicitSolveOneSubSlice (const int lev, const int step, const int ibox, InitializeSxSyWithBeam(lev); // Deposit Sx and Sy for every plasma species - m_multi_plasma.ExplicitDeposition(m_fields, m_laser, geom[lev], lev); + m_multi_plasma.ExplicitDeposition(m_fields, m_multi_laser, geom[lev], lev); // Solves Bx, By using Sx, Sy and chi ExplicitMGSolveBxBy(lev, WhichSlice::This); @@ -664,7 +664,7 @@ Hipace::ExplicitSolveOneSubSlice (const int lev, const int step, const int ibox, // shift and update force terms, push plasma particles // don't shift force terms again if salame was used - m_multi_plasma.AdvanceParticles(m_fields, m_laser, geom[lev], + m_multi_plasma.AdvanceParticles(m_fields, m_multi_laser, geom[lev], false, true, true, !do_salame, lev); // Push beam particles @@ -685,13 +685,13 @@ Hipace::PredictorCorrectorSolveOneSubSlice (const int lev, const int step, const } // push plasma - m_multi_plasma.AdvanceParticles(m_fields, m_laser, geom[lev], false, + m_multi_plasma.AdvanceParticles(m_fields, m_multi_laser, geom[lev], false, true, false, false, lev); if (m_do_tiling) m_multi_plasma.TileSort(bx, geom[lev]); // deposit jx jy jz rho and maybe chi m_multi_plasma.DepositCurrent( - m_fields, m_laser, WhichSlice::This, false, true, true, true, m_use_laser, geom[lev], lev); + m_fields, m_multi_laser, WhichSlice::This, false, true, true, true, m_use_laser, geom[lev], lev); m_fields.AddRhoIons(lev); @@ -747,7 +747,7 @@ Hipace::ResetLaser () HIPACE_PROFILE("Hipace::ResetLaser()"); for (int sl=WhichLaserSlice::nm1j00; slalloc(buffer_size); @@ -1198,9 +1198,9 @@ Hipace::Wait (const int step, int it, bool only_ghost) // Receive laser { if (only_ghost) return; - if (!m_laser.m_use_laser) return; + if (!m_multi_laser.m_use_laser) return; AMREX_ALWAYS_ASSERT(nz_laser > 0); - amrex::FArrayBox& laser_fab = m_laser.getFAB(); + amrex::FArrayBox& laser_fab = m_multi_laser.getFAB(); amrex::Array4 laser_arr = laser_fab.array(); const amrex::Box& bx = laser_fab.box(); // does not include ghost cells AMREX_ALWAYS_ASSERT_WITH_MESSAGE( @@ -1209,7 +1209,7 @@ Hipace::Wait (const int step, int it, bool only_ghost) const std::size_t nreals = bx.numPts()*laser_fab.nComp(); MPI_Status lstatus; - if (m_laser.is3dOnHost()) { + if (m_multi_laser.is3dOnHost()) { // Directly receive envelope in laser fab MPI_Recv(laser_fab.dataPtr(), nreals, amrex::ParallelDescriptor::Mpi_typemap::type(), @@ -1249,8 +1249,8 @@ Hipace::Notify (const int step, const int it, const bool only_time = m_physical_time >= m_max_time; NotifyFinish(it, only_ghost, only_time); // finish the previous send int nz_laser = 0; - if (m_laser.m_use_laser){ - const amrex::Box& laser_bx = m_laser.getFAB().box(); + if (m_multi_laser.m_use_laser){ + const amrex::Box& laser_bx = m_multi_laser.getFAB().box(); nz_laser = laser_bx.bigEnd(2) - laser_bx.smallEnd(2) + 1; } const int nbeams = m_multi_beam.get_nbeams(); @@ -1309,7 +1309,7 @@ Hipace::Notify (const int step, const int it, // Send beam particles. Currently only one tile. { const amrex::Long np_total = std::accumulate(np_snd.begin(), np_snd.begin()+nbeams, 0); - if (np_total == 0 && !m_laser.m_use_laser) return; + if (np_total == 0 && !m_multi_laser.m_use_laser) return; const amrex::Long psize = sizeof(BeamParticleContainer::SuperParticleType); const amrex::Long buffer_size = psize*np_total; char*& psend_buffer = only_ghost ? m_psend_buffer_ghost : m_psend_buffer; @@ -1402,14 +1402,14 @@ Hipace::Notify (const int step, const int it, // Send laser data { if (only_ghost) return; - if (!m_laser.m_use_laser) return; - const amrex::FArrayBox& laser_fab = m_laser.getFAB(); + if (!m_multi_laser.m_use_laser) return; + const amrex::FArrayBox& laser_fab = m_multi_laser.getFAB(); amrex::Array4 const& laser_arr = laser_fab.array(); const amrex::Box& lbx = laser_fab.box(); // does not include ghost cells const std::size_t nreals = lbx.numPts()*laser_fab.nComp(); m_lsend_buffer = (amrex::Real*)amrex::The_Pinned_Arena()->alloc (sizeof(amrex::Real)*nreals); - if (m_laser.is3dOnHost()) { + if (m_multi_laser.is3dOnHost()) { amrex::Gpu::streamSynchronize(); // Copy from laser envelope 3D array (on host) to MPI buffer (on host) laser_fab.copyToMem(lbx, 0, laser_fab.nComp(), m_lsend_buffer); @@ -1521,7 +1521,7 @@ Hipace::FillDiagnostics (const int lev, int i_slice) if (m_diags.hasField()[lev]) { m_fields.Copy(lev, i_slice, m_diags.getGeom()[lev], m_diags.getF(lev), m_diags.getF(lev).box(), Geom(lev), - m_diags.getCompsIdx(), m_diags.getNFields(), m_laser); + m_diags.getCompsIdx(), m_diags.getNFields(), m_multi_laser); } } diff --git a/src/fields/Fields.H b/src/fields/Fields.H index d5cfda3040..45cffd82a7 100644 --- a/src/fields/Fields.H +++ b/src/fields/Fields.H @@ -11,7 +11,7 @@ #include "fft_poisson_solver/FFTPoissonSolver.H" #include "diagnostics/Diagnostic.H" -#include "laser/Laser.H" +#include "laser/MultiLaser.H" #include "utils/GPUUtil.H" #include @@ -21,7 +21,7 @@ #include class Hipace; -class Laser; +class MultiLaser; /** \brief describes which slice with respect to the currently calculated is used */ struct WhichSlice { @@ -158,12 +158,12 @@ public: * \param[in] calc_geom main geometry * \param[in] diag_comps_vect the field components to copy * \param[in] ncomp number of components to copy - * \param[in] laser Laser object + * \param[in] multi_laser MultiLaser object */ void Copy (const int lev, const int i_slice, const amrex::Geometry& diag_geom, amrex::FArrayBox& diag_fab, amrex::Box diag_box, const amrex::Geometry& calc_geom, const amrex::Gpu::DeviceVector& diag_comps_vect, const int ncomp, - Laser& laser); + MultiLaser& multi_laser); /** \brief Shift slices by 1 element: slices (1,2) are then stored in (2,3). * diff --git a/src/fields/Fields.cpp b/src/fields/Fields.cpp index 0c76401aa9..1e1e9d4a20 100644 --- a/src/fields/Fields.cpp +++ b/src/fields/Fields.cpp @@ -406,7 +406,7 @@ void Fields::Copy (const int lev, const int i_slice, const amrex::Geometry& diag_geom, amrex::FArrayBox& diag_fab, amrex::Box diag_box, const amrex::Geometry& calc_geom, const amrex::Gpu::DeviceVector& diag_comps_vect, const int ncomp, - Laser& laser) + MultiLaser& multi_laser) { HIPACE_PROFILE("Fields::Copy()"); constexpr int depos_order_xy = 1; @@ -461,7 +461,7 @@ Fields::Copy (const int lev, const int i_slice, const amrex::Geometry& diag_geom if (diag_box.isEmpty()) return; auto& slice_mf = m_slices[lev][WhichSlice::This]; auto slice_func = interpolated_field_xy{{slice_mf}, calc_geom}; - auto& laser_mf = laser.getSlices(WhichLaserSlice::n00j00); + auto& laser_mf = multi_laser.getSlices(WhichLaserSlice::n00j00); auto laser_func = interpolated_field_xy{{laser_mf}, calc_geom}; #ifdef AMREX_USE_GPU @@ -493,7 +493,7 @@ Fields::Copy (const int lev, const int i_slice, const amrex::Geometry& diag_geom diag_array(i,j,k,n) += rel_z_data[k-k_min] * slice_array(x,y,m); }); - if (!laser.m_use_laser) continue; + if (!multi_laser.m_use_laser) continue; auto laser_array = laser_func.array(mfi); amrex::ParallelFor(diag_box, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept diff --git a/src/laser/CMakeLists.txt b/src/laser/CMakeLists.txt index 2e94fedfc7..3e3fc83919 100644 --- a/src/laser/CMakeLists.txt +++ b/src/laser/CMakeLists.txt @@ -1,4 +1,4 @@ target_sources(HiPACE PRIVATE - Laser.cpp + MultiLaser.cpp ) diff --git a/src/laser/Laser.H b/src/laser/MultiLaser.H similarity index 98% rename from src/laser/Laser.H rename to src/laser/MultiLaser.H index c99678bc1f..9d786ba4a1 100644 --- a/src/laser/Laser.H +++ b/src/laser/MultiLaser.H @@ -1,5 +1,5 @@ -#ifndef LASER_H_ -#define LASER_H_ +#ifndef MULTILASER_H_ +#define MULTILASER_H_ #include "fields/Fields.H" #include "mg_solver/HpMultiGrid.H" @@ -62,7 +62,7 @@ struct WhichLaserSlice { class Fields; -class Laser +class MultiLaser { using SpectralFieldLoc = amrex::BaseFab >; @@ -74,12 +74,12 @@ private: public: /** Constructor */ - explicit Laser () + explicit MultiLaser () { ReadParameters(); } - ~Laser () + ~MultiLaser () { if (!m_use_laser) return; if (m_solver_type == "fft") { @@ -223,4 +223,4 @@ private: #endif }; -#endif // LASER_H_ +#endif // MULTILASER_H_ diff --git a/src/laser/Laser.cpp b/src/laser/MultiLaser.cpp similarity index 97% rename from src/laser/Laser.cpp rename to src/laser/MultiLaser.cpp index dfbe4b2695..684a62d89b 100644 --- a/src/laser/Laser.cpp +++ b/src/laser/MultiLaser.cpp @@ -1,4 +1,4 @@ -#include "Laser.H" +#include "MultiLaser.H" #include "utils/Constants.H" #include "Hipace.H" #include "utils/HipaceProfilerWrapper.H" @@ -17,7 +17,7 @@ #endif void -Laser::ReadParameters () +MultiLaser::ReadParameters () { amrex::ParmParse pp(m_name); queryWithParser(pp, "use_laser", m_use_laser); @@ -63,12 +63,12 @@ Laser::ReadParameters () void -Laser::InitData (const amrex::BoxArray& slice_ba, +MultiLaser::InitData (const amrex::BoxArray& slice_ba, const amrex::DistributionMapping& slice_dm) { if (!m_use_laser) return; - HIPACE_PROFILE("Laser::InitData()"); + HIPACE_PROFILE("MultiLaser::InitData()"); // Alloc 2D slices // Need at least 1 guard cell transversally for transverse derivative @@ -128,12 +128,12 @@ Laser::InitData (const amrex::BoxArray& slice_ba, } void -Laser::Init3DEnvelope (int step, amrex::Box bx, const amrex::Geometry& gm) +MultiLaser::Init3DEnvelope (int step, amrex::Box bx, const amrex::Geometry& gm) { if (!m_use_laser) return; - HIPACE_PROFILE("Laser::Init3DEnvelope()"); + HIPACE_PROFILE("MultiLaser::Init3DEnvelope()"); // Allocate the 3D field on this box // Note: box has no guard cells m_F.resize(bx, m_nfields_3d, m_3d_on_host ? amrex::The_Pinned_Arena() : amrex::The_Arena()); @@ -163,13 +163,13 @@ Laser::Init3DEnvelope (int step, amrex::Box bx, const amrex::Geometry& gm) } void -Laser::Copy (int isl, bool to3d) +MultiLaser::Copy (int isl, bool to3d) { if (!m_use_laser) return; using namespace amrex::literals; - HIPACE_PROFILE("Laser::Copy()"); + HIPACE_PROFILE("MultiLaser::Copy()"); amrex::MultiFab& nm1j00 = m_slices[WhichLaserSlice::nm1j00]; amrex::MultiFab& nm1jp1 = m_slices[WhichLaserSlice::nm1jp1]; @@ -222,7 +222,7 @@ Laser::Copy (int isl, bool to3d) } void -Laser::AdvanceSlice (const Fields& fields, const amrex::Geometry& geom, amrex::Real dt, int step) +MultiLaser::AdvanceSlice (const Fields& fields, const amrex::Geometry& geom, amrex::Real dt, int step) { if (!m_use_laser) return; @@ -237,10 +237,10 @@ Laser::AdvanceSlice (const Fields& fields, const amrex::Geometry& geom, amrex::R } void -Laser::AdvanceSliceMG (const Fields& fields, const amrex::Geometry& geom, amrex::Real dt, int step) +MultiLaser::AdvanceSliceMG (const Fields& fields, const amrex::Geometry& geom, amrex::Real dt, int step) { - HIPACE_PROFILE("Laser::AdvanceSliceMG()"); + HIPACE_PROFILE("MultiLaser::AdvanceSliceMG()"); using namespace amrex::literals; using Complex = amrex::GpuComplex; @@ -453,10 +453,10 @@ Laser::AdvanceSliceMG (const Fields& fields, const amrex::Geometry& geom, amrex: } void -Laser::AdvanceSliceFFT (const Fields& fields, const amrex::Geometry& geom, const amrex::Real dt, int step) +MultiLaser::AdvanceSliceFFT (const Fields& fields, const amrex::Geometry& geom, const amrex::Real dt, int step) { - HIPACE_PROFILE("Laser::AdvanceSliceFFT()"); + HIPACE_PROFILE("MultiLaser::AdvanceSliceFFT()"); using namespace amrex::literals; using Complex = amrex::GpuComplex; @@ -694,11 +694,11 @@ Laser::AdvanceSliceFFT (const Fields& fields, const amrex::Geometry& geom, const } void -Laser::InitLaserSlice (const amrex::Geometry& geom, const int islice) +MultiLaser::InitLaserSlice (const amrex::Geometry& geom, const int islice) { if (!m_use_laser) return; - HIPACE_PROFILE("Laser::InitLaserSlice()"); + HIPACE_PROFILE("MultiLaser::InitLaserSlice()"); using namespace amrex::literals; using Complex = amrex::GpuComplex; diff --git a/src/particles/deposition/ExplicitDeposition.H b/src/particles/deposition/ExplicitDeposition.H index 1e0275bd7b..3ab6723d4c 100644 --- a/src/particles/deposition/ExplicitDeposition.H +++ b/src/particles/deposition/ExplicitDeposition.H @@ -14,12 +14,12 @@ /** Depose Sx and Sy of particles in species plasma into the current 2D slice in fields * \param[in] plasma species of which the current is deposited * \param[in,out] fields the general field class, modified by this function - * \param[in] laser that affects the plasma during the deposition + * \param[in] multi_laser Lasers that affects the plasma during the deposition * \param[in] gm Geometry of the simulation, to get the cell size etc. * \param[in] lev MR level */ void -ExplicitDeposition (PlasmaParticleContainer& plasma, Fields& fields, const Laser& laser, +ExplicitDeposition (PlasmaParticleContainer& plasma, Fields& fields, const MultiLaser& multi_laser, amrex::Geometry const& gm, const int lev); #endif // EXPLICITDEPOSITION_H_ diff --git a/src/particles/deposition/ExplicitDeposition.cpp b/src/particles/deposition/ExplicitDeposition.cpp index f22deead7e..67f7c1fae0 100644 --- a/src/particles/deposition/ExplicitDeposition.cpp +++ b/src/particles/deposition/ExplicitDeposition.cpp @@ -16,7 +16,7 @@ #include "AMReX_GpuLaunch.H" void -ExplicitDeposition (PlasmaParticleContainer& plasma, Fields& fields, const Laser& laser, +ExplicitDeposition (PlasmaParticleContainer& plasma, Fields& fields, const MultiLaser& multi_laser, amrex::Geometry const& gm, const int lev) { HIPACE_PROFILE("ExplicitDeposition()"); using namespace amrex::literals; @@ -48,8 +48,8 @@ ExplicitDeposition (PlasmaParticleContainer& plasma, Fields& fields, const Laser plasma.m_can_ionize ? soa.GetIntData(PlasmaIdx::ion_lev).data() : nullptr; // Construct empty Array4 with one z slice so that Array3 constructor works for no laser - const Array3 a_laser_arr = laser.m_use_laser ? - laser.getSlices(WhichLaserSlice::n00j00).const_array(pti) : + const Array3 a_laser_arr = multi_laser.m_use_laser ? + multi_laser.getSlices(WhichLaserSlice::n00j00).const_array(pti) : amrex::Array4(nullptr, {0,0,0}, {0,0,1}, 0); const amrex::Real x_pos_offset = GetPosOffset(0, gm, isl_fab.box()); @@ -71,7 +71,7 @@ ExplicitDeposition (PlasmaParticleContainer& plasma, Fields& fields, const Laser amrex::TypeList, // depos_order amrex::CompileTimeOptions, // can_ionize amrex::CompileTimeOptions>{}, // use_laser - {Hipace::m_depos_order_xy, plasma.m_can_ionize, laser.m_use_laser}, + {Hipace::m_depos_order_xy, plasma.m_can_ionize, multi_laser.m_use_laser}, pti.numParticles(), [=] AMREX_GPU_DEVICE (int ip, auto a_depos_order, auto can_ionize, auto use_laser) { constexpr int depos_order = a_depos_order.value; diff --git a/src/particles/deposition/PlasmaDepositCurrent.H b/src/particles/deposition/PlasmaDepositCurrent.H index 404717fa79..a68da95e8f 100644 --- a/src/particles/deposition/PlasmaDepositCurrent.H +++ b/src/particles/deposition/PlasmaDepositCurrent.H @@ -12,13 +12,13 @@ #include "particles/sorting/TileSort.H" #include "fields/Fields.H" #include "utils/Constants.H" -#include "laser/Laser.H" +#include "laser/MultiLaser.H" #include "Hipace.H" /** Depose current of particles in species plasma into the current 2D slice in fields * \param[in] plasma species of which the current is deposited * \param[in,out] fields the general field class, modified by this function - * \param[in] laser that affects the plasma during the deposition + * \param[in] multi_laser MultiLaser that affects the plasma during the deposition * \param[in] which_slice defines if this or the next slice is handled * \param[in] temp_slice if true, the temporary data (x_temp, ...) is used * \param[in] deposit_jx_jy if true, deposit to jx and jy @@ -31,7 +31,7 @@ * \param[in] bin_size tile size (square) */ void -DepositCurrent (PlasmaParticleContainer& plasma, Fields & fields, const Laser& laser, +DepositCurrent (PlasmaParticleContainer& plasma, Fields & fields, const MultiLaser& multi_laser, const int which_slice, const bool temp_slice, const bool deposit_jx_jy, const bool deposit_jz, const bool deposit_rho, bool deposit_chi, amrex::Geometry const& gm, int const lev, diff --git a/src/particles/deposition/PlasmaDepositCurrent.cpp b/src/particles/deposition/PlasmaDepositCurrent.cpp index abfda5336c..cc01d123b8 100644 --- a/src/particles/deposition/PlasmaDepositCurrent.cpp +++ b/src/particles/deposition/PlasmaDepositCurrent.cpp @@ -20,7 +20,7 @@ void -DepositCurrent (PlasmaParticleContainer& plasma, Fields & fields, const Laser& laser, +DepositCurrent (PlasmaParticleContainer& plasma, Fields & fields, const MultiLaser& multi_laser, const int which_slice, const bool temp_slice, const bool deposit_jx_jy, const bool deposit_jz, const bool deposit_rho, const bool deposit_chi, amrex::Geometry const& gm, int const lev, @@ -62,7 +62,7 @@ DepositCurrent (PlasmaParticleContainer& plasma, Fields & fields, const Laser& l amrex::Vector& tmp_dens = fields.getTmpDensities(); // extract the laser Fields - const amrex::MultiFab& a_mf = laser.getSlices(WhichLaserSlice::n00j00); + const amrex::MultiFab& a_mf = multi_laser.getSlices(WhichLaserSlice::n00j00); // Offset for converting positions to indexes const amrex::Real x_pos_offset = GetPosOffset(0, gm, isl_fab.box()); @@ -86,7 +86,7 @@ DepositCurrent (PlasmaParticleContainer& plasma, Fields & fields, const Laser& l // Extract laser array from MultiFab const Array3 a_laser_arr = - laser.m_use_laser ? a_mf[pti].const_array() : amrex::Array4(); + multi_laser.m_use_laser ? a_mf[pti].const_array() : amrex::Array4(); // Extract box properties const amrex::Real invvol = Hipace::m_normalized_units ? 1._rt : 1._rt/(dx[0]*dx[1]*dx[2]); @@ -174,7 +174,7 @@ DepositCurrent (PlasmaParticleContainer& plasma, Fields & fields, const Laser& l Hipace::m_outer_depos_loop, plasma.m_can_ionize, do_tiling, - laser.m_use_laser + multi_laser.m_use_laser }, num_particles, [=] AMREX_GPU_DEVICE (int idx, auto depos_order, auto outer_depos_loop, diff --git a/src/particles/plasma/MultiPlasma.H b/src/particles/plasma/MultiPlasma.H index c83949fe8f..17d29fbee0 100644 --- a/src/particles/plasma/MultiPlasma.H +++ b/src/particles/plasma/MultiPlasma.H @@ -11,7 +11,7 @@ #include "PlasmaParticleContainer.H" #include "particles/sorting/TileSort.H" #include "fields/Fields.H" -#include "laser/Laser.H" +#include "laser/MultiLaser.H" #include "particles/collisions/CoulombCollision.H" class MultiPlasma @@ -42,7 +42,7 @@ public: /** Loop over plasma species and depose their currents into the current 2D slice in fields * * \param[in,out] fields the general field class, modified by this function - * \param[in] laser that affects the plasma during the deposition + * \param[in] multi_laser Lasers that affects the plasma during the deposition * \param[in] which_slice defines if this or the next slice is handled * \param[in] temp_slice if true, the temporary data (x_temp, ...) is used * \param[in] deposit_jx_jy if true, deposit to jx and jy @@ -53,18 +53,18 @@ public: * \param[in] lev MR level */ void DepositCurrent ( - Fields & fields, const Laser & laser, int which_slice, bool temp_slice, bool deposit_jx_jy, + Fields & fields, const MultiLaser & multi_laser, int which_slice, bool temp_slice, bool deposit_jx_jy, bool deposit_jz, bool deposit_rho, bool deposit_chi, amrex::Geometry const& gm, int const lev); /** Loop over plasma species and depose Sx and Sy into the current 2D slice in fields * * \param[in,out] fields the general field class, modified by this function - * \param[in] laser that affects the plasma during the deposition + * \param[in] multi_laser Lasers that affects the plasma during the deposition * \param[in] gm Geometry of the simulation, to get the cell size etc. * \param[in] lev MR level */ - void ExplicitDeposition (Fields& fields, const Laser& laser, + void ExplicitDeposition (Fields& fields, const MultiLaser& multi_laser, amrex::Geometry const& gm, int const lev); /** \brief Return max density, to compute the adaptive time step. @@ -77,7 +77,7 @@ public: /** \brief Loop over plasma species and Gather fields, update forces and push particles * * \param[in,out] fields the general field class, modified by this function - * \param[in] laser that affects the plasma during the deposition + * \param[in] multi_laser Lasers that affects the plasma during the deposition * \param[in] gm Geometry of the simulation, to get the cell size etc. * \param[in] temp_slice if true, the temporary data (x_temp, ...) will be used * \param[in] do_push boolean to define if plasma particles are pushed @@ -86,7 +86,7 @@ public: * \param[in] lev MR level */ void AdvanceParticles ( - const Fields & fields, const Laser & laser, amrex::Geometry const& gm, bool temp_slice, + const Fields & fields, const MultiLaser & multi_laser, amrex::Geometry const& gm, bool temp_slice, bool do_push, bool do_update, bool do_shift, int lev); /** \brief Resets the particle position x, y, to x_prev, y_prev @@ -99,13 +99,13 @@ public: /** \brief Loop over plasma species and deposit their neutralizing background, if needed * * \param[in,out] fields the general field class, modified by this function - * \param[in] laser that affects the plasma during the deposition + * \param[in] multi_laser that affects the plasma during the deposition * \param[in] which_slice slice in which the densities are deposited * \param[in] gm Geometry of the simulation, to get the cell size etc. * \param[in] nlev number of MR levels */ void DepositNeutralizingBackground ( - Fields & fields, const Laser & laser, int which_slice, amrex::Geometry const& gm, + Fields & fields, const MultiLaser & multi_laser, int which_slice, amrex::Geometry const& gm, int const nlev); /** Calculates Ionization Probability and makes new Plasma Particles diff --git a/src/particles/plasma/MultiPlasma.cpp b/src/particles/plasma/MultiPlasma.cpp index edb6f66404..b519069dab 100644 --- a/src/particles/plasma/MultiPlasma.cpp +++ b/src/particles/plasma/MultiPlasma.cpp @@ -82,34 +82,34 @@ MultiPlasma::maxDensity () const void MultiPlasma::DepositCurrent ( - Fields & fields, const Laser & laser, int which_slice, bool temp_slice, bool deposit_jx_jy, - bool deposit_jz, bool deposit_rho, bool deposit_chi, amrex::Geometry const& gm, - int const lev) + Fields & fields, const MultiLaser & multi_laser, int which_slice, bool temp_slice, + bool deposit_jx_jy, bool deposit_jz, bool deposit_rho, bool deposit_chi, + amrex::Geometry const& gm, int const lev) { for (int i=0; i const& a_arr = use_laser ? diff --git a/src/salame/Salame.cpp b/src/salame/Salame.cpp index 9f0d4e8262..f4362bb4b5 100644 --- a/src/salame/Salame.cpp +++ b/src/salame/Salame.cpp @@ -30,14 +30,14 @@ SalameModule (Hipace* hipace, const int n_iter, const bool do_advance, int& last // STEP 1: Calculate what Ez would be with the initial SALAME beam weight // advance plasma to the temp slice, only shift once - hipace->m_multi_plasma.AdvanceParticles(hipace->m_fields, hipace->m_laser, hipace->Geom(lev), + hipace->m_multi_plasma.AdvanceParticles(hipace->m_fields, hipace->m_multi_laser, hipace->Geom(lev), true, true, true, iter==0, lev); hipace->m_fields.duplicate(lev, WhichSlice::Salame, {"jx", "jy"}, WhichSlice::Next, {"jx_beam", "jy_beam"}); // deposit plasma jx and jy on the next temp slice, to the SALANE slice - hipace->m_multi_plasma.DepositCurrent(hipace->m_fields, hipace->m_laser, + hipace->m_multi_plasma.DepositCurrent(hipace->m_fields, hipace->m_multi_laser, WhichSlice::Salame, true, true, false, false, false, hipace->Geom(lev), lev); // use an initial guess of zero for Bx and By in MG solver to reduce relative error @@ -64,7 +64,7 @@ SalameModule (Hipace* hipace, const int n_iter, const bool do_advance, int& last if (do_advance) { SalameOnlyAdvancePlasma(hipace, lev); - hipace->m_multi_plasma.DepositCurrent(hipace->m_fields, hipace->m_laser, + hipace->m_multi_plasma.DepositCurrent(hipace->m_fields, hipace->m_multi_laser, WhichSlice::Salame, true, true, false, false, false, hipace->Geom(lev), lev); } else { SalameGetJxJyFromBxBy(hipace, lev); @@ -110,7 +110,7 @@ SalameModule (Hipace* hipace, const int n_iter, const bool do_advance, int& last hipace->InitializeSxSyWithBeam(lev); - hipace->m_multi_plasma.ExplicitDeposition(hipace->m_fields, hipace->m_laser, + hipace->m_multi_plasma.ExplicitDeposition(hipace->m_fields, hipace->m_multi_laser, hipace->Geom(lev), lev); hipace->ExplicitMGSolveBxBy(lev, WhichSlice::This); From fb7131113287c5b740e61c990626e6c01c902258 Mon Sep 17 00:00:00 2001 From: Maxence Thevenet Date: Thu, 24 Nov 2022 13:13:42 +0100 Subject: [PATCH 2/9] option to have two lasers on 1 grid --- examples/laser/inputs_SI | 7 +- src/laser/CMakeLists.txt | 1 + src/laser/Laser.H | 43 +++++ src/laser/Laser.cpp | 35 +++++ src/laser/MultiLaser.H | 36 +++-- src/laser/MultiLaser.cpp | 147 +++++++++++++----- tests/laser_blowout_wake_explicit.1Rank.sh | 4 +- tests/laser_blowout_wake_explicit.SI.1Rank.sh | 4 +- tests/laser_evolution.SI.2Rank.sh | 4 +- 9 files changed, 221 insertions(+), 60 deletions(-) create mode 100644 src/laser/Laser.H create mode 100644 src/laser/Laser.cpp diff --git a/examples/laser/inputs_SI b/examples/laser/inputs_SI index 4fb6bd71eb..c4c3db6723 100644 --- a/examples/laser/inputs_SI +++ b/examples/laser/inputs_SI @@ -12,12 +12,13 @@ hipace.do_tiling = 0 geometry.prob_lo = -6.*kp_inv -6.*kp_inv -8.*kp_inv geometry.prob_hi = 6.*kp_inv 6.*kp_inv 6.*kp_inv -laser.use_laser = 1 +lasers.names = laser +lasers.lambda0 = .8e-6 + laser.a0 = 1 laser.position_mean = 0. 0. 0 -laser.w0 = 2.*kp_inv 2.*kp_inv +laser.w0 = 2.*kp_inv laser.L0 = 2.*kp_inv -laser.lambda0 = .8e-6 laser.focal_distance = 0.001 hipace.bxby_solver=explicit diff --git a/src/laser/CMakeLists.txt b/src/laser/CMakeLists.txt index 3e3fc83919..99a73ed011 100644 --- a/src/laser/CMakeLists.txt +++ b/src/laser/CMakeLists.txt @@ -1,4 +1,5 @@ target_sources(HiPACE PRIVATE MultiLaser.cpp + Laser.cpp ) diff --git a/src/laser/Laser.H b/src/laser/Laser.H new file mode 100644 index 0000000000..8d51cf2d31 --- /dev/null +++ b/src/laser/Laser.H @@ -0,0 +1,43 @@ +/* Copyright 2022 + * + * This file is part of HiPACE++. + * + * Authors: MaxThevenet, AlexanderSinn + * Severin Diederichs, atmyers, Angel Ferran Pousa + * License: BSD-3-Clause-LBNL + */ + +#ifndef LASER_H_ +#define LASER_H_ + +#include +#include + +class Laser +{ +public: + Laser (std::string name); +/* + amrex::Real getA0 () {return m_a0}; + amrex::Real getK0 () {return m_k0}; + amrex::Real getW0 () {return m_w0}; + amrex::Real getL0 () {return m_l0}; + amrex::Real getTau () {return m_tau}; + amrex::Real getLambda () {return m_lambda0}; + amrex::Real getFoc () {return m_focal_distance}; + amrex::Real getX0 () {return m_position_mean[0]}; + amrex::Real getY0 () {return m_position_mean[1]}; + amrex::Real getZ0 () {return m_position_mean[2]}; +*/ + std::string m_name {""}; + amrex::Real m_a0 {0.}; /**< Laser peak normalized amplitude */ + amrex::Real m_w0 {0.}; /**< Laser waist */ + amrex::Real m_L0 {0.}; /**< Laser length (HW 1/e in amplitude) */ + amrex::Real m_tau {0.}; /**< Laser duration (HW 1/e in amplitude) */ + /** Focal distance of the laser pulse */ + amrex::Real m_focal_distance {0.}; + /** Average position of the Gaussian laser pulse */ + amrex::RealVect m_position_mean {0., 0., 0.}; +}; + +#endif // LASER_H_ diff --git a/src/laser/Laser.cpp b/src/laser/Laser.cpp new file mode 100644 index 0000000000..c36090ac16 --- /dev/null +++ b/src/laser/Laser.cpp @@ -0,0 +1,35 @@ +/* Copyright 2022 + * + * This file is part of HiPACE++. + * + * Authors: MaxThevenet, AlexanderSinn + * Severin Diederichs, atmyers, Angel Ferran Pousa + * License: BSD-3-Clause-LBNL + */ + +#include "Laser.H" +#include "utils/Parser.H" +#include "Hipace.H" + +#include +#include + +Laser::Laser (std::string name) +{ + m_name = name; + amrex::ParmParse pp(m_name); + queryWithParser(pp, "a0", m_a0); + queryWithParser(pp, "w0", m_w0); + bool length_is_specified = queryWithParser(pp, "L0", m_L0);; + bool duration_is_specified = queryWithParser(pp, "tau", m_tau); + AMREX_ALWAYS_ASSERT_WITH_MESSAGE( length_is_specified + duration_is_specified == 1, + "Please specify exlusively either the pulse length L0 or the duration tau of the laser"); + if (duration_is_specified) m_L0 = m_tau/get_phys_const().c; + queryWithParser(pp, "focal_distance", m_focal_distance); + + amrex::Array loc_array; + queryWithParser(pp, "position_mean", loc_array); + for (int idim=0; idim < AMREX_SPACEDIM; ++idim) m_position_mean[idim] = loc_array[idim]; + AMREX_ALWAYS_ASSERT(m_position_mean[0] == 0.); + AMREX_ALWAYS_ASSERT(m_position_mean[1] == 0.); +} diff --git a/src/laser/MultiLaser.H b/src/laser/MultiLaser.H index 9d786ba4a1..12e108e361 100644 --- a/src/laser/MultiLaser.H +++ b/src/laser/MultiLaser.H @@ -1,6 +1,16 @@ +/* Copyright 2022 + * + * This file is part of HiPACE++. + * + * Authors: MaxThevenet, AlexanderSinn + * Severin Diederichs, atmyers, Angel Ferran Pousa + * License: BSD-3-Clause-LBNL + */ + #ifndef MULTILASER_H_ #define MULTILASER_H_ +#include "Laser.H" #include "fields/Fields.H" #include "mg_solver/HpMultiGrid.H" @@ -171,16 +181,24 @@ public: private: - std::string m_name = "laser"; /**< name of the laser */ - amrex::Real m_a0 {0.}; /**< Laser peak normalized amplitude */ - amrex::RealVect m_w0 {0., 0., 0.}; /**< Laser waist in x and y (the third value is omitted) */ - amrex::Real m_L0 {0.}; /**< Laser length (HW 1/e in amplitude) */ - amrex::Real m_tau {0.}; /**< Laser duration (HW 1/e in amplitude) */ - amrex::Real m_lambda0 {0.}; /**< Laser central wavelength */ - /** Average position of the Gaussian laser pulse */ - amrex::RealVect m_position_mean {0., 0., 0.}; +/* + amrex::Gpu::DeviceVector getA0s (); + amrex::Gpu::DeviceVector getK0s (); + amrex::Gpu::DeviceVector getW0s (); + amrex::Gpu::DeviceVector getX0s (); + amrex::Gpu::DeviceVector getY0s (); + amrex::Gpu::DeviceVector getZ0s (); + amrex::Gpu::DeviceVector getL0s (); + amrex::Gpu::DeviceVector getZfocs (); +*/ + /** Laser central wavelength. + * he central wavelength influences the solver. As long as all the lasers are on the same grid + * (part of MultiLaser), this must be a property of MultiLaser. */ + amrex::Real m_lambda0 {0.}; + amrex::Vector m_names; /**< name of the laser */ + int m_nlasers; /**< Number of laser pulses */ + amrex::Vector m_all_lasers; /**< Each is a laser pulse */ int m_3d_on_host {0};/** Whether the 3D laser envelope is stored in host or device memory */ - amrex::Real m_focal_distance {0.}; /** Number of guard cells for slices MultiFab */ amrex::IntVect m_slices_nguards = {-1, -1, -1}; std::string m_solver_type = "multigrid"; diff --git a/src/laser/MultiLaser.cpp b/src/laser/MultiLaser.cpp index 684a62d89b..172b7e0248 100644 --- a/src/laser/MultiLaser.cpp +++ b/src/laser/MultiLaser.cpp @@ -1,3 +1,12 @@ +/* Copyright 2022 + * + * This file is part of HiPACE++. + * + * Authors: MaxThevenet, AlexanderSinn + * Severin Diederichs, atmyers, Angel Ferran Pousa + * License: BSD-3-Clause-LBNL + */ + #include "MultiLaser.H" #include "utils/Constants.H" #include "Hipace.H" @@ -19,30 +28,19 @@ void MultiLaser::ReadParameters () { - amrex::ParmParse pp(m_name); - queryWithParser(pp, "use_laser", m_use_laser); - queryWithParser(pp, "a0", m_a0); + amrex::ParmParse pp("lasers"); + getWithParser(pp, "names", m_names); + + m_use_laser = m_names[0] != "no_laser"; + if (!m_use_laser) return; #if defined(AMREX_USE_HIP) amrex::Abort("Laser solver not implemented with HIP"); #endif - amrex::Vector tmp_vector; - if (queryWithParser(pp, "w0", tmp_vector)){ - AMREX_ALWAYS_ASSERT_WITH_MESSAGE(tmp_vector.size() == 2, - "The laser waist w0 must be provided in x and y, " - "so laser.w0 should contain 2 values"); - for (int i=0; i<2; i++) m_w0[i] = tmp_vector[i]; - } - bool length_is_specified = queryWithParser(pp, "L0", m_L0);; - bool duration_is_specified = queryWithParser(pp, "tau", m_tau); - AMREX_ALWAYS_ASSERT_WITH_MESSAGE( length_is_specified + duration_is_specified == 1, - "Please specify exlusively either the pulse length L0 or the duration tau of the laser"); - if (duration_is_specified) m_L0 = m_tau/get_phys_const().c; + m_nlasers = m_names.size(); + getWithParser(pp, "lambda0", m_lambda0); - amrex::Array loc_array; - queryWithParser(pp, "focal_distance", m_focal_distance); - queryWithParser(pp, "position_mean", loc_array); queryWithParser(pp, "3d_on_host", m_3d_on_host); queryWithParser(pp, "use_phase", m_use_phase); queryWithParser(pp, "solver_type", m_solver_type); @@ -57,8 +55,6 @@ MultiLaser::ReadParameters () if (mg_param_given && (m_solver_type != "multigrid")) { amrex::Print()<<"WARNING: parameters laser.MG_... only active if laser.solver_type = multigrid\n"; } - - for (int idim=0; idim < AMREX_SPACEDIM; ++idim) m_position_mean[idim] = loc_array[idim]; } @@ -706,18 +702,7 @@ MultiLaser::InitLaserSlice (const amrex::Geometry& geom, const int islice) // Basic laser parameters and constants Complex I(0,1); constexpr int dcomp = 0; - const amrex::Real a0 = m_a0; const amrex::Real k0 = 2._rt*MathConst::pi/m_lambda0; - const amrex::Real w0 = m_w0[0]; - const amrex::Real x0 = m_position_mean[0]; - const amrex::Real y0 = m_position_mean[1]; - const amrex::Real z0 = m_position_mean[2]; - const amrex::Real L0 = m_L0; - const amrex::Real zfoc = m_focal_distance; - - AMREX_ALWAYS_ASSERT(m_w0[0] == m_w0[1]); - AMREX_ALWAYS_ASSERT(x0 == 0._rt); - AMREX_ALWAYS_ASSERT(y0 == 0._rt); // Get grid properties const auto plo = geom.ProbLoArray(); @@ -739,21 +724,99 @@ MultiLaser::InitLaserSlice (const amrex::Geometry& geom, const int islice) bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) { - amrex::Real z = plo[2] + (islice+0.5_rt)*dx_arr[2] - zfoc; const amrex::Real x = (i+0.5_rt)*dx_arr[0]+plo[0]; const amrex::Real y = (j+0.5_rt)*dx_arr[1]+plo[1]; - // Compute envelope for time step 0 - Complex diffract_factor = 1._rt + I * z * 2._rt/( k0 * w0 * w0 ); - Complex inv_complex_waist_2 = 1._rt /( w0 * w0 * diffract_factor ); - Complex prefactor = a0/diffract_factor; - Complex time_exponent = (z-z0+zfoc)*(z-z0+zfoc)/(L0*L0); - Complex stcfactor = prefactor * amrex::exp( - time_exponent ); - Complex exp_argument = - ( x*x + y*y ) * inv_complex_waist_2; - Complex envelope = stcfactor * amrex::exp( exp_argument ); - np1j00_arr(i,j,k,dcomp ) = envelope.real(); - np1j00_arr(i,j,k,dcomp+1) = envelope.imag(); + for (const auto& laser : m_all_lasers) { + const amrex::Real a0 = laser.m_a0; + const amrex::Real w0 = laser.m_w0; + const amrex::Real x0 = laser.m_position_mean[0]; + const amrex::Real y0 = laser.m_position_mean[1]; + const amrex::Real z0 = laser.m_position_mean[2]; + const amrex::Real L0 = laser.m_L0; + const amrex::Real zfoc = laser.m_focal_distance; + + amrex::Real z = plo[2] + (islice+0.5_rt)*dx_arr[2] - zfoc; + + // Compute envelope for time step 0 + Complex diffract_factor = 1._rt + I * z * 2._rt/( k0 * w0 * w0 ); + Complex inv_complex_waist_2 = 1._rt /( w0 * w0 * diffract_factor ); + Complex prefactor = a0/diffract_factor; + Complex time_exponent = (z-z0+zfoc)*(z-z0+zfoc)/(L0*L0); + Complex stcfactor = prefactor * amrex::exp( - time_exponent ); + Complex exp_argument = - ( x*x + y*y ) * inv_complex_waist_2; + Complex envelope = stcfactor * amrex::exp( exp_argument ); + np1j00_arr(i,j,k,dcomp ) += envelope.real(); + np1j00_arr(i,j,k,dcomp+1) += envelope.imag(); + } } ); } } +/* +amrex::Gpu::DeviceVector +MultiLaser::getA0s () +{ + amrex::Gpu::DeviceVector a0s(m_nlasers); + for (int i=0; i +MultiLaser::getK0s () +{ + amrex::Gpu::DeviceVector k0s(m_nlasers); + for (int i=0; i +MultiLaser::getW0s () +{ + amrex::Gpu::DeviceVector w0s(m_nlasers); + for (int i=0; i +MultiLaser::getX0s () +{ + amrex::Gpu::DeviceVector x0s(m_nlasers); + for (int i=0; i +MultiLaser::getY0s () +{ + amrex::Gpu::DeviceVector y0s(m_nlasers); + for (int i=0; i +MultiLaser::getX0s () +{ + amrex::Gpu::DeviceVector x0s(m_nlasers); + for (int i=0; i getX0s (); + amrex::Gpu::DeviceVector getY0s (); + amrex::Gpu::DeviceVector getZ0s (); + amrex::Gpu::DeviceVector getL0s (); + amrex::Gpu::DeviceVector getZfocs (); +*/ diff --git a/tests/laser_blowout_wake_explicit.1Rank.sh b/tests/laser_blowout_wake_explicit.1Rank.sh index ea20714db8..e69c0192fc 100755 --- a/tests/laser_blowout_wake_explicit.1Rank.sh +++ b/tests/laser_blowout_wake_explicit.1Rank.sh @@ -29,9 +29,9 @@ mpiexec -n 1 $HIPACE_EXECUTABLE $HIPACE_EXAMPLE_DIR/inputs_normalized \ beams.names = no_beam \ geometry.prob_lo = -20. -20. -8 \ geometry.prob_hi = 20. 20. 6 \ - laser.use_laser = 1 \ + lasers.names = laser \ + lasers.lambda0 = .8e-6 \ laser.a0 = 4.5 \ - laser.lambda0 = .8e-6 \ laser.position_mean = 0. 0. 0 \ laser.w0 = 4 4 \ laser.L0 = 2 \ diff --git a/tests/laser_blowout_wake_explicit.SI.1Rank.sh b/tests/laser_blowout_wake_explicit.SI.1Rank.sh index 485ac58b8c..104a600b93 100755 --- a/tests/laser_blowout_wake_explicit.SI.1Rank.sh +++ b/tests/laser_blowout_wake_explicit.SI.1Rank.sh @@ -28,9 +28,9 @@ mpiexec -n 1 $HIPACE_EXECUTABLE $HIPACE_EXAMPLE_DIR/inputs_SI \ beams.names = no_beam \ geometry.prob_lo = -20.*kp_inv -20.*kp_inv -8.*kp_inv \ geometry.prob_hi = 20.*kp_inv 20.*kp_inv 6.*kp_inv \ - laser.use_laser = 1 \ + lasers.names = laser \ + lasers.lambda0 = .8e-6 \ laser.a0 = 4.5 \ - laser.lambda0 = .8e-6 \ laser.position_mean = 0. 0. 0 \ laser.w0 = 4.*kp_inv 4.*kp_inv \ laser.L0 = 2.*kp_inv \ diff --git a/tests/laser_evolution.SI.2Rank.sh b/tests/laser_evolution.SI.2Rank.sh index 4dec0b8734..7c816e7df0 100755 --- a/tests/laser_evolution.SI.2Rank.sh +++ b/tests/laser_evolution.SI.2Rank.sh @@ -27,7 +27,7 @@ TEST_NAME="${FILE_NAME%.*}" # Run the simulation with multigrid Poisson solver mpiexec -n 2 $HIPACE_EXECUTABLE $HIPACE_EXAMPLE_DIR/inputs_SI \ - laser.solver_type = multigrid \ + lasers.solver_type = multigrid \ hipace.file_prefix = $TEST_NAME # Compare the result with theory $HIPACE_EXAMPLE_DIR/analysis_laser_vacuum.py --output-dir=$TEST_NAME @@ -36,7 +36,7 @@ rm -rf $TEST_NAME # Run the simulation with FFT Poisson solver mpiexec -n 2 $HIPACE_EXECUTABLE $HIPACE_EXAMPLE_DIR/inputs_SI \ - laser.solver_type = fft \ + lasers.solver_type = fft \ hipace.file_prefix = $TEST_NAME # Compare the result with theory $HIPACE_EXAMPLE_DIR/analysis_laser_vacuum.py --output-dir=$TEST_NAME From ab4f39f4551b62d152450ef60e3ebc01ed942c5f Mon Sep 17 00:00:00 2001 From: Maxence Thevenet Date: Thu, 24 Nov 2022 13:28:14 +0100 Subject: [PATCH 3/9] fix input files to specify lasers --- examples/beam_in_vacuum/inputs_SI | 2 ++ examples/beam_in_vacuum/inputs_normalized | 2 ++ examples/beam_in_vacuum/inputs_normalized_transverse | 3 +++ examples/blowout_wake/inputs_SI | 2 ++ examples/blowout_wake/inputs_ionization_SI | 2 ++ examples/blowout_wake/inputs_normalized | 2 ++ examples/gaussian_weight/inputs_SI | 2 ++ examples/gaussian_weight/inputs_normalized | 2 ++ examples/get_started/inputs_normalized | 4 ++++ examples/linear_wake/inputs_SI | 2 ++ examples/linear_wake/inputs_ion_motion_SI | 2 ++ examples/linear_wake/inputs_normalized | 2 ++ 12 files changed, 27 insertions(+) diff --git a/examples/beam_in_vacuum/inputs_SI b/examples/beam_in_vacuum/inputs_SI index d93440fbd1..09490b5598 100644 --- a/examples/beam_in_vacuum/inputs_SI +++ b/examples/beam_in_vacuum/inputs_SI @@ -39,4 +39,6 @@ beam2.ppc = 2 2 1 plasmas.names = no_plasma +lasers.names = no_laser + diagnostic.diag_type = xyz diff --git a/examples/beam_in_vacuum/inputs_normalized b/examples/beam_in_vacuum/inputs_normalized index 13faea779e..ce204d208d 100644 --- a/examples/beam_in_vacuum/inputs_normalized +++ b/examples/beam_in_vacuum/inputs_normalized @@ -30,4 +30,6 @@ beam.ppc = 2 2 1 plasmas.names = no_plasma +lasers.names = no_laser + diagnostic.diag_type = xyz diff --git a/examples/beam_in_vacuum/inputs_normalized_transverse b/examples/beam_in_vacuum/inputs_normalized_transverse index 6a1eea4f04..f18f35e4e5 100644 --- a/examples/beam_in_vacuum/inputs_normalized_transverse +++ b/examples/beam_in_vacuum/inputs_normalized_transverse @@ -39,4 +39,7 @@ beam2.position_mean = 0. 0. 0 beam2.position_std = 8. 0.3 1.41 plasmas.names = no_plasma + +lasers.names = no_laser + diagnostic.diag_type = xz diff --git a/examples/blowout_wake/inputs_SI b/examples/blowout_wake/inputs_SI index fb69a21500..4c2bb62748 100644 --- a/examples/blowout_wake/inputs_SI +++ b/examples/blowout_wake/inputs_SI @@ -44,4 +44,6 @@ plasma.ppc = 1 1 plasma.u_mean = 0.0 0.0 0. plasma.element = electron +lasers.names = no_laser + diagnostic.diag_type = xyz diff --git a/examples/blowout_wake/inputs_ionization_SI b/examples/blowout_wake/inputs_ionization_SI index 5611476255..0d8027a586 100644 --- a/examples/blowout_wake/inputs_ionization_SI +++ b/examples/blowout_wake/inputs_ionization_SI @@ -53,4 +53,6 @@ ion.mass_Da = 1.008 ion.initial_ion_level = 0 ion.ionization_product = elec +lasers.names = no_laser + diagnostic.diag_type = xyz diff --git a/examples/blowout_wake/inputs_normalized b/examples/blowout_wake/inputs_normalized index c973902a3e..d54837479f 100644 --- a/examples/blowout_wake/inputs_normalized +++ b/examples/blowout_wake/inputs_normalized @@ -40,4 +40,6 @@ plasma.ppc = 1 1 plasma.u_mean = 0.0 0.0 0. plasma.element = electron +lasers.names = no_laser + diagnostic.diag_type = xyz diff --git a/examples/gaussian_weight/inputs_SI b/examples/gaussian_weight/inputs_SI index 8f81250191..d3378f752f 100644 --- a/examples/gaussian_weight/inputs_SI +++ b/examples/gaussian_weight/inputs_SI @@ -29,4 +29,6 @@ beam.ppc = 2 2 1 plasmas.names = no_plasma +lasers.names = no_laser + diagnostic.diag_type = xyz diff --git a/examples/gaussian_weight/inputs_normalized b/examples/gaussian_weight/inputs_normalized index 359d08c799..bab5fb6695 100644 --- a/examples/gaussian_weight/inputs_normalized +++ b/examples/gaussian_weight/inputs_normalized @@ -29,4 +29,6 @@ beam.u_std = 3. 4. 0. plasmas.names = no_plasma +lasers.names = no_laser + diagnostic.diag_type = xyz diff --git a/examples/get_started/inputs_normalized b/examples/get_started/inputs_normalized index 6a1abfe1df..0b3f3fdb7b 100644 --- a/examples/get_started/inputs_normalized +++ b/examples/get_started/inputs_normalized @@ -36,6 +36,10 @@ plasma.element = electron # type of plasma: electron, proton, or a plasma.density(x,y,z) = 1. # density function in the respective unit systems plasma.ppc = 1 1 # particles per cell in x,y +### Laser +################################ +lasers.names = no_laser # name(s) of the laser pulses. Here, no laser pulse used. + ### Diagnostics ################################ diagnostic.diag_type = xz # 2D xz slice output. Options: xyz, xz, yz diff --git a/examples/linear_wake/inputs_SI b/examples/linear_wake/inputs_SI index c5fbe65c6b..f064340bca 100644 --- a/examples/linear_wake/inputs_SI +++ b/examples/linear_wake/inputs_SI @@ -38,4 +38,6 @@ plasma.ppc = 1 1 plasma.u_mean = 0.0 0.0 0. plasma.element = electron +lasers.names = no_laser + diagnostic.diag_type = xyz diff --git a/examples/linear_wake/inputs_ion_motion_SI b/examples/linear_wake/inputs_ion_motion_SI index ee1574ad14..ba5a8f201f 100644 --- a/examples/linear_wake/inputs_ion_motion_SI +++ b/examples/linear_wake/inputs_ion_motion_SI @@ -57,4 +57,6 @@ ions.neutralize_background = false "ions.density(x,y,z)" = ne ions.ppc = 1 1 +lasers.names = no_laser + diagnostic.diag_type = xyz diff --git a/examples/linear_wake/inputs_normalized b/examples/linear_wake/inputs_normalized index 52be059a4c..ac442354f1 100644 --- a/examples/linear_wake/inputs_normalized +++ b/examples/linear_wake/inputs_normalized @@ -36,3 +36,5 @@ plasma.ppc = 1 1 plasma.u_mean = 0.0 0.0 0. plasma.element = electron diagnostic.diag_type = xyz + +lasers.names = no_laser From 1d132dbd23c38542a83b7c9994628d973278ef7c Mon Sep 17 00:00:00 2001 From: Maxence Thevenet Date: Thu, 24 Nov 2022 13:28:44 +0100 Subject: [PATCH 4/9] eol --- src/laser/Laser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/laser/Laser.cpp b/src/laser/Laser.cpp index c36090ac16..19041f968c 100644 --- a/src/laser/Laser.cpp +++ b/src/laser/Laser.cpp @@ -31,5 +31,5 @@ Laser::Laser (std::string name) queryWithParser(pp, "position_mean", loc_array); for (int idim=0; idim < AMREX_SPACEDIM; ++idim) m_position_mean[idim] = loc_array[idim]; AMREX_ALWAYS_ASSERT(m_position_mean[0] == 0.); - AMREX_ALWAYS_ASSERT(m_position_mean[1] == 0.); + AMREX_ALWAYS_ASSERT(m_position_mean[1] == 0.); } From f2a9a8314ed9ecb0f6da441218f7567a47685a26 Mon Sep 17 00:00:00 2001 From: Maxence Thevenet Date: Thu, 24 Nov 2022 13:41:15 +0100 Subject: [PATCH 5/9] init lasers --- src/laser/MultiLaser.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/laser/MultiLaser.cpp b/src/laser/MultiLaser.cpp index 172b7e0248..2ade05b2e3 100644 --- a/src/laser/MultiLaser.cpp +++ b/src/laser/MultiLaser.cpp @@ -39,6 +39,9 @@ MultiLaser::ReadParameters () #endif m_nlasers = m_names.size(); + for (int i = 0; i < m_nlasers; ++i) { + m_all_lasers.emplace_back(Laser(m_names[i])); + } getWithParser(pp, "lambda0", m_lambda0); queryWithParser(pp, "3d_on_host", m_3d_on_host); From 0009c496ddc7920d046a678b71a5cb246bc6f568 Mon Sep 17 00:00:00 2001 From: Maxence Thevenet Date: Thu, 24 Nov 2022 13:58:39 +0100 Subject: [PATCH 6/9] fix --- src/laser/MultiLaser.cpp | 2 ++ tests/laser_blowout_wake_explicit.1Rank.sh | 2 +- tests/laser_blowout_wake_explicit.SI.1Rank.sh | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/laser/MultiLaser.cpp b/src/laser/MultiLaser.cpp index 2ade05b2e3..c9153dc300 100644 --- a/src/laser/MultiLaser.cpp +++ b/src/laser/MultiLaser.cpp @@ -730,6 +730,8 @@ MultiLaser::InitLaserSlice (const amrex::Geometry& geom, const int islice) const amrex::Real x = (i+0.5_rt)*dx_arr[0]+plo[0]; const amrex::Real y = (j+0.5_rt)*dx_arr[1]+plo[1]; + np1j00_arr(i,j,k,dcomp ) = 0._rt; + np1j00_arr(i,j,k,dcomp+1) = 0._rt; for (const auto& laser : m_all_lasers) { const amrex::Real a0 = laser.m_a0; const amrex::Real w0 = laser.m_w0; diff --git a/tests/laser_blowout_wake_explicit.1Rank.sh b/tests/laser_blowout_wake_explicit.1Rank.sh index e69c0192fc..495dc4719a 100755 --- a/tests/laser_blowout_wake_explicit.1Rank.sh +++ b/tests/laser_blowout_wake_explicit.1Rank.sh @@ -33,7 +33,7 @@ mpiexec -n 1 $HIPACE_EXECUTABLE $HIPACE_EXAMPLE_DIR/inputs_normalized \ lasers.lambda0 = .8e-6 \ laser.a0 = 4.5 \ laser.position_mean = 0. 0. 0 \ - laser.w0 = 4 4 \ + laser.w0 = 4 \ laser.L0 = 2 \ amr.n_cell = 128 128 100 \ diff --git a/tests/laser_blowout_wake_explicit.SI.1Rank.sh b/tests/laser_blowout_wake_explicit.SI.1Rank.sh index 104a600b93..f7211abde1 100755 --- a/tests/laser_blowout_wake_explicit.SI.1Rank.sh +++ b/tests/laser_blowout_wake_explicit.SI.1Rank.sh @@ -32,7 +32,7 @@ mpiexec -n 1 $HIPACE_EXECUTABLE $HIPACE_EXAMPLE_DIR/inputs_SI \ lasers.lambda0 = .8e-6 \ laser.a0 = 4.5 \ laser.position_mean = 0. 0. 0 \ - laser.w0 = 4.*kp_inv 4.*kp_inv \ + laser.w0 = 4.*kp_inv \ laser.L0 = 2.*kp_inv \ amr.n_cell = 128 128 100 \ From 6194ef1135d711f95d6446c910e44f46d42973e2 Mon Sep 17 00:00:00 2001 From: Maxence Thevenet Date: Thu, 24 Nov 2022 14:14:01 +0100 Subject: [PATCH 7/9] safer for GPU when laser class becomes bigger, although a few more kernel launches --- src/laser/MultiLaser.cpp | 43 +++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/laser/MultiLaser.cpp b/src/laser/MultiLaser.cpp index c9153dc300..8afde13647 100644 --- a/src/laser/MultiLaser.cpp +++ b/src/laser/MultiLaser.cpp @@ -723,25 +723,28 @@ MultiLaser::InitLaserSlice (const amrex::Geometry& geom, const int islice) amrex::Array4 const & np1j00_arr = np1j00.array(mfi); // Initialize a Gaussian laser envelope on slice islice - amrex::ParallelFor( - bx, - [=] AMREX_GPU_DEVICE(int i, int j, int k) - { - const amrex::Real x = (i+0.5_rt)*dx_arr[0]+plo[0]; - const amrex::Real y = (j+0.5_rt)*dx_arr[1]+plo[1]; - - np1j00_arr(i,j,k,dcomp ) = 0._rt; - np1j00_arr(i,j,k,dcomp+1) = 0._rt; - for (const auto& laser : m_all_lasers) { - const amrex::Real a0 = laser.m_a0; - const amrex::Real w0 = laser.m_w0; - const amrex::Real x0 = laser.m_position_mean[0]; - const amrex::Real y0 = laser.m_position_mean[1]; - const amrex::Real z0 = laser.m_position_mean[2]; - const amrex::Real L0 = laser.m_L0; - const amrex::Real zfoc = laser.m_focal_distance; - + for (int ilaser=0; ilaser Date: Thu, 24 Nov 2022 15:19:24 +0100 Subject: [PATCH 8/9] try fix Juwels compile issue --- src/particles/deposition/PlasmaDepositCurrent.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/particles/deposition/PlasmaDepositCurrent.cpp b/src/particles/deposition/PlasmaDepositCurrent.cpp index abfda5336c..15b785bf42 100644 --- a/src/particles/deposition/PlasmaDepositCurrent.cpp +++ b/src/particles/deposition/PlasmaDepositCurrent.cpp @@ -214,6 +214,9 @@ DepositCurrent (PlasmaParticleContainer& plasma, Fields & fields, const Laser& l q_mu0_mass_ratio *= ion_lev[ip]; } + const amrex::Real xmid = (xp - x_pos_offset) * dx_inv; + const amrex::Real ymid = (yp - y_pos_offset) * dy_inv; + amrex::Real Aabssqp = 0._rt; [[maybe_unused]] auto laser_arr = a_laser_arr; if constexpr (use_laser.value) { @@ -248,12 +251,10 @@ DepositCurrent (PlasmaParticleContainer& plasma, Fields & fields, const Laser& l } // --- Compute shape factors // x direction - const amrex::Real xmid = (xp - x_pos_offset) * dx_inv; auto [shape_x, cell_x] = compute_single_shape_factor(xmid, tx); // y direction - const amrex::Real ymid = (yp - y_pos_offset) * dy_inv; auto [shape_y, cell_y] = compute_single_shape_factor(ymid, iy); From 35880f5057235fd414f5c5f01b983e6be47be169 Mon Sep 17 00:00:00 2001 From: Maxence Thevenet Date: Thu, 24 Nov 2022 16:10:59 +0100 Subject: [PATCH 9/9] update doc for multiple laser pulses --- docs/source/run/parameters.rst | 66 ++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/docs/source/run/parameters.rst b/docs/source/run/parameters.rst index 1da720eb04..835e4ebe3b 100644 --- a/docs/source/run/parameters.rst +++ b/docs/source/run/parameters.rst @@ -508,57 +508,61 @@ Laser parameters ---------------- The laser profile is defined by :math:`a(x,y,z) = a_0 * \mathrm{exp}[-(x^2/w0_x^2 + y^2/w0_y^2 + z^2/L0^2)]`. -The laser pulse length :math:`L0 = \tau / c_0` can be specified via the pulse duration ``laser.tau``. The model implemented is the one from [C. Benedetti et al. Plasma Phys. Control. Fusion 60.1: 014002 (2017)]. +The model implemented is the one from [C. Benedetti et al. Plasma Phys. Control. Fusion 60.1: 014002 (2017)]. +Unlike for ``beams`` and ``plasmas``, all the laser pulses are currently stored on the same array, +which you can find in the output openPMD file as `laser_real` (for the real part of the envelope) and `laser_imag` for its imaginary part. +Parameters starting with ``lasers.`` apply to all laser pulses, parameters starting with ```` apply to a single laser pulse. -* ``laser.use_laser`` (`0` or `1`) optional (default `0`) - Whether to activate the laser envelope solver. +* ``lasers.names`` (list of `string`) + The names of the laser pulses, separated by a space. + To run without a laser, choose the name ``no_laser``. -* ``laser.a0`` (`float`) optional (default `0`) - Peak normalized vector potential of the laser pulse. - -* ``laser.position_mean`` (3 `float`) optional (default `0 0 0`) - The mean position of the laser in `x, y, z`. - -* ``laser.w0`` (2 `float`) optional (default `0 0`) - The laser waist in `x, y`. - -* ``laser.L0`` (`float`) optional (default `0`) - The laser pulse length in `z`. Use either the pulse length or the pulse duration. - -* ``laser.tau`` (`float`) optional (default `0`) - The laser pulse duration. The pulse length will be set to `laser.tau`:math:`/c_0`. - Use either the pulse length or the pulse duration. - -* ``laser.lambda0`` (`float`) - The laser pulse wavelength. - -* ``laser.focal_distance`` (`float`) - Distance at which the laser pulse if focused (in the z direction, counted from laser initial position). +* ``lasers.lambda0`` (`float`) + Wavelength of the laser pulses. Currently, all pulses must have the same wavelength. -* ``laser.use_phase`` (`bool`) optional (default `true`) +* ``lasers.use_phase`` (`bool`) optional (default `true`) Whether the phase terms (:math:`\theta` in Eq. (6) of [C. Benedetti et al. Plasma Phys. Control. Fusion 60.1: 014002 (2017)]) are computed and used in the laser envelope advance. Keeping the phase should be more accurate, but can cause numerical issues in the presence of strong depletion/frequency shift. -* ``laser.solver_type`` (`string`) optional (default `multigrid`) +* ``lasers.solver_type`` (`string`) optional (default `multigrid`) Type of solver for the laser envelope solver, either ``fft`` or ``multigrid``. Currently, the approximation that the phase is evaluated on-axis only is made with both solvers. With the multigrid solver, we could drop this assumption. For now, the fft solver should be faster, more accurate and more stable, so only use the multigrid one with care. -* ``laser.MG_tolerance_rel`` (`float`) optional (default `1e-4`) +* ``lasers.MG_tolerance_rel`` (`float`) optional (default `1e-4`) Relative error tolerance of the multigrid solver used for the laser pulse. -* ``laser.MG_tolerance_abs`` (`float`) optional (default `0.`) +* ``lasers.MG_tolerance_abs`` (`float`) optional (default `0.`) Absolute error tolerance of the multigrid solver used for the laser pulse. -* ``laser.MG_verbose`` (`int`) optional (default `0`) +* ``lasers.MG_verbose`` (`int`) optional (default `0`) Level of verbosity of the multigrid solver used for the laser pulse. -* ``laser.MG_average_rhs`` (`0` or `1`) optional (default `1`) +* ``lasers.MG_average_rhs`` (`0` or `1`) optional (default `1`) Whether to use the most stable discretization for the envelope solver. -* ``laser.3d_on_host`` (`0` or `1`) optional (default `0`) +* ``lasers.3d_on_host`` (`0` or `1`) optional (default `0`) When running on GPU: whether the 3D array containing the laser envelope is stored in host memory (CPU, slower but large memory available) or in device memory (GPU, faster but less memory available). +* ``.a0`` (`float`) optional (default `0`) + Peak normalized vector potential of the laser pulse. + +* ``.position_mean`` (3 `float`) optional (default `0 0 0`) + The mean position of the laser in `x, y, z`. + +* ``.w0`` (2 `float`) optional (default `0 0`) + The laser waist in `x, y`. + +* ``.L0`` (`float`) optional (default `0`) + The laser pulse length in `z`. Use either the pulse length or the pulse duration ``.tau``. + +* ``.tau`` (`float`) optional (default `0`) + The laser pulse duration. The pulse length will be set to `laser.tau`:math:`/c_0`. + Use either the pulse length or the pulse duration. + +* ``.focal_distance`` (`float`) + Distance at which the laser pulse if focused (in the z direction, counted from laser initial position). + Diagnostic parameters ---------------------