From 910651721bccb3743a4ea8c8fe0c562c37f3ff6e Mon Sep 17 00:00:00 2001 From: Chad Mitchell Date: Tue, 7 Jun 2022 15:47:07 -0700 Subject: [PATCH 01/18] Examples for 3D space charge benchmarking - Modified the initial beam size in the IOTA lens benchmark example. - Added 2 benchmarks of 3D space charge for initial testing. - Add documentation for 2 benchmarks with space charge. - Add a benchmark example with space charge and periodic s-dependent focusing. - Added an s-dependent example using a Kurth beam without space charge. - Modified tolerance for IOTA lens benchmark example. Reduced tolerance to account for smaller initial beam size and improved preservation of invariants of motion. - Modified tolerances of space charge examples to allow CI tests to pass when space charge is not active. - Modified tolerance for space charge examples. These should fail unless space charge is turned on. --- examples/kurth/input_kurth_10nC.in | 37 ++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 examples/kurth/input_kurth_10nC.in diff --git a/examples/kurth/input_kurth_10nC.in b/examples/kurth/input_kurth_10nC.in new file mode 100644 index 000000000..be1a3611d --- /dev/null +++ b/examples/kurth/input_kurth_10nC.in @@ -0,0 +1,37 @@ +############################################################################### +# Particle Beam(s) +############################################################################### +beam.npart = 10000 +beam.units = static +beam.energy = 2.0e3 +beam.charge = 1.0e-8 +beam.particle = proton +beam.distribution = kurth6d +beam.sigmaX = 1.2154443728379865788e-3 +beam.sigmaY = 1.2154443728379865788e-3 +beam.sigmaT = 4.0956844276541331005e-4 +beam.sigmaPx = 8.2274435782286157175e-4 +beam.sigmaPy = 8.2274435782286157175e-4 +beam.sigmaPt = 2.4415943602685364584e-3 + + +############################################################################### +# Beamline: lattice elements and segments +############################################################################### +lattice.elements = constf1 + +constf1.type = constf +constf1.ds = 2.0 +constf1.kx = 1.0 +constf1.ky = 1.0 +constf1.kt = 1.0 + + +############################################################################### +# Algorithms +############################################################################### +algo.particle_shape = 2 +algo.space_charge = true + +amr.n_cell = 40 40 32 +geometry.prob_relative = 1.0 From 5d98f066ee2c9d2b446c1a442dd832bbaa919228 Mon Sep 17 00:00:00 2001 From: Chad Mitchell <46825199+cemitch99@users.noreply.github.com> Date: Mon, 5 Dec 2022 15:14:50 -0800 Subject: [PATCH 02/18] Update input_kurth_10nC.in Selected numerical values for amr.n_cell, lattice.nslice, and geometry.prob_relative. --- examples/kurth/input_kurth_10nC.in | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/kurth/input_kurth_10nC.in b/examples/kurth/input_kurth_10nC.in index be1a3611d..6349bfdda 100644 --- a/examples/kurth/input_kurth_10nC.in +++ b/examples/kurth/input_kurth_10nC.in @@ -2,6 +2,7 @@ # Particle Beam(s) ############################################################################### beam.npart = 10000 +#beam.npart = 100000 #optional for increased precision beam.units = static beam.energy = 2.0e3 beam.charge = 1.0e-8 @@ -19,6 +20,8 @@ beam.sigmaPt = 2.4415943602685364584e-3 # Beamline: lattice elements and segments ############################################################################### lattice.elements = constf1 +lattice.nslice = 50 +#lattice.nslice = 100 #optional for increased precision constf1.type = constf constf1.ds = 2.0 @@ -33,5 +36,6 @@ constf1.kt = 1.0 algo.particle_shape = 2 algo.space_charge = true -amr.n_cell = 40 40 32 +amr.n_cell = 48 48 40 +#amr.n_cell = 72 72 72 #optional for increased precision geometry.prob_relative = 1.0 From f742231d52bb16653ab5405301599e9d4db42293 Mon Sep 17 00:00:00 2001 From: Chad Mitchell Date: Mon, 7 Aug 2023 12:20:33 -0700 Subject: [PATCH 03/18] Rename ShortRF and add MAD-X short RF model. --- examples/fodo_rf/input_fodo_rf.in | 2 +- examples/fodo_rf/run_fodo_rf.py | 2 +- src/initialization/InitElement.cpp | 11 ++- src/particles/elements/All.H | 2 + src/particles/elements/Buncher.H | 107 +++++++++++++++++++++++++++++ src/particles/elements/ShortRF.H | 50 ++++++++++---- src/python/elements.cpp | 14 +++- 7 files changed, 169 insertions(+), 19 deletions(-) create mode 100644 src/particles/elements/Buncher.H diff --git a/examples/fodo_rf/input_fodo_rf.in b/examples/fodo_rf/input_fodo_rf.in index bd26e033c..5294b58f7 100644 --- a/examples/fodo_rf/input_fodo_rf.in +++ b/examples/fodo_rf/input_fodo_rf.in @@ -34,7 +34,7 @@ quad1.k = 2.5 drift1.type = drift drift1.ds = 1.0 -shortrf1.type = shortrf +shortrf1.type = buncher shortrf1.V = 0.01 shortrf1.k = 15.0 diff --git a/examples/fodo_rf/run_fodo_rf.py b/examples/fodo_rf/run_fodo_rf.py index 0adc0ddab..aaf44e29d 100644 --- a/examples/fodo_rf/run_fodo_rf.py +++ b/examples/fodo_rf/run_fodo_rf.py @@ -53,7 +53,7 @@ # Drift element drift1 = elements.Drift(ds=1.0) # Short RF cavity element -shortrf1 = elements.ShortRF(V=0.01, k=15.0) +shortrf1 = elements.Buncher(V=0.01, k=15.0) lattice_no_drifts = [quad1, shortrf1, quad2, shortrf1, quad1] # set first lattice element diff --git a/src/initialization/InitElement.cpp b/src/initialization/InitElement.cpp index 873041596..6ab6e0468 100644 --- a/src/initialization/InitElement.cpp +++ b/src/initialization/InitElement.cpp @@ -113,11 +113,18 @@ namespace detail pp_element.get("kt", kt); pp_element.queryAdd("nslice", nslice); m_lattice.emplace_back( ConstF(ds, kx, ky, kt, nslice) ); - } else if (element_type == "shortrf") { + } else if (element_type == "buncher") { amrex::Real V, k; pp_element.get("V", V); pp_element.get("k", k); - m_lattice.emplace_back( ShortRF(V, k) ); + m_lattice.emplace_back( Buncher(V, k) ); + } else if (element_type == "shortrf") { + amrex::Real V, freq; + amrex::Real phase = -90.0; + pp_element.get("V", V); + pp_element.get("freq", freq); + pp_element.queryAdd("phase", phase); + m_lattice.emplace_back( ShortRF(V, freq, phase) ); } else if (element_type == "multipole") { int m; amrex::Real k_normal, k_skew; diff --git a/src/particles/elements/All.H b/src/particles/elements/All.H index 27fe1a176..db46fe27d 100644 --- a/src/particles/elements/All.H +++ b/src/particles/elements/All.H @@ -10,6 +10,7 @@ #ifndef IMPACTX_ELEMENTS_ALL_H #define IMPACTX_ELEMENTS_ALL_H +#include "Buncher.H" #include "CFbend.H" #include "ChrDrift.H" #include "ChrQuad.H" @@ -40,6 +41,7 @@ namespace impactx { using KnownElements = std::variant< None, /* must be first, so KnownElements creates a default constructor */ + Buncher, CFbend, ChrAcc, ChrDrift, diff --git a/src/particles/elements/Buncher.H b/src/particles/elements/Buncher.H new file mode 100644 index 000000000..39e59ffd6 --- /dev/null +++ b/src/particles/elements/Buncher.H @@ -0,0 +1,107 @@ +/* Copyright 2022-2023 The Regents of the University of California, through Lawrence + * Berkeley National Laboratory (subject to receipt of any required + * approvals from the U.S. Dept. of Energy). All rights reserved. + * + * This file is part of ImpactX. + * + * Authors: Chad Mitchell, Axel Huebl + * License: BSD-3-Clause-LBNL + */ +#ifndef IMPACTX_BUNCHER_H +#define IMPACTX_BUNCHER_H + +#include "particles/ImpactXParticleContainer.H" +#include "mixin/beamoptic.H" +#include "mixin/thin.H" +#include "mixin/nofinalize.H" + +#include +#include + +#include + + +namespace impactx +{ + struct Buncher + : public elements::BeamOptic, + public elements::Thin, + public elements::NoFinalize + { + static constexpr auto name = "Buncher"; + using PType = ImpactXParticleContainer::ParticleType; + + /** A short RF cavity element at zero crossing for bunching + * + * @param V Normalized RF voltage drop V = Emax*L/(c*Brho) + * @param k Wavenumber of RF in 1/m + */ + Buncher( amrex::ParticleReal const V, amrex::ParticleReal const k ) + : m_V(V), m_k(k) + { + } + + /** Push all particles */ + using BeamOptic::operator(); + + /** This is a buncher functor, so that a variable of this type can be used like a + * buncher function. + * + * @param p Particle AoS data for positions and cpu/id + * @param px particle momentum in x + * @param py particle momentum in y + * @param pt particle momentum in t + * @param refpart reference particle + */ + AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE + void operator() ( + PType& AMREX_RESTRICT p, + amrex::ParticleReal & AMREX_RESTRICT px, + amrex::ParticleReal & AMREX_RESTRICT py, + amrex::ParticleReal & AMREX_RESTRICT pt, + RefPart const & refpart) const { + + using namespace amrex::literals; // for _rt and _prt + + // access AoS data such as positions and cpu/id + amrex::ParticleReal const x = p.pos(RealAoS::x); + amrex::ParticleReal const y = p.pos(RealAoS::y); + amrex::ParticleReal const t = p.pos(RealAoS::t); + + // access reference particle values to find (beta*gamma)^2 + amrex::ParticleReal const pt_ref = refpart.pt; + amrex::ParticleReal const betgam2 = pow(pt_ref, 2) - 1.0_prt; + + // intialize output values of momenta + amrex::ParticleReal pxout = px; + amrex::ParticleReal pyout = py; + amrex::ParticleReal ptout = pt; + + // advance position and momentum + p.pos(RealAoS::x) = x; + pxout = px + m_k*m_V/(2.0_prt*betgam2)*x; + + p.pos(RealAoS::y) = y; + pyout = py + m_k*m_V/(2.0_prt*betgam2)*y; + + p.pos(RealAoS::t) = t; + ptout = pt - m_k*m_V*t; + + // assign updated momenta + px = pxout; + py = pyout; + pt = ptout; + + } + + /** This pushes the reference particle. */ + using Thin::operator(); + + private: + amrex::ParticleReal m_V; //! normalized (max) RF voltage drop. + amrex::ParticleReal m_k; //! RF wavenumber in 1/m. + }; + +} // namespace impactx + +#endif // IMPACTX_BUNCHER_H diff --git a/src/particles/elements/ShortRF.H b/src/particles/elements/ShortRF.H index a3ff4645e..8a2b51537 100644 --- a/src/particles/elements/ShortRF.H +++ b/src/particles/elements/ShortRF.H @@ -31,13 +31,18 @@ namespace impactx static constexpr auto name = "ShortRF"; using PType = ImpactXParticleContainer::ParticleType; - /** A short RF cavity element at zero crossing for bunching + /** A short RF cavity element * - * @param V Normalized RF voltage drop V = Emax*L/(c*Brho) - * @param k Wavenumber of RF in 1/m + * @param V Normalized RF voltage V = maximum energy gain/(m*c^2) + * @param freq RF frequency in Hz + * @param phase RF synchronous phase of the reference particle in deg + * phi = 0: maximum energy gain (on-crest) + * phi = -90 deg: zero-crossing for bunching + * phi = 90 deg: zero-crossing for debunching */ - ShortRF( amrex::ParticleReal const V, amrex::ParticleReal const k ) - : m_V(V), m_k(k) + ShortRF( amrex::ParticleReal const V, amrex::ParticleReal const freq, + amrex::ParticleReal const phase ) + : m_V(V), m_freq(freq), m_phase(phase) { } @@ -68,30 +73,48 @@ namespace impactx amrex::ParticleReal const y = p.pos(RealAoS::y); amrex::ParticleReal const t = p.pos(RealAoS::t); - // access reference particle values to find (beta*gamma)^2 - amrex::ParticleReal const pt_ref = refpart.pt; - amrex::ParticleReal const betgam2 = pow(pt_ref, 2) - 1.0_prt; + // Define parameters and intermediate constants + using ablastr::constant::math::pi; + using ablastr::constant::SI::c; + amrex::ParticleReal const k = (2.0_prt*pi/c)*m_freq; + amrex::ParticleReal const phi = m_phase*(pi/180.0_prt); + + // access reference particle values (final, initial): + amrex::ParticleReal const ptf_ref = refpart.pt; + amrex::ParticleReal const pti_ref = ptf_ref + m_V*cos(phi); + amrex::ParticleReal const bgf = sqrt(pow(ptf_ref, 2) - 1.0_prt); + amrex::ParticleReal const bgi = sqrt(pow(pti_ref, 2) - 1.0_prt); + + // initial conversion from static to dynamic units: + px = px*bgi; + py = py*bgi; + pt = pt*bgi; // intialize output values of momenta amrex::ParticleReal pxout = px; amrex::ParticleReal pyout = py; amrex::ParticleReal ptout = pt; - // advance position and momentum + // advance position and momentum in dynamic units p.pos(RealAoS::x) = x; - pxout = px + m_k*m_V/(2.0_prt*betgam2)*x; + pxout = px; p.pos(RealAoS::y) = y; - pyout = py + m_k*m_V/(2.0_prt*betgam2)*y; + pyout = py; p.pos(RealAoS::t) = t; - ptout = pt - m_k*m_V*t; + ptout = pt - m_V*cos(k*t + phi) + m_V*cos(phi); // assign updated momenta px = pxout; py = pyout; pt = ptout; + // final conversion from dynamic to static units: + px = px/bgf; + py = py/bgf; + pt = pt/bgf; + } /** This pushes the reference particle. */ @@ -99,7 +122,8 @@ namespace impactx private: amrex::ParticleReal m_V; //! normalized (max) RF voltage drop. - amrex::ParticleReal m_k; //! RF wavenumber in 1/m. + amrex::ParticleReal m_freq; //! RF frequency in Hz. + amrex::ParticleReal m_phase; //! reference RF phase in degrees. }; } // namespace impactx diff --git a/src/python/elements.cpp b/src/python/elements.cpp index d734b76b4..606d071a1 100644 --- a/src/python/elements.cpp +++ b/src/python/elements.cpp @@ -299,12 +299,22 @@ void init_elements(py::module& m) ) ; + py::class_(me, "Buncher") + .def(py::init< + amrex::ParticleReal const, + amrex::ParticleReal const>(), + py::arg("V"), py::arg("k"), + "A short linear RF cavity element at zero-crossing for bunching." + ) + ; + py::class_(me, "ShortRF") .def(py::init< + amrex::ParticleReal const, amrex::ParticleReal const, amrex::ParticleReal const>(), - py::arg("V"), py::arg("k"), - "A short RF cavity element at zero crossing for bunching." + py::arg("V"), py::arg("freq"), py::arg("phase") = -90.0, + "A short RF cavity element." ) ; From 757522c5ad4a2cd1586765ea30d6ecf3133c01de Mon Sep 17 00:00:00 2001 From: Chad Mitchell <46825199+cemitch99@users.noreply.github.com> Date: Mon, 7 Aug 2023 12:24:04 -0700 Subject: [PATCH 04/18] Delete input_kurth_10nC.in This file is not part of this PR. --- examples/kurth/input_kurth_10nC.in | 41 ------------------------------ 1 file changed, 41 deletions(-) delete mode 100644 examples/kurth/input_kurth_10nC.in diff --git a/examples/kurth/input_kurth_10nC.in b/examples/kurth/input_kurth_10nC.in deleted file mode 100644 index 6349bfdda..000000000 --- a/examples/kurth/input_kurth_10nC.in +++ /dev/null @@ -1,41 +0,0 @@ -############################################################################### -# Particle Beam(s) -############################################################################### -beam.npart = 10000 -#beam.npart = 100000 #optional for increased precision -beam.units = static -beam.energy = 2.0e3 -beam.charge = 1.0e-8 -beam.particle = proton -beam.distribution = kurth6d -beam.sigmaX = 1.2154443728379865788e-3 -beam.sigmaY = 1.2154443728379865788e-3 -beam.sigmaT = 4.0956844276541331005e-4 -beam.sigmaPx = 8.2274435782286157175e-4 -beam.sigmaPy = 8.2274435782286157175e-4 -beam.sigmaPt = 2.4415943602685364584e-3 - - -############################################################################### -# Beamline: lattice elements and segments -############################################################################### -lattice.elements = constf1 -lattice.nslice = 50 -#lattice.nslice = 100 #optional for increased precision - -constf1.type = constf -constf1.ds = 2.0 -constf1.kx = 1.0 -constf1.ky = 1.0 -constf1.kt = 1.0 - - -############################################################################### -# Algorithms -############################################################################### -algo.particle_shape = 2 -algo.space_charge = true - -amr.n_cell = 48 48 40 -#amr.n_cell = 72 72 72 #optional for increased precision -geometry.prob_relative = 1.0 From 9c6a011b3a4f0541ca3cd50f423451054ab2242e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 7 Aug 2023 19:24:07 +0000 Subject: [PATCH 05/18] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/particles/elements/ShortRF.H | 2 +- src/python/elements.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/particles/elements/ShortRF.H b/src/particles/elements/ShortRF.H index 8a2b51537..47d87298a 100644 --- a/src/particles/elements/ShortRF.H +++ b/src/particles/elements/ShortRF.H @@ -31,7 +31,7 @@ namespace impactx static constexpr auto name = "ShortRF"; using PType = ImpactXParticleContainer::ParticleType; - /** A short RF cavity element + /** A short RF cavity element * * @param V Normalized RF voltage V = maximum energy gain/(m*c^2) * @param freq RF frequency in Hz diff --git a/src/python/elements.cpp b/src/python/elements.cpp index 606d071a1..212324fa3 100644 --- a/src/python/elements.cpp +++ b/src/python/elements.cpp @@ -302,7 +302,7 @@ void init_elements(py::module& m) py::class_(me, "Buncher") .def(py::init< amrex::ParticleReal const, - amrex::ParticleReal const>(), + amrex::ParticleReal const>(), py::arg("V"), py::arg("k"), "A short linear RF cavity element at zero-crossing for bunching." ) From f5d5c5f94bff5c2c5f157f54cbff801e0fdfa160 Mon Sep 17 00:00:00 2001 From: Chad Mitchell Date: Mon, 7 Aug 2023 12:39:02 -0700 Subject: [PATCH 06/18] Add reference particle push. --- src/particles/elements/ShortRF.H | 47 ++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/particles/elements/ShortRF.H b/src/particles/elements/ShortRF.H index 47d87298a..02d161d21 100644 --- a/src/particles/elements/ShortRF.H +++ b/src/particles/elements/ShortRF.H @@ -120,6 +120,53 @@ namespace impactx /** This pushes the reference particle. */ using Thin::operator(); + /** This pushes the reference particle. + * + * @param[in,out] refpart reference particle + */ + AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE + void operator() (RefPart & AMREX_RESTRICT refpart) const { + + using namespace amrex::literals; // for _rt and _prt + + // assign input reference particle values + amrex::ParticleReal const x = refpart.x; + amrex::ParticleReal const px = refpart.px; + amrex::ParticleReal const y = refpart.y; + amrex::ParticleReal const py = refpart.py; + amrex::ParticleReal const z = refpart.z; + amrex::ParticleReal const pz = refpart.pz; + amrex::ParticleReal const t = refpart.t; + amrex::ParticleReal const pt = refpart.pt; + + // Define parameters and intermediate constants + using ablastr::constant::math::pi; + amrex::ParticleReal const phi = m_phase*(pi/180.0_prt); + + // compute intial value of beta*gamma + amrex::ParticleReal const bgi = sqrt(pow(pt, 2) - 1.0_prt); + + // advance pt + refpart.pt = pt - m_V*cos(phi); + + // compute final value of beta*gamma + amrex::ParticleReal const ptf = refpart.pt; + amrex::ParticleReal const bgf = sqrt(pow(ptf, 2) - 1.0_prt); + + // advance position (x,y,z,t) + refpart.x = x; + refpart.y = y; + refpart.z = z; + refpart.t = t; + + // advance momentum (px,py,pz) + refpart.px = px*bgf/bgi; + refpart.py = py*bgf/bgi; + refpart.pz = pz*bgf/bgi; + + } + + private: amrex::ParticleReal m_V; //! normalized (max) RF voltage drop. amrex::ParticleReal m_freq; //! RF frequency in Hz. From d46dc45bc4a1fbc29d502ea8a61e9ee4f46aac30 Mon Sep 17 00:00:00 2001 From: Chad Mitchell Date: Mon, 7 Aug 2023 15:43:27 -0700 Subject: [PATCH 07/18] Add example. --- docs/source/usage/examples.rst | 1 + examples/CMakeLists.txt | 18 ++++ examples/compression/README.rst | 46 +++++++++ examples/compression/analysis_compression.py | 103 +++++++++++++++++++ examples/compression/input_compression.in | 42 ++++++++ examples/compression/run_compression.py | 64 ++++++++++++ 6 files changed, 274 insertions(+) create mode 100644 examples/compression/README.rst create mode 100755 examples/compression/analysis_compression.py create mode 100644 examples/compression/input_compression.in create mode 100644 examples/compression/run_compression.py diff --git a/docs/source/usage/examples.rst b/docs/source/usage/examples.rst index ba663a773..db907d6b0 100644 --- a/docs/source/usage/examples.rst +++ b/docs/source/usage/examples.rst @@ -26,6 +26,7 @@ This section allows you to **download input files** that correspond to different examples/positron_channel/README.rst examples/cyclotron/README.rst examples/cfbend/README.rst + examples/compression/README.rst Unit tests diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 0ce374398..c81b15c4e 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -583,3 +583,21 @@ add_impactx_test(cfbend.py examples/cfbend/analysis_cfbend.py OFF # no plot script yet ) + +# Ballistic compression ######################################################## +# +# w/o space charge +add_impactx_test(compression + examples/compression/input_compression.in + ON # ImpactX MPI-parallel + OFF # ImpactX Python interface + examples/compression/analysis_compression.py + OFF # no plot script yet +) +add_impactx_test(compression.py + examples/compression/run_compression.py + OFF # ImpactX MPI-parallel + ON # ImpactX Python interface + examples/compression/analysis_compression.py + OFF # no plot script yet +) diff --git a/examples/compression/README.rst b/examples/compression/README.rst new file mode 100644 index 000000000..57fc2ab97 --- /dev/null +++ b/examples/compression/README.rst @@ -0,0 +1,46 @@ +.. _examples-compression: + +Ballistic compression using a short RF element +================================================ + +A 20 MeV electron beam propagates through a short RF element +at zero-crossing, inducing a head-tail energy correlation. +This is followed by ballistic motion in a drift, which is +used to compress the bunch length by a factor of 3. + +The transverse emittance is sufficiently small that the transverse second moments are essentially unchanged. Due to RF curvature, there is some growth of the longitudinal emittance. + +In this test, the initial and final values of :math:`\sigma_x`, :math:`\sigma_y`, :math:`\sigma_t`, :math:`\epsilon_x`, :math:`\epsilon_y`, and :math:`\epsilon_t` must agree with nominal values. + + +Run +--- + +This example can be run as a Python script (``python3 run_compression.py``) or with an app with an input file (``impactx input_compression.in``). +Each can also be prefixed with an `MPI executor `__, such as ``mpiexec -n 4 ...`` or ``srun -n 4 ...``, depending on the system. + +.. tab-set:: + + .. tab-item:: Python Script + + .. literalinclude:: run_compression.py + :language: python3 + :caption: You can copy this file from ``examples/compression/run_compression.py``. + + .. tab-item:: App Input File + + .. literalinclude:: input_compression.in + :language: ini + :caption: You can copy this file from ``examples/compression/input_compression.in``. + + +Analyze +------- + +We run the following script to analyze correctness: + +.. dropdown:: Script ``analysis_compression.py`` + + .. literalinclude:: analysis_compression.py + :language: python3 + :caption: You can copy this file from ``examples/compression/analysis_compression.py``. diff --git a/examples/compression/analysis_compression.py b/examples/compression/analysis_compression.py new file mode 100755 index 000000000..16f652e34 --- /dev/null +++ b/examples/compression/analysis_compression.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 +# +# Copyright 2022-2023 ImpactX contributors +# Authors: Axel Huebl, Chad Mitchell +# License: BSD-3-Clause-LBNL +# + +import numpy as np +import openpmd_api as io +from scipy.stats import moment + + +def get_moments(beam): + """Calculate standard deviations of beam position & momenta + and emittance values + + Returns + ------- + sigx, sigy, sigt, emittance_x, emittance_y, emittance_t + """ + sigx = moment(beam["position_x"], moment=2) ** 0.5 # variance -> std dev. + sigpx = moment(beam["momentum_x"], moment=2) ** 0.5 + sigy = moment(beam["position_y"], moment=2) ** 0.5 + sigpy = moment(beam["momentum_y"], moment=2) ** 0.5 + sigt = moment(beam["position_t"], moment=2) ** 0.5 + sigpt = moment(beam["momentum_t"], moment=2) ** 0.5 + + epstrms = beam.cov(ddof=0) + emittance_x = ( + sigx**2 * sigpx**2 - epstrms["position_x"]["momentum_x"] ** 2 + ) ** 0.5 + emittance_y = ( + sigy**2 * sigpy**2 - epstrms["position_y"]["momentum_y"] ** 2 + ) ** 0.5 + emittance_t = ( + sigt**2 * sigpt**2 - epstrms["position_t"]["momentum_t"] ** 2 + ) ** 0.5 + + return (sigx, sigy, sigt, emittance_x, emittance_y, emittance_t) + + +# initial/final beam +series = io.Series("diags/openPMD/monitor.h5", io.Access.read_only) +last_step = list(series.iterations)[-1] +initial = series.iterations[1].particles["beam"].to_df() +final = series.iterations[last_step].particles["beam"].to_df() + +# compare number of particles +num_particles = 10000 +assert num_particles == len(initial) +assert num_particles == len(final) + +print("Initial Beam:") +sigx, sigy, sigt, emittance_x, emittance_y, emittance_t = get_moments(initial) +print(f" sigx={sigx:e} sigy={sigy:e} sigt={sigt:e}") +print( + f" emittance_x={emittance_x:e} emittance_y={emittance_y:e} emittance_t={emittance_t:e}" +) + +atol = 0.0 # ignored +rtol = 1.5*num_particles**-0.5 # from random sampling of a smooth distribution +print(f" rtol={rtol} (ignored: atol~={atol})") + +assert np.allclose( + [sigx, sigy, sigt, emittance_x, emittance_y, emittance_t], + [ + 5.0e-04, + 5.0e-04, + 5.0e-03, + 4.952764e-09, + 5.028325e-09, + 1.997821e-08, + ], + rtol=rtol, + atol=atol, +) + + +print("") +print("Final Beam:") +sigx, sigy, sigt, emittance_x, emittance_y, emittance_t = get_moments(final) +print(f" sigx={sigx:e} sigy={sigy:e} sigt={sigt:e}") +print( + f" emittance_x={emittance_x:e} emittance_y={emittance_y:e} emittance_t={emittance_t:e}" +) + +atol = 0.0 # ignored +rtol = 1.5*num_particles**-0.5 # from random sampling of a smooth distribution +print(f" rtol={rtol} (ignored: atol~={atol})") + +assert np.allclose( + [sigx, sigy, sigt, emittance_x, emittance_y, emittance_t], + [ + 5.005845e-04, + 5.006680e-04, + 1.444522e-03, + 4.952764e-09, + 5.028325e-09, + 7.775187e-05, + ], + rtol=rtol, + atol=atol, +) diff --git a/examples/compression/input_compression.in b/examples/compression/input_compression.in new file mode 100644 index 000000000..5add9027d --- /dev/null +++ b/examples/compression/input_compression.in @@ -0,0 +1,42 @@ +############################################################################### +# Particle Beam(s) +############################################################################### +beam.npart = 10000 +beam.units = static +beam.energy = 20.0 +beam.charge = 1.0e-9 +beam.particle = electron +beam.distribution = waterbag +beam.sigmaX = 0.5e-3 +beam.sigmaY = 0.5e-3 +beam.sigmaT = 5.0e-3 +beam.sigmaPx = 1.0e-5 +beam.sigmaPy = 1.0e-5 +beam.sigmaPt = 4.0e-6 +beam.muxpx = 0.0 +beam.muypy = 0.0 +beam.mutpt = 0.0 + + +############################################################################### +# Beamline: lattice elements and segments +############################################################################### +lattice.elements = monitor shortrf1 drift1 monitor + +monitor.type = beam_monitor +monitor.backend = h5 + +shortrf1.type = shortrf +shortrf1.V = 1000.0 +shortrf1.freq = 1.3e9 +shortrf1.phase = -90.0 + +drift1.type = drift +drift1.ds = 1.7 + + +############################################################################### +# Algorithms +############################################################################### +algo.particle_shape = 2 +algo.space_charge = false diff --git a/examples/compression/run_compression.py b/examples/compression/run_compression.py new file mode 100644 index 000000000..0f8dfa535 --- /dev/null +++ b/examples/compression/run_compression.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +# +# Copyright 2022-2023 ImpactX contributors +# Authors: Marco Garten, Axel Huebl, Chad Mitchell +# License: BSD-3-Clause-LBNL +# +# -*- coding: utf-8 -*- + +import amrex.space3d as amr +from impactx import ImpactX, distribution, elements + +sim = ImpactX() + +# set numerical parameters and IO control +sim.particle_shape = 2 # B-spline order +sim.space_charge = False +# sim.diagnostics = False # benchmarking +sim.slice_step_diagnostics = True + +# domain decomposition & space charge mesh +sim.init_grids() + +# load a 250 MeV proton beam with an initial +# unnormalized rms emittance of 1 mm-mrad in all +# three phase planes +energy_MeV = 20.0 # reference energy +bunch_charge_C = 1.0e-9 # used with space charge +npart = 10000 # number of macro particles + +# reference particle +ref = sim.particle_container().ref_particle() +ref.set_charge_qe(-1.0).set_mass_MeV(0.510998950).set_energy_MeV(energy_MeV) + +# particle bunch +distr = distribution.Waterbag( + sigmaX=0.5e-3, + sigmaY=0.5e-3, + sigmaT=5.0e-3, + sigmaPx=1.0e-5, + sigmaPy=1.0e-5, + sigmaPt=4.0e-6, +) +sim.add_particles(bunch_charge_C, distr, npart) + +# add beam diagnostics +monitor = elements.BeamMonitor("monitor", backend="h5") + +# design the accelerator lattice +sim.lattice.append(monitor) +# Short RF cavity element +shortrf1 = elements.ShortRF(V=1000.0, freq=1.3e9, phase=-90.0) +# Drift element +drift1 = elements.Drift(ds=1.7) + +sim.lattice.extend([shortrf1, drift1]) + +sim.lattice.append(monitor) + +# run simulation +sim.evolve() + +# clean shutdown +del sim +amr.finalize() From afa58ad70230d50b816061f749bad1cbb16a22ff Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 7 Aug 2023 22:45:34 +0000 Subject: [PATCH 08/18] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- examples/CMakeLists.txt | 2 +- examples/compression/analysis_compression.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index c81b15c4e..9eef8a647 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -588,7 +588,7 @@ add_impactx_test(cfbend.py # # w/o space charge add_impactx_test(compression - examples/compression/input_compression.in + examples/compression/input_compression.in ON # ImpactX MPI-parallel OFF # ImpactX Python interface examples/compression/analysis_compression.py diff --git a/examples/compression/analysis_compression.py b/examples/compression/analysis_compression.py index 16f652e34..5587a10e8 100755 --- a/examples/compression/analysis_compression.py +++ b/examples/compression/analysis_compression.py @@ -58,7 +58,7 @@ def get_moments(beam): ) atol = 0.0 # ignored -rtol = 1.5*num_particles**-0.5 # from random sampling of a smooth distribution +rtol = 1.5 * num_particles**-0.5 # from random sampling of a smooth distribution print(f" rtol={rtol} (ignored: atol~={atol})") assert np.allclose( @@ -85,7 +85,7 @@ def get_moments(beam): ) atol = 0.0 # ignored -rtol = 1.5*num_particles**-0.5 # from random sampling of a smooth distribution +rtol = 1.5 * num_particles**-0.5 # from random sampling of a smooth distribution print(f" rtol={rtol} (ignored: atol~={atol})") assert np.allclose( From b8ef133a63fb91d982cac4c5246f47af3dca5418 Mon Sep 17 00:00:00 2001 From: Chad Mitchell Date: Mon, 7 Aug 2023 15:56:11 -0700 Subject: [PATCH 09/18] Add documentation. --- docs/source/usage/parameters.rst | 19 ++++++++++++++++++- docs/source/usage/python.rst | 12 ++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/docs/source/usage/parameters.rst b/docs/source/usage/parameters.rst index 123488f6d..4ad9e14fd 100644 --- a/docs/source/usage/parameters.rst +++ b/docs/source/usage/parameters.rst @@ -409,7 +409,7 @@ Lattice Elements * ``.nslice`` (``integer``) number of slices used for the application of space charge (default: ``1``) - * ``shortrf`` for a short RF (bunching) cavity element. + * ``buncher`` for a short RF cavity (linear) bunching element. This requires these additional parameters: * ``.V`` (``float``, dimensionless) normalized voltage drop across the cavity @@ -420,6 +420,23 @@ Lattice Elements = 2*pi/(RF wavelength in m) + * ``shortrf`` for a short RF cavity element. + This requires these additional parameters: + + * ``.V`` (``float``, dimensionless) normalized voltage drop across the cavity + + = (maximum energy gain in MeV) / (particle rest energy in MeV) + + * ``.freq`` (``float``, in Hz) the RF frequency + + * ``.phase`` (``float``, in degrees) the synchronous RF phase + + phase = 0: maximum energy gain (on-crest) + + phase = -90 deg: zero energy gain for bunching + + phase = 90 deg: zero energy gain for debunching + * ``uniform_acc_chromatic`` for a region of uniform acceleration, with chromatic effects included. The Hamiltonian is expanded through second order in the transverse variables (x,px,y,py), with the exact pt dependence retained. This requires these additional parameters: diff --git a/docs/source/usage/python.rst b/docs/source/usage/python.rst index e85fcbd72..1b746c481 100644 --- a/docs/source/usage/python.rst +++ b/docs/source/usage/python.rst @@ -602,13 +602,21 @@ References: :param B: Magnetic field in Tesla; when B = 0 (default), the reference bending radius is defined by r0 = length / (angle in rad), corresponding to a magnetic field of B = rigidity / r0; otherwise the reference bending radius is defined by r0 = rigidity / B. :param nslice: number of slices used for the application of space charge -.. py:class:: impactx.elements.ShortRF(V, k) +.. py:class:: impactx.elements.Buncher(V, k) - A short RF cavity element at zero crossing for bunching. + A short RF cavity element at zero crossing for bunching (MaryLie model). :param V: Normalized RF voltage drop V = Emax*L/(c*Brho) :param k: Wavenumber of RF in 1/m +.. py:class:: impactx.elements.ShortRF(V, freq, phase) + + A short RF cavity element (MAD-X model). + + :param V: Normalized RF voltage V = maximum energy gain/(m*c^2) + :param freq: RF frequency in Hz + :param phase: RF synchronous phase in degrees (phase = 0 corresponds to maximum energy gain, phase = -90 corresponds go zero energy gain for bunching) + .. py:class:: impactx.elements.ChrUniformAcc(ds, k, nslice=1) A region of constant Ez and Bz for uniform acceleration, with chromatic effects included. From 9fa8c75605fcf477343a65dde47f54419375b3bb Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 7 Aug 2023 22:56:59 +0000 Subject: [PATCH 10/18] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- docs/source/usage/python.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/usage/python.rst b/docs/source/usage/python.rst index 1b746c481..51efa6c61 100644 --- a/docs/source/usage/python.rst +++ b/docs/source/usage/python.rst @@ -611,8 +611,8 @@ References: .. py:class:: impactx.elements.ShortRF(V, freq, phase) - A short RF cavity element (MAD-X model). - + A short RF cavity element (MAD-X model). + :param V: Normalized RF voltage V = maximum energy gain/(m*c^2) :param freq: RF frequency in Hz :param phase: RF synchronous phase in degrees (phase = 0 corresponds to maximum energy gain, phase = -90 corresponds go zero energy gain for bunching) From c3ebe44e95e3f431d21ee93a8c448eb2e1b4f09a Mon Sep 17 00:00:00 2001 From: Axel Huebl Date: Tue, 8 Aug 2023 13:44:42 -0700 Subject: [PATCH 11/18] Compression README: Minor Formatting --- examples/compression/README.rst | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/examples/compression/README.rst b/examples/compression/README.rst index 57fc2ab97..49ef7c39c 100644 --- a/examples/compression/README.rst +++ b/examples/compression/README.rst @@ -1,12 +1,10 @@ .. _examples-compression: -Ballistic compression using a short RF element -================================================ +Ballistic Compression Using a Short RF Element +============================================== -A 20 MeV electron beam propagates through a short RF element -at zero-crossing, inducing a head-tail energy correlation. -This is followed by ballistic motion in a drift, which is -used to compress the bunch length by a factor of 3. +A 20 MeV electron beam propagates through a short RF element at zero-crossing, inducing a head-tail energy correlation. +This is followed by ballistic motion in a drift, which is used to compress the bunch length by a factor of 3. The transverse emittance is sufficiently small that the transverse second moments are essentially unchanged. Due to RF curvature, there is some growth of the longitudinal emittance. From 5b3120227738f7ce0b09cbe7d5b2088d55b8a70b Mon Sep 17 00:00:00 2001 From: Axel Huebl Date: Tue, 8 Aug 2023 13:51:59 -0700 Subject: [PATCH 12/18] Compression Analysis: Add Gamma Ref Template --- examples/compression/analysis_compression.py | 22 ++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/examples/compression/analysis_compression.py b/examples/compression/analysis_compression.py index 5587a10e8..123bce1ea 100755 --- a/examples/compression/analysis_compression.py +++ b/examples/compression/analysis_compression.py @@ -39,11 +39,21 @@ def get_moments(beam): return (sigx, sigy, sigt, emittance_x, emittance_y, emittance_t) -# initial/final beam +# openPMD data series at the beam monitors series = io.Series("diags/openPMD/monitor.h5", io.Access.read_only) -last_step = list(series.iterations)[-1] -initial = series.iterations[1].particles["beam"].to_df() -final = series.iterations[last_step].particles["beam"].to_df() + +# first and last step +final_step = list(series.iterations)[-1] +first_it = series.iterations[1] +final_it = series.iterations[final_step] + +# initial beam & reference particle gamma +initial = first_it.particles["beam"].to_df() +initial_gamma_ref = first_it.particles["beam"].get_attribute("gamma_ref") + +# final beam & reference particle gamma +final = final_it.particles["beam"].to_df() +final_gamma_ref = final_it.particles["beam"].get_attribute("gamma_ref") # compare number of particles num_particles = 10000 @@ -75,6 +85,8 @@ def get_moments(beam): atol=atol, ) +# TODO assert initial_gamma_ref + print("") print("Final Beam:") @@ -101,3 +113,5 @@ def get_moments(beam): rtol=rtol, atol=atol, ) + +# TODO assert final_gamma_ref \ No newline at end of file From d910299d75d6c159160862511977ecb1bdf467c4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 8 Aug 2023 21:01:57 +0000 Subject: [PATCH 13/18] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- examples/compression/analysis_compression.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/compression/analysis_compression.py b/examples/compression/analysis_compression.py index 123bce1ea..45c44b4b4 100755 --- a/examples/compression/analysis_compression.py +++ b/examples/compression/analysis_compression.py @@ -114,4 +114,4 @@ def get_moments(beam): atol=atol, ) -# TODO assert final_gamma_ref \ No newline at end of file +# TODO assert final_gamma_ref From bb8be12eb02febe2d7015ba4542e58f267bda81a Mon Sep 17 00:00:00 2001 From: Chad Mitchell Date: Tue, 8 Aug 2023 16:07:33 -0700 Subject: [PATCH 14/18] Modified the example to include a small acceleration. --- examples/compression/README.rst | 8 +++++--- examples/compression/input_compression.in | 2 +- examples/compression/run_compression.py | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/examples/compression/README.rst b/examples/compression/README.rst index 49ef7c39c..207fcbe8c 100644 --- a/examples/compression/README.rst +++ b/examples/compression/README.rst @@ -3,10 +3,12 @@ Ballistic Compression Using a Short RF Element ============================================== -A 20 MeV electron beam propagates through a short RF element at zero-crossing, inducing a head-tail energy correlation. -This is followed by ballistic motion in a drift, which is used to compress the bunch length by a factor of 3. +A 20 MeV electron beam propagates through a short RF element near zero-crossing, inducing a head-tail energy correlation. +This is followed by ballistic motion in a drift, which is used to compress the rms bunch length from 16 ps to 10 ps (compression of 5/3). -The transverse emittance is sufficiently small that the transverse second moments are essentially unchanged. Due to RF curvature, there is some growth of the longitudinal emittance. +The beam is not exactly on-crest (phase = -89.5 deg), so there is an energy gain of 4.5 MeV. + +The transverse emittance is sufficiently small that the horizontal and verticle beam size are essentially unchanged. Due to RF curvature, there is some growth of the longitudinal emittance. In this test, the initial and final values of :math:`\sigma_x`, :math:`\sigma_y`, :math:`\sigma_t`, :math:`\epsilon_x`, :math:`\epsilon_y`, and :math:`\epsilon_t` must agree with nominal values. diff --git a/examples/compression/input_compression.in b/examples/compression/input_compression.in index 5add9027d..cc2315059 100644 --- a/examples/compression/input_compression.in +++ b/examples/compression/input_compression.in @@ -29,7 +29,7 @@ monitor.backend = h5 shortrf1.type = shortrf shortrf1.V = 1000.0 shortrf1.freq = 1.3e9 -shortrf1.phase = -90.0 +shortrf1.phase = -89.5 drift1.type = drift drift1.ds = 1.7 diff --git a/examples/compression/run_compression.py b/examples/compression/run_compression.py index 0f8dfa535..3fd36ecb9 100644 --- a/examples/compression/run_compression.py +++ b/examples/compression/run_compression.py @@ -48,7 +48,7 @@ # design the accelerator lattice sim.lattice.append(monitor) # Short RF cavity element -shortrf1 = elements.ShortRF(V=1000.0, freq=1.3e9, phase=-90.0) +shortrf1 = elements.ShortRF(V=1000.0, freq=1.3e9, phase=-89.5) # Drift element drift1 = elements.Drift(ds=1.7) From d3e8c950b09522f2cbb07866efb1e64bc7c0d20f Mon Sep 17 00:00:00 2001 From: Chad Mitchell Date: Tue, 8 Aug 2023 16:11:11 -0700 Subject: [PATCH 15/18] Update analysis script. --- examples/compression/analysis_compression.py | 22 ++++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/examples/compression/analysis_compression.py b/examples/compression/analysis_compression.py index 45c44b4b4..2eded2cd2 100755 --- a/examples/compression/analysis_compression.py +++ b/examples/compression/analysis_compression.py @@ -66,13 +66,14 @@ def get_moments(beam): print( f" emittance_x={emittance_x:e} emittance_y={emittance_y:e} emittance_t={emittance_t:e}" ) +print(f" gamma={initial_gamma_ref:e}") atol = 0.0 # ignored rtol = 1.5 * num_particles**-0.5 # from random sampling of a smooth distribution print(f" rtol={rtol} (ignored: atol~={atol})") assert np.allclose( - [sigx, sigy, sigt, emittance_x, emittance_y, emittance_t], + [sigx, sigy, sigt, emittance_x, emittance_y, emittance_t, initial_gamma_ref], [ 5.0e-04, 5.0e-04, @@ -80,6 +81,7 @@ def get_moments(beam): 4.952764e-09, 5.028325e-09, 1.997821e-08, + 40.1389432485322889, ], rtol=rtol, atol=atol, @@ -95,23 +97,25 @@ def get_moments(beam): print( f" emittance_x={emittance_x:e} emittance_y={emittance_y:e} emittance_t={emittance_t:e}" ) +print(f" gamma={final_gamma_ref:e}") + atol = 0.0 # ignored rtol = 1.5 * num_particles**-0.5 # from random sampling of a smooth distribution print(f" rtol={rtol} (ignored: atol~={atol})") assert np.allclose( - [sigx, sigy, sigt, emittance_x, emittance_y, emittance_t], + [sigx, sigy, sigt, emittance_x, emittance_y, emittance_t, final_gamma_ref], [ - 5.005845e-04, - 5.006680e-04, - 1.444522e-03, - 4.952764e-09, - 5.028325e-09, - 7.775187e-05, + 5.004995e-04, + 5.005865e-04, + 3.033949e-03, + 4.067876e-09, + 4.129937e-09, + 6.432081e-05, + 48.8654787469061860, ], rtol=rtol, atol=atol, ) -# TODO assert final_gamma_ref From ee8d6902c12d8f774b9423b790021bbc760f210c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 8 Aug 2023 23:11:38 +0000 Subject: [PATCH 16/18] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- examples/compression/analysis_compression.py | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/compression/analysis_compression.py b/examples/compression/analysis_compression.py index 2eded2cd2..d2d16176c 100755 --- a/examples/compression/analysis_compression.py +++ b/examples/compression/analysis_compression.py @@ -118,4 +118,3 @@ def get_moments(beam): rtol=rtol, atol=atol, ) - From 5ca7c94c2a4ab974db0366322051badb7eba2094 Mon Sep 17 00:00:00 2001 From: Chad Mitchell <46825199+cemitch99@users.noreply.github.com> Date: Tue, 8 Aug 2023 16:59:13 -0700 Subject: [PATCH 17/18] Update analysis_compression.py Relax tolerance. --- examples/compression/analysis_compression.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/compression/analysis_compression.py b/examples/compression/analysis_compression.py index d2d16176c..6c4e929fc 100755 --- a/examples/compression/analysis_compression.py +++ b/examples/compression/analysis_compression.py @@ -69,7 +69,7 @@ def get_moments(beam): print(f" gamma={initial_gamma_ref:e}") atol = 0.0 # ignored -rtol = 1.5 * num_particles**-0.5 # from random sampling of a smooth distribution +rtol = 1.8 * num_particles**-0.5 # from random sampling of a smooth distribution print(f" rtol={rtol} (ignored: atol~={atol})") assert np.allclose( @@ -101,7 +101,7 @@ def get_moments(beam): atol = 0.0 # ignored -rtol = 1.5 * num_particles**-0.5 # from random sampling of a smooth distribution +rtol = 1.8 * num_particles**-0.5 # from random sampling of a smooth distribution print(f" rtol={rtol} (ignored: atol~={atol})") assert np.allclose( From b9016750fa14bee616ce85c84b3f9df0fec835ff Mon Sep 17 00:00:00 2001 From: Axel Huebl Date: Tue, 8 Aug 2023 23:10:16 -0700 Subject: [PATCH 18/18] Cleanup --- examples/compression/analysis_compression.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/compression/analysis_compression.py b/examples/compression/analysis_compression.py index 6c4e929fc..775e1a903 100755 --- a/examples/compression/analysis_compression.py +++ b/examples/compression/analysis_compression.py @@ -87,8 +87,6 @@ def get_moments(beam): atol=atol, ) -# TODO assert initial_gamma_ref - print("") print("Final Beam:")