From 0e2b6eac78fdd819779e2aaf801129a2f1e2e03a Mon Sep 17 00:00:00 2001 From: huixingjian Date: Fri, 6 Sep 2024 14:14:52 +0200 Subject: [PATCH 01/20] update the documentation --- docs/source/run/parameters.rst | 6 +++--- examples/.DS_Store | Bin 0 -> 6148 bytes 2 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 examples/.DS_Store diff --git a/docs/source/run/parameters.rst b/docs/source/run/parameters.rst index 7b862892f7..6f71dc84db 100644 --- a/docs/source/run/parameters.rst +++ b/docs/source/run/parameters.rst @@ -912,17 +912,17 @@ Option: ``gaussian`` Option: ``from_file`` -* ``lasers.input_file`` (`string`) optional (default `""`) +* ``.input_file`` (`string`) (default `""`) Path to an openPMD file containing a laser envelope. The file should comply with the `LaserEnvelope extension of the openPMD-standard `__, as generated by `LASY `__. Currently supported geometries: 3D or cylindrical profiles with azimuthal decomposition. The laser pulse is injected in the HiPACE++ simulation so that the beginning of the temporal profile from the file corresponds to the head of the simulation box, and time (in the file) is converted to space (HiPACE++ longitudinal coordinate) with ``z = -c*t + const``. If this parameter is set, then the file is used to initialize all lasers instead of using a gaussian profile. -* ``lasers.openPMD_laser_name`` (`string`) optional (default `laserEnvelope`) +* ``.openPMD_laser_name`` (`string`) optional (default `laserEnvelope`) Name of the laser envelope field inside the openPMD file to be read in. -* ``lasers.iteration`` (`int`) optional (default `0`) +* ``.iteration`` (`int`) optional (default `0`) Iteration of the openPMD file to be read in. Option: ``parser`` diff --git a/examples/.DS_Store b/examples/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..bfcfd372d1306b3b8e7631bf5db76d8d979dcd6b GIT binary patch literal 6148 zcmeHKI|>3Z5S{S@f{mqRuHX%V=n3`$3W|*=C|YmjxjdS0KFzY&X`#G<$x9~l67q_j z9TCyxZMP7aiO2+QC=VO@X8Yzn8)QU*aGY_uH<#1#d^+@U-vx|2mZNOtD*F!Kc4$<9 z3Qz$mKn1A4rxnNwJDGm^V4g<>sKC!FVBd!VH>`Bxq5@RluN2VHs#z`Zq^zyI$62i{@D1E@o^UhFor1y3G0@8~7FLeuo)me-=Gd=^ UZJ^T;cRG+i1Evd&3Vd6E7mN86&j0`b literal 0 HcmV?d00001 From a9addda8bd414065d3c4363f266777a44929a80d Mon Sep 17 00:00:00 2001 From: huixingjian Date: Fri, 6 Sep 2024 14:15:28 +0200 Subject: [PATCH 02/20] delete .DS file --- examples/.DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 examples/.DS_Store diff --git a/examples/.DS_Store b/examples/.DS_Store deleted file mode 100644 index bfcfd372d1306b3b8e7631bf5db76d8d979dcd6b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKI|>3Z5S{S@f{mqRuHX%V=n3`$3W|*=C|YmjxjdS0KFzY&X`#G<$x9~l67q_j z9TCyxZMP7aiO2+QC=VO@X8Yzn8)QU*aGY_uH<#1#d^+@U-vx|2mZNOtD*F!Kc4$<9 z3Qz$mKn1A4rxnNwJDGm^V4g<>sKC!FVBd!VH>`Bxq5@RluN2VHs#z`Zq^zyI$62i{@D1E@o^UhFor1y3G0@8~7FLeuo)me-=Gd=^ UZJ^T;cRG+i1Evd&3Vd6E7mN86&j0`b From 7dbab1b5134b2558177e0a5e702d65522af32858 Mon Sep 17 00:00:00 2001 From: huixingjian Date: Fri, 6 Sep 2024 14:21:21 +0200 Subject: [PATCH 03/20] add arguments in Laser object --- src/laser/Laser.H | 22 ++++++++++++++++++++-- src/laser/Laser.cpp | 19 ++++++++++++++++--- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/laser/Laser.H b/src/laser/Laser.H index 88245ba456..60afd9a5bd 100644 --- a/src/laser/Laser.H +++ b/src/laser/Laser.H @@ -14,12 +14,16 @@ #include #include "utils/Constants.H" #include "utils/Parser.H" +#include class Laser { public: - - Laser (std::string name); +/** \brief Read in a laser from an openPMD file */ + void GetEnvelopeFromFileHelper (amrex::Geometry laser_geom_3D); + template + void GetEnvelopeFromFile (amrex::Geometry laser_geom_3D); + Laser (std::string name, amrex::Geometry laser_geom_3D); std::string m_name {""}; /** The way to initialize a laser (from_file/gaussian/parser)*/ @@ -44,6 +48,20 @@ public: amrex::ParserExecutor<3> m_profile_real; /** stores the output function of makeFunctionWithParser for profile_imag_str */ amrex::ParserExecutor<3> m_profile_imag; + /** if the lasers are initialized from openPMD file */ + bool m_laser_from_file = false; + /** full 3D laser data stored on the host */ + amrex::FArrayBox m_F_input_file; + /** path to input openPMD file */ + std::string m_input_file_path; + /** name of the openPMD species in the file */ + std::string m_file_envelope_name = "laserEnvelope"; + /** index of the iteration in the openPMD file */ + int m_file_num_iteration = 0; + /** Geometry of the laser file, 'rt' or 'xyt' */ + std::string m_file_geometry = ""; + /** Wavelength from file */ + amrex::Real m_lambda0_from_file {0.}; }; #endif // LASER_H_ diff --git a/src/laser/Laser.cpp b/src/laser/Laser.cpp index f3a0e5a4ab..af49cfb898 100644 --- a/src/laser/Laser.cpp +++ b/src/laser/Laser.cpp @@ -13,13 +13,23 @@ #include #include +#include "particles/particles_utils/ShapeFactors.H" -Laser::Laser (std::string name) +Laser::Laser (std::string name, amrex::Geometry laser_geom_3D) { m_name = name; amrex::ParmParse pp(m_name); queryWithParser(pp, "init_type", m_laser_init_type); - if (m_laser_init_type == "from_file") return; + if (m_laser_init_type == "from_file") { + queryWithParser(pp, "input_file", m_input_file_path); + queryWithParser(pp, "openPMD_laser_name", m_file_envelope_name); + queryWithParser(pp, "iteration", m_file_num_iteration); + if (Hipace::HeadRank()) { + m_F_input_file.resize(laser_geom_3D.Domain(), 2, amrex::The_Pinned_Arena()); + GetEnvelopeFromFileHelper(laser_geom_3D); + } + return; + } else if (m_laser_init_type == "gaussian"){ queryWithParser(pp, "a0", m_a0); queryWithParser(pp, "w0", m_w0); @@ -29,7 +39,7 @@ Laser::Laser (std::string name) 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"); + "Please specify exlusively either the pulse length L0 or the duration tau of gaussian lasers"); if (duration_is_specified) m_L0 = m_tau*get_phys_const().c; queryWithParser(pp, "focal_distance", m_focal_distance); queryWithParser(pp, "position_mean", m_position_mean); @@ -44,4 +54,7 @@ Laser::Laser (std::string name) m_profile_imag = makeFunctionWithParser<3>( profile_imag_str, m_parser_li, {"x", "y", "z"}); return; } + else { + amrex::Abort("ilegal init type specified"); + } } From 6559263ec825664988290d359bc22b6d0dedd188 Mon Sep 17 00:00:00 2001 From: huixingjian Date: Fri, 6 Sep 2024 14:21:21 +0200 Subject: [PATCH 04/20] add the read_from_file funcions to laser object Co-authored-by: AlexanderSinn Co-authored-by: MaxThevenet --- src/laser/Laser.H | 22 +++- src/laser/Laser.cpp | 302 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 319 insertions(+), 5 deletions(-) diff --git a/src/laser/Laser.H b/src/laser/Laser.H index 88245ba456..60afd9a5bd 100644 --- a/src/laser/Laser.H +++ b/src/laser/Laser.H @@ -14,12 +14,16 @@ #include #include "utils/Constants.H" #include "utils/Parser.H" +#include class Laser { public: - - Laser (std::string name); +/** \brief Read in a laser from an openPMD file */ + void GetEnvelopeFromFileHelper (amrex::Geometry laser_geom_3D); + template + void GetEnvelopeFromFile (amrex::Geometry laser_geom_3D); + Laser (std::string name, amrex::Geometry laser_geom_3D); std::string m_name {""}; /** The way to initialize a laser (from_file/gaussian/parser)*/ @@ -44,6 +48,20 @@ public: amrex::ParserExecutor<3> m_profile_real; /** stores the output function of makeFunctionWithParser for profile_imag_str */ amrex::ParserExecutor<3> m_profile_imag; + /** if the lasers are initialized from openPMD file */ + bool m_laser_from_file = false; + /** full 3D laser data stored on the host */ + amrex::FArrayBox m_F_input_file; + /** path to input openPMD file */ + std::string m_input_file_path; + /** name of the openPMD species in the file */ + std::string m_file_envelope_name = "laserEnvelope"; + /** index of the iteration in the openPMD file */ + int m_file_num_iteration = 0; + /** Geometry of the laser file, 'rt' or 'xyt' */ + std::string m_file_geometry = ""; + /** Wavelength from file */ + amrex::Real m_lambda0_from_file {0.}; }; #endif // LASER_H_ diff --git a/src/laser/Laser.cpp b/src/laser/Laser.cpp index f3a0e5a4ab..d5a81e79d0 100644 --- a/src/laser/Laser.cpp +++ b/src/laser/Laser.cpp @@ -13,13 +13,23 @@ #include #include +#include "particles/particles_utils/ShapeFactors.H" -Laser::Laser (std::string name) +Laser::Laser (std::string name, amrex::Geometry laser_geom_3D) { m_name = name; amrex::ParmParse pp(m_name); queryWithParser(pp, "init_type", m_laser_init_type); - if (m_laser_init_type == "from_file") return; + if (m_laser_init_type == "from_file") { + queryWithParser(pp, "input_file", m_input_file_path); + queryWithParser(pp, "openPMD_laser_name", m_file_envelope_name); + queryWithParser(pp, "iteration", m_file_num_iteration); + if (Hipace::HeadRank()) { + m_F_input_file.resize(laser_geom_3D.Domain(), 2, amrex::The_Pinned_Arena()); + GetEnvelopeFromFileHelper(laser_geom_3D); + } + return; + } else if (m_laser_init_type == "gaussian"){ queryWithParser(pp, "a0", m_a0); queryWithParser(pp, "w0", m_w0); @@ -29,7 +39,7 @@ Laser::Laser (std::string name) 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"); + "Please specify exlusively either the pulse length L0 or the duration tau of gaussian lasers"); if (duration_is_specified) m_L0 = m_tau*get_phys_const().c; queryWithParser(pp, "focal_distance", m_focal_distance); queryWithParser(pp, "position_mean", m_position_mean); @@ -44,4 +54,290 @@ Laser::Laser (std::string name) m_profile_imag = makeFunctionWithParser<3>( profile_imag_str, m_parser_li, {"x", "y", "z"}); return; } + else { + amrex::Abort("ilegal init type specified"); + } +} + + +void +Laser::GetEnvelopeFromFileHelper (amrex::Geometry laser_geom_3D) { + + HIPACE_PROFILE("MultiLaser::GetEnvelopeFromFileHelper()"); +#ifdef HIPACE_USE_OPENPMD + openPMD::Datatype input_type = openPMD::Datatype::INT; + { + // Check what kind of Datatype is used in the Laser file + auto series = openPMD::Series( m_input_file_path , openPMD::Access::READ_ONLY ); + + if(!series.iterations.contains(m_file_num_iteration)) { + amrex::Abort("Could not find iteration " + std::to_string(m_file_num_iteration) + + " in file " + m_input_file_path + "\n"); + } + + auto iteration = series.iterations[m_file_num_iteration]; + + if(!iteration.meshes.contains(m_file_envelope_name)) { + amrex::Abort("Could not find mesh '" + m_file_envelope_name + "' in file " + + m_input_file_path + "\n"); + } + + auto mesh = iteration.meshes[m_file_envelope_name]; + + if (!mesh.containsAttribute("angularFrequency")) { + amrex::Abort("Could not find Attribute 'angularFrequency' of iteration " + + std::to_string(m_file_num_iteration) + " in file " + + m_input_file_path + "\n"); + } + + m_lambda0_from_file = 2.*MathConst::pi*PhysConstSI::c + / mesh.getAttribute("angularFrequency").get(); + + if(!mesh.contains(openPMD::RecordComponent::SCALAR)) { + amrex::Abort("Could not find component '" + + std::string(openPMD::RecordComponent::SCALAR) + + "' in file " + m_input_file_path + "\n"); + } + + input_type = mesh[openPMD::RecordComponent::SCALAR].getDatatype(); + } + + if (input_type == openPMD::Datatype::CFLOAT) { + GetEnvelopeFromFile>(laser_geom_3D); + } else if (input_type == openPMD::Datatype::CDOUBLE) { + GetEnvelopeFromFile>(laser_geom_3D); + } else { + amrex::Abort("Unknown Datatype used in Laser input file. Must use CDOUBLE or CFLOAT\n"); + } +#else + amrex::Abort("loading a laser envelope from an external file requires openPMD support: " + "Add HiPACE_OPENPMD=ON when compiling HiPACE++.\n"); +#endif // HIPACE_USE_OPENPMD } + +template +void +Laser::GetEnvelopeFromFile (amrex::Geometry laser_geom_3D) { + + using namespace amrex::literals; + + HIPACE_PROFILE("MultiLaser::GetEnvelopeFromFile()"); +#ifdef HIPACE_USE_OPENPMD + const PhysConst phc = get_phys_const(); + const amrex::Real clight = phc.c; + + const amrex::Box& domain = laser_geom_3D.Domain(); + + auto series = openPMD::Series( m_input_file_path , openPMD::Access::READ_ONLY ); + auto laser = series.iterations[m_file_num_iteration].meshes[m_file_envelope_name]; + auto laser_comp = laser[openPMD::RecordComponent::SCALAR]; + + const std::vector axis_labels = laser.axisLabels(); + if (axis_labels[0] == "t" && axis_labels[1] == "y" && axis_labels[2] == "x") { + m_file_geometry = "xyt"; + } else if (axis_labels[0] == "z" && axis_labels[1] == "y" && axis_labels[2] == "x") { + m_file_geometry = "xyz"; + } else if (axis_labels[0] == "t" && axis_labels[1] == "r") { + m_file_geometry = "rt"; + } else { + amrex::Abort("Incorrect axis labels in laser file, must be either tyx, zyx or tr"); + } + + const std::shared_ptr data = laser_comp.loadChunk(); + auto extent = laser_comp.getExtent(); + double unitSI = laser_comp.unitSI(); + + // Extract grid offset and grid spacing from laser file + std::vector offset = laser.gridGlobalOffset(); + std::vector position = laser_comp.position(); + std::vector spacing = laser.gridSpacing(); + + //lasy: tyx in C order, tr in C order + amrex::Dim3 arr_begin = {0, 0, 0}; + amrex::Dim3 arr_end = {static_cast(extent[2]), static_cast(extent[1]), + static_cast(extent[0])}; + amrex::Array4 input_file_arr(data.get(), arr_begin, arr_end, 1); + + //hipace: xyt in Fortran order + amrex::Array4 laser_arr = m_F_input_file.array(); + + series.flush(); + + constexpr int interp_order_xy = 1; + const amrex::Real dx = laser_geom_3D.CellSize(Direction::x); + const amrex::Real dy = laser_geom_3D.CellSize(Direction::y); + const amrex::Real dz = laser_geom_3D.CellSize(Direction::z); + const amrex::Real xmin = laser_geom_3D.ProbLo(Direction::x)+dx/2; + const amrex::Real ymin = laser_geom_3D.ProbLo(Direction::y)+dy/2; + const amrex::Real zmin = laser_geom_3D.ProbLo(Direction::z)+dz/2; + const amrex::Real zmax = laser_geom_3D.ProbHi(Direction::z)-dz/2; + const int imin = domain.smallEnd(0); + const int jmin = domain.smallEnd(1); + const int kmin = domain.smallEnd(2); + + if (m_file_geometry == "xyt") { + // Calculate the min and max of the grid from laser file + amrex::Real ymin_laser = offset[1] + position[1]*spacing[1]; + amrex::Real xmin_laser = offset[2] + position[2]*spacing[2]; + AMREX_ALWAYS_ASSERT(position[0] == 0 && position[1] == 0 && position[2] == 0); + + + for (int k = kmin; k <= domain.bigEnd(2); ++k) { + for (int j = jmin; j <= domain.bigEnd(1); ++j) { + for (int i = imin; i <= domain.bigEnd(0); ++i) { + + const amrex::Real x = (i-imin)*dx + xmin; + const amrex::Real xmid = (x - xmin_laser)/spacing[2]; + amrex::Real sx_cell[interp_order_xy+1]; + const int i_cell = compute_shape_factor(sx_cell, xmid); + + const amrex::Real y = (j-jmin)*dy + ymin; + const amrex::Real ymid = (y - ymin_laser)/spacing[1]; + amrex::Real sy_cell[interp_order_xy+1]; + const int j_cell = compute_shape_factor(sy_cell, ymid); + + const amrex::Real z = (k-kmin)*dz + zmin; + const amrex::Real tmid = (zmax-z)/clight/spacing[0]; + amrex::Real st_cell[interp_order_xy+1]; + const int k_cell = compute_shape_factor(st_cell, tmid); + + laser_arr(i, j, k, 0) = 0._rt; + laser_arr(i, j, k, 1) = 0._rt; + for (int it=0; it<=interp_order_xy; it++){ + for (int iy=0; iy<=interp_order_xy; iy++){ + for (int ix=0; ix<=interp_order_xy; ix++){ + if (i_cell+ix >= 0 && i_cell+ix < static_cast(extent[2]) && + j_cell+iy >= 0 && j_cell+iy < static_cast(extent[1]) && + k_cell+it >= 0 && k_cell+it < static_cast(extent[0])) { + laser_arr(i, j, k, 0) += sx_cell[ix] * sy_cell[iy] * st_cell[it] * + static_cast( + input_file_arr(i_cell+ix, j_cell+iy, k_cell+it).real() * unitSI + ); + laser_arr(i, j, k, 1) += sx_cell[ix] * sy_cell[iy] * st_cell[it] * + static_cast( + input_file_arr(i_cell+ix, j_cell+iy, k_cell+it).imag() * unitSI + ); + } + } + } + } // End of 3 loops (1 per dimension) over laser array from file + } + } + } // End of 3 loops (1 per dimension) over laser array from simulation + } else if (m_file_geometry == "xyz") { + // Calculate the min and max of the grid from laser file + amrex::Real zmin_laser = offset[0] + position[0]*spacing[0]; + amrex::Real ymin_laser = offset[1] + position[1]*spacing[1]; + amrex::Real xmin_laser = offset[2] + position[2]*spacing[2]; + + for (int k = kmin; k <= domain.bigEnd(2); ++k) { + for (int j = jmin; j <= domain.bigEnd(1); ++j) { + for (int i = imin; i <= domain.bigEnd(0); ++i) { + + const amrex::Real x = (i-imin)*dx + xmin; + const amrex::Real xmid = (x - xmin_laser)/spacing[2]; + amrex::Real sx_cell[interp_order_xy+1]; + const int i_cell = compute_shape_factor(sx_cell, xmid); + + const amrex::Real y = (j-jmin)*dy + ymin; + const amrex::Real ymid = (y - ymin_laser)/spacing[1]; + amrex::Real sy_cell[interp_order_xy+1]; + const int j_cell = compute_shape_factor(sy_cell, ymid); + + const amrex::Real z = (k-kmin)*dz + zmin; + const amrex::Real zmid = (z - zmin_laser)/spacing[0]; + amrex::Real sz_cell[interp_order_xy+1]; + const int k_cell = compute_shape_factor(sz_cell, zmid); + + laser_arr(i, j, k, 0) = 0._rt; + laser_arr(i, j, k, 1) = 0._rt; + for (int iz=0; iz<=interp_order_xy; iz++){ + for (int iy=0; iy<=interp_order_xy; iy++){ + for (int ix=0; ix<=interp_order_xy; ix++){ + if (i_cell+ix >= 0 && i_cell+ix < static_cast(extent[2]) && + j_cell+iy >= 0 && j_cell+iy < static_cast(extent[1]) && + k_cell+iz >= 0 && k_cell+iz < static_cast(extent[0])) { + laser_arr(i, j, k, 0) += sx_cell[ix] * sy_cell[iy] * sz_cell[iz] * + static_cast( + input_file_arr(i_cell+ix, j_cell+iy, k_cell+iz).real() * unitSI + ); + laser_arr(i, j, k, 1) += sx_cell[ix] * sy_cell[iy] * sz_cell[iz] * + static_cast( + input_file_arr(i_cell+ix, j_cell+iy, k_cell+iz).imag() * unitSI + ); + } + } + } + } // End of 3 loops (1 per dimension) over laser array from file + } + } + } // End of 3 loops (1 per dimension) over laser array from simulation + } else if (m_file_geometry == "rt") { + + // extent = {nmodes, nt, nr} + + // Calculate the min and max of the grid from laser file + amrex::Real rmin_laser = offset[1] + position[1]*spacing[1]; + AMREX_ALWAYS_ASSERT(position[0] == 0 && position[1] == 0); + + for (int k = kmin; k <= domain.bigEnd(2); ++k) { + for (int j = jmin; j <= domain.bigEnd(1); ++j) { + for (int i = imin; i <= domain.bigEnd(0); ++i) { + + const amrex::Real x = (i-imin)*dx + xmin; + const amrex::Real y = (j-jmin)*dy + ymin; + const amrex::Real r = std::sqrt(x*x + y*y); + const amrex::Real theta = std::atan2(y, x); + const amrex::Real rmid = (r - rmin_laser)/spacing[1]; + amrex::Real sr_cell[interp_order_xy+1]; + const int i_cell = compute_shape_factor(sr_cell, rmid); + + const amrex::Real z = (k-kmin)*dz + zmin; + const amrex::Real tmid = (zmax-z)/clight/spacing[0]; + amrex::Real st_cell[interp_order_xy+1]; + const int k_cell = compute_shape_factor(st_cell, tmid); + + laser_arr(i, j, k, 0) = 0._rt; + laser_arr(i, j, k, 1) = 0._rt; + for (int it=0; it<=interp_order_xy; it++){ + for (int ir=0; ir<=interp_order_xy; ir++){ + AMREX_ALWAYS_ASSERT_WITH_MESSAGE(i_cell+ir >= 0, + "Touching a r<0 cell in laser file reader. Is staggering correct?"); + if (i_cell+ir < static_cast(extent[2]) && + k_cell+it >= 0 && k_cell+it < static_cast(extent[1])) { + // mode 0 + laser_arr(i, j, k, 0) += sr_cell[ir] * st_cell[it] * + static_cast( + input_file_arr(i_cell+ir, k_cell+it, 0).real() * unitSI); + laser_arr(i, j, k, 1) += sr_cell[ir] * st_cell[it] * + static_cast( + input_file_arr(i_cell+ir, k_cell+it, 0).imag() * unitSI); + for (int im=1; im<=static_cast(extent[0])/2; im++) { + // cos(m*theta) part of the mode + laser_arr(i, j, k, 0) += sr_cell[ir] * st_cell[it] * + std::cos(im*theta) * static_cast( + input_file_arr(i_cell+ir, k_cell+it, 2*im-1).real() * unitSI); + laser_arr(i, j, k, 1) += sr_cell[ir] * st_cell[it] * + std::cos(im*theta) * static_cast( + input_file_arr(i_cell+ir, k_cell+it, 2*im-1).imag() * unitSI); + // sin(m*theta) part of the mode + laser_arr(i, j, k, 0) += sr_cell[ir] * st_cell[it] * + std::sin(im*theta) * static_cast( + input_file_arr(i_cell+ir, k_cell+it, 2*im).real() * unitSI); + laser_arr(i, j, k, 1) += sr_cell[ir] * st_cell[it] * + std::sin(im*theta) * static_cast( + input_file_arr(i_cell+ir, k_cell+it, 2*im).imag() * unitSI); + } // End of loop over modes of laser array from file + } + } + } // End of 2 loops (1 per RT dimension) over laser array from file + } + } + } // End of 3 loops (1 per dimension) over laser array from simulation + } // End if statement over file laser geometry (rt or xyt) +#else + amrex::Abort("loading a laser envelope from an external file requires openPMD support: " + "Add HiPACE_OPENPMD=ON when compiling HiPACE++.\n"); +#endif // HIPACE_USE_OPENPMD +} + From 648ed7a25f0252eff1259260023b36820b2b4760 Mon Sep 17 00:00:00 2001 From: huixingjian Date: Fri, 6 Sep 2024 14:56:25 +0200 Subject: [PATCH 05/20] add read from file in slice_init --- src/laser/Laser.cpp | 6 +- src/laser/MultiLaser.H | 25 +-- src/laser/MultiLaser.cpp | 354 ++++----------------------------------- 3 files changed, 34 insertions(+), 351 deletions(-) diff --git a/src/laser/Laser.cpp b/src/laser/Laser.cpp index d5a81e79d0..95579e7c11 100644 --- a/src/laser/Laser.cpp +++ b/src/laser/Laser.cpp @@ -20,7 +20,7 @@ Laser::Laser (std::string name, amrex::Geometry laser_geom_3D) m_name = name; amrex::ParmParse pp(m_name); queryWithParser(pp, "init_type", m_laser_init_type); - if (m_laser_init_type == "from_file") { + if (m_laser_init_type == "from_file") { queryWithParser(pp, "input_file", m_input_file_path); queryWithParser(pp, "openPMD_laser_name", m_file_envelope_name); queryWithParser(pp, "iteration", m_file_num_iteration); @@ -30,7 +30,7 @@ Laser::Laser (std::string name, amrex::Geometry laser_geom_3D) } return; } - else if (m_laser_init_type == "gaussian"){ + else if (m_laser_init_type == "gaussian") { queryWithParser(pp, "a0", m_a0); queryWithParser(pp, "w0", m_w0); queryWithParser(pp, "CEP", m_CEP); @@ -45,7 +45,7 @@ Laser::Laser (std::string name, amrex::Geometry laser_geom_3D) queryWithParser(pp, "position_mean", m_position_mean); return; } - else if (m_laser_init_type == "parser"){ + else if (m_laser_init_type == "parser") { std::string profile_real_str = ""; std::string profile_imag_str = ""; getWithParser(pp, "laser_real(x,y,z)", profile_real_str); diff --git a/src/laser/MultiLaser.H b/src/laser/MultiLaser.H index b0db9b7619..d50d5b0de8 100644 --- a/src/laser/MultiLaser.H +++ b/src/laser/MultiLaser.H @@ -88,13 +88,6 @@ public: */ void InitSliceEnvelope (const int islice, const int comp); - /** \brief Read in a laser from an openPMD file */ - void GetEnvelopeFromFileHelper (); - - /** \brief Read in a laser from an openPMD file */ - template - void GetEnvelopeFromFile (); - /** \brief Shift 2D slices in zeta * \param[in] islice slice index */ @@ -197,8 +190,8 @@ public: private: bool m_use_laser {false}; /**< whether a laser is used or not */ - /** Laser central wavelength. - * he central wavelength influences the solver. As long as all the lasers are on the same grid + /** Laser central wavelength defined by user. + * the 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 {"no_laser"}; /**< name of the laser */ @@ -218,20 +211,6 @@ private: amrex::Box m_slice_box; /** interpolation order for laser to field and field to laser operations */ int m_interp_order = 1; - - /** if the lasers are initialized from openPMD file */ - bool m_laser_from_file = false; - /** full 3D laser data stored on the host */ - amrex::FArrayBox m_F_input_file; - /** path to input openPMD file */ - std::string m_input_file_path; - /** name of the openPMD species in the file */ - std::string m_file_envelope_name = "laserEnvelope"; - /** index of the iteration in the openPMD file */ - int m_file_num_iteration = 0; - /** Geometry of the laser file, 'rt' or 'xyt' */ - std::string m_file_geometry = ""; - /** Array of N slices required to compute current slice */ amrex::MultiFab m_slices; amrex::Real m_MG_tolerance_rel = 1.e-4; diff --git a/src/laser/MultiLaser.cpp b/src/laser/MultiLaser.cpp index 18d6252b67..bd457f69d0 100644 --- a/src/laser/MultiLaser.cpp +++ b/src/laser/MultiLaser.cpp @@ -32,17 +32,7 @@ MultiLaser::ReadParameters () m_use_laser = m_names[0] != "no_laser"; if (!m_use_laser) return; - - m_laser_from_file = queryWithParser(pp, "input_file", m_input_file_path); - - m_nlasers = m_names.size(); - for (int i = 0; i < m_nlasers; ++i) { - m_all_lasers.emplace_back(Laser(m_names[i])); - } - - if (!m_laser_from_file) { - getWithParser(pp, "lambda0", m_lambda0); - } + queryWithParser(pp, "lambda0", m_lambda0); DeprecatedInput("lasers", "3d_on_host", "comms_buffer.on_gpu", "", true); queryWithParser(pp, "use_phase", m_use_phase); queryWithParser(pp, "solver_type", m_solver_type); @@ -60,11 +50,6 @@ MultiLaser::ReadParameters () amrex::Print()<<"WARNING: parameters laser.MG_... only active if laser.solver_type = multigrid\n"; } - if (m_laser_from_file) { - queryWithParser(pp, "openPMD_laser_name", m_file_envelope_name); - queryWithParser(pp, "iteration", m_file_num_iteration); - } - queryWithParser(pp, "insitu_period", m_insitu_period); queryWithParser(pp, "insitu_file_prefix", m_insitu_file_prefix); } @@ -164,21 +149,6 @@ MultiLaser::InitData () m_rhs_mg.resize(amrex::grow(m_slice_box, amrex::IntVect{1, 1, 0}), 2, amrex::The_Arena()); } - if (m_laser_from_file) { - if (Hipace::HeadRank()) { - m_F_input_file.resize(m_laser_geom_3D.Domain(), 2, amrex::The_Pinned_Arena()); - GetEnvelopeFromFileHelper(); - } -#ifdef AMREX_USE_MPI - // need to communicate m_lambda0 as it is read in from the input file only by the head rank - MPI_Bcast(&m_lambda0, - 1, - amrex::ParallelDescriptor::Mpi_typemap::type(), - Hipace::HeadRankID(), - amrex::ParallelDescriptor::Communicator()); -#endif - } - if (m_insitu_period > 0) { #ifdef HIPACE_USE_OPENPMD AMREX_ALWAYS_ASSERT_WITH_MESSAGE(m_insitu_file_prefix != @@ -198,298 +168,7 @@ MultiLaser::InitSliceEnvelope (const int islice, const int comp) if (!UseLaser(islice)) return; HIPACE_PROFILE("MultiLaser::InitSliceEnvelope()"); - - if (m_laser_from_file) { - amrex::Box src_box = m_slice_box; - src_box.setSmall(2, islice); - src_box.setBig(2, islice); - m_slices[0].copy(m_F_input_file, src_box, 0, m_slice_box, comp, 2); - } else { - // Compute initial field on the current (device) slice comp and comp + 1 - InitLaserSlice(islice, comp); - } - -} - -void -MultiLaser::GetEnvelopeFromFileHelper () { - - HIPACE_PROFILE("MultiLaser::GetEnvelopeFromFileHelper()"); -#ifdef HIPACE_USE_OPENPMD - openPMD::Datatype input_type = openPMD::Datatype::INT; - { - // Check what kind of Datatype is used in the Laser file - auto series = openPMD::Series( m_input_file_path , openPMD::Access::READ_ONLY ); - - if(!series.iterations.contains(m_file_num_iteration)) { - amrex::Abort("Could not find iteration " + std::to_string(m_file_num_iteration) + - " in file " + m_input_file_path + "\n"); - } - - auto iteration = series.iterations[m_file_num_iteration]; - - if(!iteration.meshes.contains(m_file_envelope_name)) { - amrex::Abort("Could not find mesh '" + m_file_envelope_name + "' in file " - + m_input_file_path + "\n"); - } - - auto mesh = iteration.meshes[m_file_envelope_name]; - - if (!mesh.containsAttribute("angularFrequency")) { - amrex::Abort("Could not find Attribute 'angularFrequency' of iteration " - + std::to_string(m_file_num_iteration) + " in file " - + m_input_file_path + "\n"); - } - - m_lambda0 = 2.*MathConst::pi*PhysConstSI::c - / mesh.getAttribute("angularFrequency").get(); - - if(!mesh.contains(openPMD::RecordComponent::SCALAR)) { - amrex::Abort("Could not find component '" + - std::string(openPMD::RecordComponent::SCALAR) + - "' in file " + m_input_file_path + "\n"); - } - - input_type = mesh[openPMD::RecordComponent::SCALAR].getDatatype(); - } - - if (input_type == openPMD::Datatype::CFLOAT) { - GetEnvelopeFromFile>(); - } else if (input_type == openPMD::Datatype::CDOUBLE) { - GetEnvelopeFromFile>(); - } else { - amrex::Abort("Unknown Datatype used in Laser input file. Must use CDOUBLE or CFLOAT\n"); - } -#else - amrex::Abort("loading a laser envelope from an external file requires openPMD support: " - "Add HiPACE_OPENPMD=ON when compiling HiPACE++.\n"); -#endif // HIPACE_USE_OPENPMD -} - -template -void -MultiLaser::GetEnvelopeFromFile () { - - using namespace amrex::literals; - - HIPACE_PROFILE("MultiLaser::GetEnvelopeFromFile()"); -#ifdef HIPACE_USE_OPENPMD - const PhysConst phc = get_phys_const(); - const amrex::Real clight = phc.c; - - const amrex::Box& domain = m_laser_geom_3D.Domain(); - - auto series = openPMD::Series( m_input_file_path , openPMD::Access::READ_ONLY ); - auto laser = series.iterations[m_file_num_iteration].meshes[m_file_envelope_name]; - auto laser_comp = laser[openPMD::RecordComponent::SCALAR]; - - const std::vector axis_labels = laser.axisLabels(); - if (axis_labels[0] == "t" && axis_labels[1] == "y" && axis_labels[2] == "x") { - m_file_geometry = "xyt"; - } else if (axis_labels[0] == "z" && axis_labels[1] == "y" && axis_labels[2] == "x") { - m_file_geometry = "xyz"; - } else if (axis_labels[0] == "t" && axis_labels[1] == "r") { - m_file_geometry = "rt"; - } else { - amrex::Abort("Incorrect axis labels in laser file, must be either tyx, zyx or tr"); - } - - const std::shared_ptr data = laser_comp.loadChunk(); - auto extent = laser_comp.getExtent(); - double unitSI = laser_comp.unitSI(); - - // Extract grid offset and grid spacing from laser file - std::vector offset = laser.gridGlobalOffset(); - std::vector position = laser_comp.position(); - std::vector spacing = laser.gridSpacing(); - - //lasy: tyx in C order, tr in C order - amrex::Dim3 arr_begin = {0, 0, 0}; - amrex::Dim3 arr_end = {static_cast(extent[2]), static_cast(extent[1]), - static_cast(extent[0])}; - amrex::Array4 input_file_arr(data.get(), arr_begin, arr_end, 1); - - //hipace: xyt in Fortran order - amrex::Array4 laser_arr = m_F_input_file.array(); - - series.flush(); - - constexpr int interp_order_xy = 1; - const amrex::Real dx = m_laser_geom_3D.CellSize(Direction::x); - const amrex::Real dy = m_laser_geom_3D.CellSize(Direction::y); - const amrex::Real dz = m_laser_geom_3D.CellSize(Direction::z); - const amrex::Real xmin = m_laser_geom_3D.ProbLo(Direction::x)+dx/2; - const amrex::Real ymin = m_laser_geom_3D.ProbLo(Direction::y)+dy/2; - const amrex::Real zmin = m_laser_geom_3D.ProbLo(Direction::z)+dz/2; - const amrex::Real zmax = m_laser_geom_3D.ProbHi(Direction::z)-dz/2; - const int imin = domain.smallEnd(0); - const int jmin = domain.smallEnd(1); - const int kmin = domain.smallEnd(2); - - if (m_file_geometry == "xyt") { - // Calculate the min and max of the grid from laser file - amrex::Real ymin_laser = offset[1] + position[1]*spacing[1]; - amrex::Real xmin_laser = offset[2] + position[2]*spacing[2]; - AMREX_ALWAYS_ASSERT(position[0] == 0 && position[1] == 0 && position[2] == 0); - - - for (int k = kmin; k <= domain.bigEnd(2); ++k) { - for (int j = jmin; j <= domain.bigEnd(1); ++j) { - for (int i = imin; i <= domain.bigEnd(0); ++i) { - - const amrex::Real x = (i-imin)*dx + xmin; - const amrex::Real xmid = (x - xmin_laser)/spacing[2]; - amrex::Real sx_cell[interp_order_xy+1]; - const int i_cell = compute_shape_factor(sx_cell, xmid); - - const amrex::Real y = (j-jmin)*dy + ymin; - const amrex::Real ymid = (y - ymin_laser)/spacing[1]; - amrex::Real sy_cell[interp_order_xy+1]; - const int j_cell = compute_shape_factor(sy_cell, ymid); - - const amrex::Real z = (k-kmin)*dz + zmin; - const amrex::Real tmid = (zmax-z)/clight/spacing[0]; - amrex::Real st_cell[interp_order_xy+1]; - const int k_cell = compute_shape_factor(st_cell, tmid); - - laser_arr(i, j, k, 0) = 0._rt; - laser_arr(i, j, k, 1) = 0._rt; - for (int it=0; it<=interp_order_xy; it++){ - for (int iy=0; iy<=interp_order_xy; iy++){ - for (int ix=0; ix<=interp_order_xy; ix++){ - if (i_cell+ix >= 0 && i_cell+ix < static_cast(extent[2]) && - j_cell+iy >= 0 && j_cell+iy < static_cast(extent[1]) && - k_cell+it >= 0 && k_cell+it < static_cast(extent[0])) { - laser_arr(i, j, k, 0) += sx_cell[ix] * sy_cell[iy] * st_cell[it] * - static_cast( - input_file_arr(i_cell+ix, j_cell+iy, k_cell+it).real() * unitSI - ); - laser_arr(i, j, k, 1) += sx_cell[ix] * sy_cell[iy] * st_cell[it] * - static_cast( - input_file_arr(i_cell+ix, j_cell+iy, k_cell+it).imag() * unitSI - ); - } - } - } - } // End of 3 loops (1 per dimension) over laser array from file - } - } - } // End of 3 loops (1 per dimension) over laser array from simulation - } else if (m_file_geometry == "xyz") { - // Calculate the min and max of the grid from laser file - amrex::Real zmin_laser = offset[0] + position[0]*spacing[0]; - amrex::Real ymin_laser = offset[1] + position[1]*spacing[1]; - amrex::Real xmin_laser = offset[2] + position[2]*spacing[2]; - - for (int k = kmin; k <= domain.bigEnd(2); ++k) { - for (int j = jmin; j <= domain.bigEnd(1); ++j) { - for (int i = imin; i <= domain.bigEnd(0); ++i) { - - const amrex::Real x = (i-imin)*dx + xmin; - const amrex::Real xmid = (x - xmin_laser)/spacing[2]; - amrex::Real sx_cell[interp_order_xy+1]; - const int i_cell = compute_shape_factor(sx_cell, xmid); - - const amrex::Real y = (j-jmin)*dy + ymin; - const amrex::Real ymid = (y - ymin_laser)/spacing[1]; - amrex::Real sy_cell[interp_order_xy+1]; - const int j_cell = compute_shape_factor(sy_cell, ymid); - - const amrex::Real z = (k-kmin)*dz + zmin; - const amrex::Real zmid = (z - zmin_laser)/spacing[0]; - amrex::Real sz_cell[interp_order_xy+1]; - const int k_cell = compute_shape_factor(sz_cell, zmid); - - laser_arr(i, j, k, 0) = 0._rt; - laser_arr(i, j, k, 1) = 0._rt; - for (int iz=0; iz<=interp_order_xy; iz++){ - for (int iy=0; iy<=interp_order_xy; iy++){ - for (int ix=0; ix<=interp_order_xy; ix++){ - if (i_cell+ix >= 0 && i_cell+ix < static_cast(extent[2]) && - j_cell+iy >= 0 && j_cell+iy < static_cast(extent[1]) && - k_cell+iz >= 0 && k_cell+iz < static_cast(extent[0])) { - laser_arr(i, j, k, 0) += sx_cell[ix] * sy_cell[iy] * sz_cell[iz] * - static_cast( - input_file_arr(i_cell+ix, j_cell+iy, k_cell+iz).real() * unitSI - ); - laser_arr(i, j, k, 1) += sx_cell[ix] * sy_cell[iy] * sz_cell[iz] * - static_cast( - input_file_arr(i_cell+ix, j_cell+iy, k_cell+iz).imag() * unitSI - ); - } - } - } - } // End of 3 loops (1 per dimension) over laser array from file - } - } - } // End of 3 loops (1 per dimension) over laser array from simulation - } else if (m_file_geometry == "rt") { - - // extent = {nmodes, nt, nr} - - // Calculate the min and max of the grid from laser file - amrex::Real rmin_laser = offset[1] + position[1]*spacing[1]; - AMREX_ALWAYS_ASSERT(position[0] == 0 && position[1] == 0); - - for (int k = kmin; k <= domain.bigEnd(2); ++k) { - for (int j = jmin; j <= domain.bigEnd(1); ++j) { - for (int i = imin; i <= domain.bigEnd(0); ++i) { - - const amrex::Real x = (i-imin)*dx + xmin; - const amrex::Real y = (j-jmin)*dy + ymin; - const amrex::Real r = std::sqrt(x*x + y*y); - const amrex::Real theta = std::atan2(y, x); - const amrex::Real rmid = (r - rmin_laser)/spacing[1]; - amrex::Real sr_cell[interp_order_xy+1]; - const int i_cell = compute_shape_factor(sr_cell, rmid); - - const amrex::Real z = (k-kmin)*dz + zmin; - const amrex::Real tmid = (zmax-z)/clight/spacing[0]; - amrex::Real st_cell[interp_order_xy+1]; - const int k_cell = compute_shape_factor(st_cell, tmid); - - laser_arr(i, j, k, 0) = 0._rt; - laser_arr(i, j, k, 1) = 0._rt; - for (int it=0; it<=interp_order_xy; it++){ - for (int ir=0; ir<=interp_order_xy; ir++){ - AMREX_ALWAYS_ASSERT_WITH_MESSAGE(i_cell+ir >= 0, - "Touching a r<0 cell in laser file reader. Is staggering correct?"); - if (i_cell+ir < static_cast(extent[2]) && - k_cell+it >= 0 && k_cell+it < static_cast(extent[1])) { - // mode 0 - laser_arr(i, j, k, 0) += sr_cell[ir] * st_cell[it] * - static_cast( - input_file_arr(i_cell+ir, k_cell+it, 0).real() * unitSI); - laser_arr(i, j, k, 1) += sr_cell[ir] * st_cell[it] * - static_cast( - input_file_arr(i_cell+ir, k_cell+it, 0).imag() * unitSI); - for (int im=1; im<=static_cast(extent[0])/2; im++) { - // cos(m*theta) part of the mode - laser_arr(i, j, k, 0) += sr_cell[ir] * st_cell[it] * - std::cos(im*theta) * static_cast( - input_file_arr(i_cell+ir, k_cell+it, 2*im-1).real() * unitSI); - laser_arr(i, j, k, 1) += sr_cell[ir] * st_cell[it] * - std::cos(im*theta) * static_cast( - input_file_arr(i_cell+ir, k_cell+it, 2*im-1).imag() * unitSI); - // sin(m*theta) part of the mode - laser_arr(i, j, k, 0) += sr_cell[ir] * st_cell[it] * - std::sin(im*theta) * static_cast( - input_file_arr(i_cell+ir, k_cell+it, 2*im).real() * unitSI); - laser_arr(i, j, k, 1) += sr_cell[ir] * st_cell[it] * - std::sin(im*theta) * static_cast( - input_file_arr(i_cell+ir, k_cell+it, 2*im).imag() * unitSI); - } // End of loop over modes of laser array from file - } - } - } // End of 2 loops (1 per RT dimension) over laser array from file - } - } - } // End of 3 loops (1 per dimension) over laser array from simulation - } // End if statement over file laser geometry (rt or xyt) -#else - amrex::Abort("loading a laser envelope from an external file requires openPMD support: " - "Add HiPACE_OPENPMD=ON when compiling HiPACE++.\n"); -#endif // HIPACE_USE_OPENPMD + InitLaserSlice(islice, comp); } void @@ -1137,10 +816,35 @@ MultiLaser::InitLaserSlice (const int islice, const int comp) for ( amrex::MFIter mfi(m_slices, DfltMfiTlng); mfi.isValid(); ++mfi ){ const amrex::Box& bx = mfi.tilebox(); amrex::Array4 const & arr = m_slices.array(mfi); - // Initialize a Gaussian laser envelope on slice islice - //check point + // Initialize a laser envelope on slice islice for (int ilaser=0; ilaser < m_nlasers; ilaser++) { auto& laser = m_all_lasers[ilaser]; + if (laser.m_laser_init_type == "from_file"){ + amrex::Array4 const& arr_ff = laser.m_F_input_file.array(); + amrex::ParallelFor( + bx, + [=] AMREX_GPU_DEVICE(int i, int j, int k) + { + if (ilaser == 0) { + arr(i, j, k, comp ) = 0._rt; + arr(i, j, k, comp + 1 ) = 0._rt; + } + arr(i, j, k, comp ) += arr_ff(i, j, k, 0 ); + arr(i, j, k, comp + 1 ) += arr_ff(i, j, k, 1 ); + } + ); + AMREX_ASSERT_WITH_MESSAGE(laser.m_lambda0_from_file == m_lambda0 && m_lambda0 != 0, + "The central wavelength of laser from openPMD file and other lasers must be identical"); + m_lambda0 = laser.m_lambda0_from_file; + #ifdef AMREX_USE_MPI + // need to communicate m_lambda0 as it is read in from the input file only by the head rank + MPI_Bcast(&m_lambda0, + 1, + amrex::ParallelDescriptor::Mpi_typemap::type(), + Hipace::HeadRankID(), + amrex::ParallelDescriptor::Communicator()); + #endif + } if (laser.m_laser_init_type == "parser") { auto profile_real = laser.m_profile_real; auto profile_imag = laser.m_profile_imag; From c504a84768ed2025229c58229d60f5b2b9e6b3a7 Mon Sep 17 00:00:00 2001 From: huixingjian Date: Fri, 6 Sep 2024 15:11:21 +0200 Subject: [PATCH 06/20] missing laser creation --- src/laser/Laser.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/laser/Laser.cpp b/src/laser/Laser.cpp index 95579e7c11..3937a319f2 100644 --- a/src/laser/Laser.cpp +++ b/src/laser/Laser.cpp @@ -59,7 +59,6 @@ Laser::Laser (std::string name, amrex::Geometry laser_geom_3D) } } - void Laser::GetEnvelopeFromFileHelper (amrex::Geometry laser_geom_3D) { @@ -340,4 +339,3 @@ Laser::GetEnvelopeFromFile (amrex::Geometry laser_geom_3D) { "Add HiPACE_OPENPMD=ON when compiling HiPACE++.\n"); #endif // HIPACE_USE_OPENPMD } - From 0a4ea3145f74faa74ab7c207acd5857d5d838fd7 Mon Sep 17 00:00:00 2001 From: huixingjian Date: Fri, 6 Sep 2024 15:22:32 +0200 Subject: [PATCH 07/20] Intialise the laser objects --- src/laser/MultiLaser.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/laser/MultiLaser.cpp b/src/laser/MultiLaser.cpp index bd457f69d0..d9ef82da0d 100644 --- a/src/laser/MultiLaser.cpp +++ b/src/laser/MultiLaser.cpp @@ -102,6 +102,12 @@ MultiLaser::MakeLaserGeometry (const amrex::Geometry& field_geom_3D) // make the geometry, slice box and ba and dm m_laser_geom_3D.define(domain_3D_laser, real_box, amrex::CoordSys::cartesian, {0, 0, 0}); + m_nlasers = m_names.size(); + + for (int i = 0; i < m_nlasers; ++i) { + m_all_lasers.emplace_back(Laser(m_names[i], m_laser_geom_3D)); + amrex::Print()<<"laser"+ m_names[i] + "loaded"; + } m_slice_box = domain_3D_laser; m_slice_box.setSmall(2, 0); From a5311971762784eb1a5826e066c67d837027284e Mon Sep 17 00:00:00 2001 From: Xingjian Hui <151739545+huixingjian@users.noreply.github.com> Date: Mon, 30 Sep 2024 16:31:38 +0200 Subject: [PATCH 08/20] Update src/laser/Laser.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Maxence Thévenet --- 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 3937a319f2..3650eef6a9 100644 --- a/src/laser/Laser.cpp +++ b/src/laser/Laser.cpp @@ -39,7 +39,7 @@ Laser::Laser (std::string name, amrex::Geometry laser_geom_3D) 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 gaussian lasers"); + "Please specify exlusively either the pulse length L0 or the duration tau of gaussian lasers"); if (duration_is_specified) m_L0 = m_tau*get_phys_const().c; queryWithParser(pp, "focal_distance", m_focal_distance); queryWithParser(pp, "position_mean", m_position_mean); From ff111240bbaa0a5a63df2c48a8356ddb710d73dc Mon Sep 17 00:00:00 2001 From: Xingjian Hui <151739545+huixingjian@users.noreply.github.com> Date: Mon, 30 Sep 2024 16:31:47 +0200 Subject: [PATCH 09/20] Update src/laser/Laser.H MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Maxence Thévenet --- src/laser/Laser.H | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/laser/Laser.H b/src/laser/Laser.H index 60afd9a5bd..d1b53decdd 100644 --- a/src/laser/Laser.H +++ b/src/laser/Laser.H @@ -19,7 +19,7 @@ class Laser { public: -/** \brief Read in a laser from an openPMD file */ + /** \brief Read in a laser from an openPMD file */ void GetEnvelopeFromFileHelper (amrex::Geometry laser_geom_3D); template void GetEnvelopeFromFile (amrex::Geometry laser_geom_3D); From 6a287420fef5cd5575258fdf4c2ca8bfaa82b667 Mon Sep 17 00:00:00 2001 From: Xingjian Hui <151739545+huixingjian@users.noreply.github.com> Date: Mon, 30 Sep 2024 16:31:58 +0200 Subject: [PATCH 10/20] Update src/laser/MultiLaser.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Maxence Thévenet --- src/laser/MultiLaser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/laser/MultiLaser.cpp b/src/laser/MultiLaser.cpp index d9ef82da0d..13f33c6353 100644 --- a/src/laser/MultiLaser.cpp +++ b/src/laser/MultiLaser.cpp @@ -823,7 +823,7 @@ MultiLaser::InitLaserSlice (const int islice, const int comp) const amrex::Box& bx = mfi.tilebox(); amrex::Array4 const & arr = m_slices.array(mfi); // Initialize a laser envelope on slice islice - for (int ilaser=0; ilaser < m_nlasers; ilaser++) { + for (int ilaser = 0; ilaser < m_nlasers; ilaser++) { auto& laser = m_all_lasers[ilaser]; if (laser.m_laser_init_type == "from_file"){ amrex::Array4 const& arr_ff = laser.m_F_input_file.array(); From d48b1dad2dd5ba15507374d3a4bc0063bdead4ee Mon Sep 17 00:00:00 2001 From: Xingjian Hui <151739545+huixingjian@users.noreply.github.com> Date: Mon, 30 Sep 2024 16:32:05 +0200 Subject: [PATCH 11/20] Update src/laser/MultiLaser.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Maxence Thévenet --- src/laser/MultiLaser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/laser/MultiLaser.cpp b/src/laser/MultiLaser.cpp index 13f33c6353..bd437793ab 100644 --- a/src/laser/MultiLaser.cpp +++ b/src/laser/MultiLaser.cpp @@ -106,7 +106,7 @@ MultiLaser::MakeLaserGeometry (const amrex::Geometry& field_geom_3D) for (int i = 0; i < m_nlasers; ++i) { m_all_lasers.emplace_back(Laser(m_names[i], m_laser_geom_3D)); - amrex::Print()<<"laser"+ m_names[i] + "loaded"; + amrex::Print()<<"Laser "+ m_names[i] + " loaded"; } m_slice_box = domain_3D_laser; From d074632df66fb0115709c4f9a6cb7711488a7cb6 Mon Sep 17 00:00:00 2001 From: Xingjian Hui <151739545+huixingjian@users.noreply.github.com> Date: Mon, 30 Sep 2024 16:32:17 +0200 Subject: [PATCH 12/20] Update src/laser/Laser.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Maxence Thévenet --- 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 3650eef6a9..b9969c1bdf 100644 --- a/src/laser/Laser.cpp +++ b/src/laser/Laser.cpp @@ -55,7 +55,7 @@ Laser::Laser (std::string name, amrex::Geometry laser_geom_3D) return; } else { - amrex::Abort("ilegal init type specified"); + amrex::Abort("Illegal init type specified for laser. Must be one of: gaussian, from_file, parser."); } } From 086c4bbf600cd59de44053a98abfcc0b9decb040 Mon Sep 17 00:00:00 2001 From: huixingjian Date: Mon, 30 Sep 2024 16:50:23 +0200 Subject: [PATCH 13/20] add documentation for varaibles --- docs/source/run/parameters.rst | 2 +- examples/laser/analysis_laser_init_chirp.py | 103 ++++++++++++++++++++ src/laser/Laser.H | 1 + 3 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 examples/laser/analysis_laser_init_chirp.py diff --git a/docs/source/run/parameters.rst b/docs/source/run/parameters.rst index 6f71dc84db..55044c7039 100644 --- a/docs/source/run/parameters.rst +++ b/docs/source/run/parameters.rst @@ -912,7 +912,7 @@ Option: ``gaussian`` Option: ``from_file`` -* ``.input_file`` (`string`) (default `""`) +* ``.input_file`` (`string`) optional (default `""`) Path to an openPMD file containing a laser envelope. The file should comply with the `LaserEnvelope extension of the openPMD-standard `__, as generated by `LASY `__. Currently supported geometries: 3D or cylindrical profiles with azimuthal decomposition. diff --git a/examples/laser/analysis_laser_init_chirp.py b/examples/laser/analysis_laser_init_chirp.py new file mode 100644 index 0000000000..01db93a355 --- /dev/null +++ b/examples/laser/analysis_laser_init_chirp.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 + +import numpy as np +import scipy.constants as scc +from openpmd_viewer.addons import LpaDiagnostics +import argparse + +# Constants +C = scc.c # Speed of light (precomputing constant) + + +def get_zeta(Ar, m, w0, L): + laser_module = np.abs(Ar) + phi_envelope = np.unwrap(np.angle(Ar), axis=1) + + # Vectorized operations to calculate pphi_pz and pphi_pzpy + z_diff = np.diff(m.z) + x_diff = np.diff(m.x) + + pphi_pz = np.diff(phi_envelope, axis=0) / (z_diff[:, None] / C) + pphi_pzpy = np.diff(pphi_pz, axis=1) / x_diff + + # Vectorized summation + weighted_sum = np.sum(pphi_pzpy * laser_module[:-2, :-2]) + total_sum = np.sum(laser_module[:-2, :-2]) + + nu = weighted_sum / C / total_sum + a = 4 * nu * w0**2 * L**4 + b = -4 * C + c = nu * w0**2 * L**2 + + zeta_solutions = np.roots([a, b, c]) + return np.min(zeta_solutions) + + +def get_phi2(Ar, m, tau): + laser_module = np.abs(Ar) + phi_envelope = np.unwrap(np.angle(Ar), axis=0) + + z_diff = np.diff(m.z) + + # Vectorized operations to calculate pphi_pz and pphi_pz2 + pphi_pz = np.diff(phi_envelope, axis=0) / (z_diff[:, None] / C) + pphi_pz2 = np.diff(pphi_pz, axis=1) / (z_diff[:-1][:, None] / C) + + # Vectorized summation + temp_chirp = np.sum(pphi_pz2 * laser_module[:-2, :-2]) + total_sum = np.sum(laser_module[:-2, :-2]) + + x = temp_chirp * C**2 / total_sum + a = 4 * x + b = -4 + c = tau**4 * x + + zeta_solutions = np.roots([a, b, c]) + return np.max(zeta_solutions) + + +def get_centroids(F, x, z): + # Vectorized computation of centroids + index_array = np.arange(F.shape[1])[None, :] # Faster with broadcasting + centroids = np.sum(index_array * np.abs(F)**2, axis=1) / np.sum(np.abs(F)**2, axis=1) + return z[centroids.astype(int)] + + +def get_beta(F, m, k0): + z_centroids = get_centroids(F.T, m.x, m.z) + weight = np.mean(np.abs(F.T)**2, axis=np.ndim(F) - 1) + + # Vectorized derivative calculation + derivative = np.gradient(z_centroids) / (m.x[1] - m.x[0]) + + return np.sum(derivative * weight) / np.sum(weight) / k0 / C + + +parser = argparse.ArgumentParser(description='Verify the chirp initialization') +parser.add_argument('--output-dir', + dest='output_dir', + default='diags/hdf5', + help='Path to the directory containing output files') +parser.add_argument('--chirp_type', + dest='chirp_type', + default='phi2', + help='The type of the initialized chirp') +args = parser.parse_args() + +ts = LpaDiagnostics(args.output_dir) + +Ar, m = ts.get_field(field='laserEnvelope', iteration=0) +lambda0 = 0.8e-6 # Laser wavelength +w0 = 30.e-6 # Laser waist +L0 = 5e-6 +tau = L0 / C # Laser duration +k0 = 2 * np.pi / lambda0 +if args.chirp_type == 'phi2': + phi2 = get_phi2(Ar, m, tau) + assert np.abs(phi2 - 2.4e-26) / 2.4e-26 < 1e-2 +elif args.chirp_type == 'zeta': + zeta = get_zeta(Ar, m, w0, L0) + assert np.abs(zeta - 2.4e-19) / 2.4e-19 < 1e-2 +elif args.chirp_type == 'beta': + beta = get_beta(Ar, m, k0) + assert np.abs(beta - 2e-17) / 2e-17 < 1e-2 diff --git a/src/laser/Laser.H b/src/laser/Laser.H index d1b53decdd..5cdd3af3c2 100644 --- a/src/laser/Laser.H +++ b/src/laser/Laser.H @@ -20,6 +20,7 @@ class Laser { public: /** \brief Read in a laser from an openPMD file */ + \param[in] laser_geom_3D 3D laser geometry for level 0 void GetEnvelopeFromFileHelper (amrex::Geometry laser_geom_3D); template void GetEnvelopeFromFile (amrex::Geometry laser_geom_3D); From b19863c0ad8d64ed5f2b7b9d7732184bdb18227c Mon Sep 17 00:00:00 2001 From: huixingjian Date: Mon, 30 Sep 2024 16:56:37 +0200 Subject: [PATCH 14/20] add comments --- src/laser/Laser.H | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/laser/Laser.H b/src/laser/Laser.H index 5cdd3af3c2..4e6a3b4825 100644 --- a/src/laser/Laser.H +++ b/src/laser/Laser.H @@ -19,8 +19,9 @@ class Laser { public: - /** \brief Read in a laser from an openPMD file */ - \param[in] laser_geom_3D 3D laser geometry for level 0 + /** \brief Read in a laser from an openPMD file + *\param[in] laser_geom_3D 3D laser geometry for level 0 + */ void GetEnvelopeFromFileHelper (amrex::Geometry laser_geom_3D); template void GetEnvelopeFromFile (amrex::Geometry laser_geom_3D); From e5d96197f0baf80dc278d7a2188af44b066faa45 Mon Sep 17 00:00:00 2001 From: huixingjian Date: Wed, 2 Oct 2024 16:58:25 +0200 Subject: [PATCH 15/20] change the document --- docs/source/run/parameters.rst | 82 ++++++++++++++++------------------ 1 file changed, 39 insertions(+), 43 deletions(-) diff --git a/docs/source/run/parameters.rst b/docs/source/run/parameters.rst index 55044c7039..b4e469e612 100644 --- a/docs/source/run/parameters.rst +++ b/docs/source/run/parameters.rst @@ -873,68 +873,64 @@ Parameters starting with ``lasers.`` apply to all laser pulses, parameters start * ``.init_type`` (list of `string`) optional (default `gaussian`) The initializing method of laser. Possible options are: - * ``gaussian``(default) the laser is iniliatized with an ideal gaussian pulse. - - * ``from_file``, the laser is loaded from an openPMD file. - * ``parser``, the laser is initialized with the expression of the complex envelope function. -Option: ``gaussian`` + Option: ``gaussian`` (default) the laser is iniliatized with an ideal gaussian pulse. -* ``.a0`` (`float`) optional (default `0`) - Peak normalized vector potential of the laser pulse. + * ``.a0`` (`float`) optional (default `0`) + Peak normalized vector potential of the laser pulse. -* ``lasers.lambda0`` (`float`) - Wavelength of the laser pulses. Currently, all pulses must have the same wavelength. + * ``lasers.lambda0`` (`float`) + Wavelength of the laser pulses. Currently, all pulses must have the same wavelength. -* ``.position_mean`` (3 `float`) optional (default `0 0 0`) - The mean position of the laser in `x, y, z`. + * ``.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`. + * ``.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``. + * ``.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 is set to `laser.tau`:math:`*c_0`. - Use either the pulse length or the pulse duration. + * ``.tau`` (`float`) optional (default `0`) + The laser pulse duration. The pulse length is 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). + * ``.focal_distance`` (`float`) + Distance at which the laser pulse if focused (in the z direction, counted from laser initial position). -* ``.propagation_angle_yz`` (`float`) optinal (default `0`) - Propagation angle of the pulse in the yz plane (0 is the along the z axis) + * ``.propagation_angle_yz`` (`float`) optional (default `0`) + Propagation angle of the pulse in the yz plane (0 is the along the z axis) -* ``.PFT_yz`` (`float`) optinal (default `pi/2`) - Pulse front tilt angle on yz plane - the angle between the pulse front (maximum intensity contour)and the propagation - direction defined by [Selcuk Akturk Opt. Express 12 (2004)](pi/2 is no PFT) + * ``.PFT_yz`` (`float`) optional (default `pi/2`) + Pulse front tilt angle on yz plane - the angle between the pulse front (maximum intensity contour)and the propagation + direction defined by [Selcuk Akturk Opt. Express 12 (2004)](pi/2 is no PFT) -Option: ``from_file`` + Option: ``from_file`` the laser is loaded from an openPMD file. -* ``.input_file`` (`string`) optional (default `""`) - Path to an openPMD file containing a laser envelope. - The file should comply with the `LaserEnvelope extension of the openPMD-standard `__, as generated by `LASY `__. - Currently supported geometries: 3D or cylindrical profiles with azimuthal decomposition. - The laser pulse is injected in the HiPACE++ simulation so that the beginning of the temporal profile from the file corresponds to the head of the simulation box, and time (in the file) is converted to space (HiPACE++ longitudinal coordinate) with ``z = -c*t + const``. - If this parameter is set, then the file is used to initialize all lasers instead of using a gaussian profile. + * ``.input_file`` (`string`) optional (default `""`) + Path to an openPMD file containing a laser envelope. + The file should comply with the `LaserEnvelope extension of the openPMD-standard `__, as generated by `LASY `__. + Currently supported geometries: 3D or cylindrical profiles with azimuthal decomposition. + The laser pulse is injected in the HiPACE++ simulation so that the beginning of the temporal profile from the file corresponds to the head of the simulation box, and time (in the file) is converted to space (HiPACE++ longitudinal coordinate) with ``z = -c*t + const``. + If this parameter is set, then the file is used to initialize all lasers instead of using a gaussian profile. -* ``.openPMD_laser_name`` (`string`) optional (default `laserEnvelope`) - Name of the laser envelope field inside the openPMD file to be read in. + * ``.openPMD_laser_name`` (`string`) optional (default `laserEnvelope`) + Name of the laser envelope field inside the openPMD file to be read in. -* ``.iteration`` (`int`) optional (default `0`) - Iteration of the openPMD file to be read in. + * ``.iteration`` (`int`) optional (default `0`) + Iteration of the openPMD file to be read in. -Option: ``parser`` + Option: ``parser`` -* ``.laser_real(x,y,z)`` (`string`) - Expression for the real part of the laser evelope in `x, y, z`. + * ``.laser_real(x,y,z)`` (`string`) + Expression for the real part of the laser evelope in `x, y, z`. -* ``.laser_imag(x,y,z)`` (`string`) - Expression for the imaginary part of the laser evelope `x, y, z`. + * ``.laser_imag(x,y,z)`` (`string`) + Expression for the imaginary part of the laser evelope `x, y, z`. -* ``lasers.lambda0`` (`float`) - Wavelength of the laser pulses. Currently, all pulses must have the same wavelength. + * ``lasers.lambda0`` (`float`) + Wavelength of the laser pulses. Currently, all pulses must have the same wavelength. Diagnostic parameters --------------------- From f0fa8dd931e6731d98a2307967604ee45d0335d3 Mon Sep 17 00:00:00 2001 From: huixingjian Date: Mon, 7 Oct 2024 10:25:24 +0200 Subject: [PATCH 16/20] admend the doc --- docs/source/run/Makefile | 20 ++++++++++++ docs/source/run/make.bat | 35 +++++++++++++++++++++ docs/source/run/parameters.rst | 8 ++--- docs/source/run/source/conf.py | 52 ++++++++++++++++++++++++++++++++ docs/source/run/source/index.rst | 20 ++++++++++++ 5 files changed, 130 insertions(+), 5 deletions(-) create mode 100644 docs/source/run/Makefile create mode 100644 docs/source/run/make.bat create mode 100644 docs/source/run/source/conf.py create mode 100644 docs/source/run/source/index.rst diff --git a/docs/source/run/Makefile b/docs/source/run/Makefile new file mode 100644 index 0000000000..d0c3cbf102 --- /dev/null +++ b/docs/source/run/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/source/run/make.bat b/docs/source/run/make.bat new file mode 100644 index 0000000000..747ffb7b30 --- /dev/null +++ b/docs/source/run/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/source/run/parameters.rst b/docs/source/run/parameters.rst index b4e469e612..e7005c1ba7 100644 --- a/docs/source/run/parameters.rst +++ b/docs/source/run/parameters.rst @@ -873,8 +873,6 @@ Parameters starting with ``lasers.`` apply to all laser pulses, parameters start * ``.init_type`` (list of `string`) optional (default `gaussian`) The initializing method of laser. Possible options are: - * ``parser``, the laser is initialized with the expression of the complex envelope function. - Option: ``gaussian`` (default) the laser is iniliatized with an ideal gaussian pulse. * ``.a0`` (`float`) optional (default `0`) @@ -921,12 +919,12 @@ Parameters starting with ``lasers.`` apply to all laser pulses, parameters start * ``.iteration`` (`int`) optional (default `0`) Iteration of the openPMD file to be read in. - Option: ``parser`` + Option: ``parser``, the laser is initialized with the expression of the complex envelope function. - * ``.laser_real(x,y,z)`` (`string`) + * ``.laser_real(x,y,z)`` optional (`string`) (default `""`) Expression for the real part of the laser evelope in `x, y, z`. - * ``.laser_imag(x,y,z)`` (`string`) + * ``.laser_imag(x,y,z)`` optional (`string`) (default `""`) Expression for the imaginary part of the laser evelope `x, y, z`. * ``lasers.lambda0`` (`float`) diff --git a/docs/source/run/source/conf.py b/docs/source/run/source/conf.py new file mode 100644 index 0000000000..9a91b45b7d --- /dev/null +++ b/docs/source/run/source/conf.py @@ -0,0 +1,52 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + + +# -- Project information ----------------------------------------------------- + +project = 'hipacedoc' +copyright = '2024, xingjian hui' +author = 'xingjian hui' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] \ No newline at end of file diff --git a/docs/source/run/source/index.rst b/docs/source/run/source/index.rst new file mode 100644 index 0000000000..bb3b718da1 --- /dev/null +++ b/docs/source/run/source/index.rst @@ -0,0 +1,20 @@ +.. hipacedoc documentation master file, created by + sphinx-quickstart on Wed Oct 2 17:09:03 2024. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to hipacedoc's documentation! +===================================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` From a0f03b25ffac8f97a93ac59b4877a56e5fac4647 Mon Sep 17 00:00:00 2001 From: huixingjian Date: Mon, 7 Oct 2024 11:00:29 +0200 Subject: [PATCH 17/20] delete useless files --- docs/source/run/Makefile | 20 ---- docs/source/run/make.bat | 35 ------- docs/source/run/source/conf.py | 52 ---------- docs/source/run/source/index.rst | 20 ---- examples/laser/analysis_laser_init_chirp.py | 103 -------------------- 5 files changed, 230 deletions(-) delete mode 100644 docs/source/run/Makefile delete mode 100644 docs/source/run/make.bat delete mode 100644 docs/source/run/source/conf.py delete mode 100644 docs/source/run/source/index.rst delete mode 100644 examples/laser/analysis_laser_init_chirp.py diff --git a/docs/source/run/Makefile b/docs/source/run/Makefile deleted file mode 100644 index d0c3cbf102..0000000000 --- a/docs/source/run/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = source -BUILDDIR = build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/source/run/make.bat b/docs/source/run/make.bat deleted file mode 100644 index 747ffb7b30..0000000000 --- a/docs/source/run/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=source -set BUILDDIR=build - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.https://www.sphinx-doc.org/ - exit /b 1 -) - -if "%1" == "" goto help - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:end -popd diff --git a/docs/source/run/source/conf.py b/docs/source/run/source/conf.py deleted file mode 100644 index 9a91b45b7d..0000000000 --- a/docs/source/run/source/conf.py +++ /dev/null @@ -1,52 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# This file only contains a selection of the most common options. For a full -# list see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) - - -# -- Project information ----------------------------------------------------- - -project = 'hipacedoc' -copyright = '2024, xingjian hui' -author = 'xingjian hui' - - -# -- General configuration --------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ -] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = [] - - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = 'alabaster' - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] \ No newline at end of file diff --git a/docs/source/run/source/index.rst b/docs/source/run/source/index.rst deleted file mode 100644 index bb3b718da1..0000000000 --- a/docs/source/run/source/index.rst +++ /dev/null @@ -1,20 +0,0 @@ -.. hipacedoc documentation master file, created by - sphinx-quickstart on Wed Oct 2 17:09:03 2024. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to hipacedoc's documentation! -===================================== - -.. toctree:: - :maxdepth: 2 - :caption: Contents: - - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/examples/laser/analysis_laser_init_chirp.py b/examples/laser/analysis_laser_init_chirp.py deleted file mode 100644 index 01db93a355..0000000000 --- a/examples/laser/analysis_laser_init_chirp.py +++ /dev/null @@ -1,103 +0,0 @@ -#!/usr/bin/env python3 - -import numpy as np -import scipy.constants as scc -from openpmd_viewer.addons import LpaDiagnostics -import argparse - -# Constants -C = scc.c # Speed of light (precomputing constant) - - -def get_zeta(Ar, m, w0, L): - laser_module = np.abs(Ar) - phi_envelope = np.unwrap(np.angle(Ar), axis=1) - - # Vectorized operations to calculate pphi_pz and pphi_pzpy - z_diff = np.diff(m.z) - x_diff = np.diff(m.x) - - pphi_pz = np.diff(phi_envelope, axis=0) / (z_diff[:, None] / C) - pphi_pzpy = np.diff(pphi_pz, axis=1) / x_diff - - # Vectorized summation - weighted_sum = np.sum(pphi_pzpy * laser_module[:-2, :-2]) - total_sum = np.sum(laser_module[:-2, :-2]) - - nu = weighted_sum / C / total_sum - a = 4 * nu * w0**2 * L**4 - b = -4 * C - c = nu * w0**2 * L**2 - - zeta_solutions = np.roots([a, b, c]) - return np.min(zeta_solutions) - - -def get_phi2(Ar, m, tau): - laser_module = np.abs(Ar) - phi_envelope = np.unwrap(np.angle(Ar), axis=0) - - z_diff = np.diff(m.z) - - # Vectorized operations to calculate pphi_pz and pphi_pz2 - pphi_pz = np.diff(phi_envelope, axis=0) / (z_diff[:, None] / C) - pphi_pz2 = np.diff(pphi_pz, axis=1) / (z_diff[:-1][:, None] / C) - - # Vectorized summation - temp_chirp = np.sum(pphi_pz2 * laser_module[:-2, :-2]) - total_sum = np.sum(laser_module[:-2, :-2]) - - x = temp_chirp * C**2 / total_sum - a = 4 * x - b = -4 - c = tau**4 * x - - zeta_solutions = np.roots([a, b, c]) - return np.max(zeta_solutions) - - -def get_centroids(F, x, z): - # Vectorized computation of centroids - index_array = np.arange(F.shape[1])[None, :] # Faster with broadcasting - centroids = np.sum(index_array * np.abs(F)**2, axis=1) / np.sum(np.abs(F)**2, axis=1) - return z[centroids.astype(int)] - - -def get_beta(F, m, k0): - z_centroids = get_centroids(F.T, m.x, m.z) - weight = np.mean(np.abs(F.T)**2, axis=np.ndim(F) - 1) - - # Vectorized derivative calculation - derivative = np.gradient(z_centroids) / (m.x[1] - m.x[0]) - - return np.sum(derivative * weight) / np.sum(weight) / k0 / C - - -parser = argparse.ArgumentParser(description='Verify the chirp initialization') -parser.add_argument('--output-dir', - dest='output_dir', - default='diags/hdf5', - help='Path to the directory containing output files') -parser.add_argument('--chirp_type', - dest='chirp_type', - default='phi2', - help='The type of the initialized chirp') -args = parser.parse_args() - -ts = LpaDiagnostics(args.output_dir) - -Ar, m = ts.get_field(field='laserEnvelope', iteration=0) -lambda0 = 0.8e-6 # Laser wavelength -w0 = 30.e-6 # Laser waist -L0 = 5e-6 -tau = L0 / C # Laser duration -k0 = 2 * np.pi / lambda0 -if args.chirp_type == 'phi2': - phi2 = get_phi2(Ar, m, tau) - assert np.abs(phi2 - 2.4e-26) / 2.4e-26 < 1e-2 -elif args.chirp_type == 'zeta': - zeta = get_zeta(Ar, m, w0, L0) - assert np.abs(zeta - 2.4e-19) / 2.4e-19 < 1e-2 -elif args.chirp_type == 'beta': - beta = get_beta(Ar, m, k0) - assert np.abs(beta - 2e-17) / 2e-17 < 1e-2 From 70a34ed9b0dbfc5acdc3e935585e106630c37e7f Mon Sep 17 00:00:00 2001 From: huixingjian Date: Mon, 7 Oct 2024 15:58:14 +0200 Subject: [PATCH 18/20] add /n when print laser loaded --- src/laser/MultiLaser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/laser/MultiLaser.cpp b/src/laser/MultiLaser.cpp index bd437793ab..4e126a4484 100644 --- a/src/laser/MultiLaser.cpp +++ b/src/laser/MultiLaser.cpp @@ -106,7 +106,7 @@ MultiLaser::MakeLaserGeometry (const amrex::Geometry& field_geom_3D) for (int i = 0; i < m_nlasers; ++i) { m_all_lasers.emplace_back(Laser(m_names[i], m_laser_geom_3D)); - amrex::Print()<<"Laser "+ m_names[i] + " loaded"; + amrex::Print()<<"Laser "+ m_names[i] + " loaded" << "\n"; } m_slice_box = domain_3D_laser; From e576848af6fdf10077d6750a786d1d3aa3c6578e Mon Sep 17 00:00:00 2001 From: Xingjian Hui <151739545+huixingjian@users.noreply.github.com> Date: Mon, 7 Oct 2024 17:26:53 +0200 Subject: [PATCH 19/20] Update src/laser/MultiLaser.cpp Co-authored-by: Alexander Sinn <64009254+AlexanderSinn@users.noreply.github.com> --- src/laser/MultiLaser.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/laser/MultiLaser.cpp b/src/laser/MultiLaser.cpp index a339c9f3f7..049248ab28 100644 --- a/src/laser/MultiLaser.cpp +++ b/src/laser/MultiLaser.cpp @@ -837,8 +837,8 @@ MultiLaser::InitLaserSlice (const int islice, const int comp) arr(i, j, k, comp ) = 0._rt; arr(i, j, k, comp + 1 ) = 0._rt; } - arr(i, j, k, comp ) += arr_ff(i, j, k, 0 ); - arr(i, j, k, comp + 1 ) += arr_ff(i, j, k, 1 ); + arr(i, j, k, comp ) += arr_ff(i, j, islice, 0 ); + arr(i, j, k, comp + 1 ) += arr_ff(i, j, islice, 1 ); } ); AMREX_ASSERT_WITH_MESSAGE(laser.m_lambda0_from_file == m_lambda0 && m_lambda0 != 0, From 0f7b97847d2551e69d80af288cc0ef6629e5963e Mon Sep 17 00:00:00 2001 From: huixingjian Date: Wed, 9 Oct 2024 17:40:44 +0200 Subject: [PATCH 20/20] typo in doc --- docs/source/run/parameters.rst | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/docs/source/run/parameters.rst b/docs/source/run/parameters.rst index e7005c1ba7..66e0ae7382 100644 --- a/docs/source/run/parameters.rst +++ b/docs/source/run/parameters.rst @@ -871,9 +871,9 @@ Parameters starting with ``lasers.`` apply to all laser pulses, parameters start Whether to use the most stable discretization for the envelope solver. * ``.init_type`` (list of `string`) optional (default `gaussian`) - The initializing method of laser. Possible options are: + The initialisation method of laser. Possible options are: - Option: ``gaussian`` (default) the laser is iniliatized with an ideal gaussian pulse. + Option: ``gaussian`` (default) the laser is initialised with an ideal gaussian pulse. * ``.a0`` (`float`) optional (default `0`) Peak normalized vector potential of the laser pulse. @@ -895,14 +895,10 @@ Parameters starting with ``lasers.`` apply to all laser pulses, parameters start 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). + Distance at which the laser pulse is focused (in the z direction, counted from laser initial position). * ``.propagation_angle_yz`` (`float`) optional (default `0`) - Propagation angle of the pulse in the yz plane (0 is the along the z axis) - - * ``.PFT_yz`` (`float`) optional (default `pi/2`) - Pulse front tilt angle on yz plane - the angle between the pulse front (maximum intensity contour)and the propagation - direction defined by [Selcuk Akturk Opt. Express 12 (2004)](pi/2 is no PFT) + Propagation angle of the pulse in the yz plane (0 is along the z axis) Option: ``from_file`` the laser is loaded from an openPMD file. @@ -922,10 +918,10 @@ Parameters starting with ``lasers.`` apply to all laser pulses, parameters start Option: ``parser``, the laser is initialized with the expression of the complex envelope function. * ``.laser_real(x,y,z)`` optional (`string`) (default `""`) - Expression for the real part of the laser evelope in `x, y, z`. + Expression for the real part of the laser envelope in `x, y, z`. * ``.laser_imag(x,y,z)`` optional (`string`) (default `""`) - Expression for the imaginary part of the laser evelope `x, y, z`. + Expression for the imaginary part of the laser envelope `x, y, z`. * ``lasers.lambda0`` (`float`) Wavelength of the laser pulses. Currently, all pulses must have the same wavelength.