Skip to content

Commit 2eb9384

Browse files
committed
Make Buncher fast
1 parent 3ccf3fd commit 2eb9384

File tree

1 file changed

+40
-17
lines changed

1 file changed

+40
-17
lines changed

src/elements/Buncher.H

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -64,47 +64,65 @@ namespace impactx::elements
6464
/** Push all particles */
6565
using BeamOptic::operator();
6666

67+
/** Compute and cache the constants for the push.
68+
*
69+
* In particular, used to pre-compute and cache variables that are
70+
* independent of the individually tracked particle.
71+
*
72+
* @param refpart reference particle
73+
*/
74+
void compute_constants (RefPart const & refpart)
75+
{
76+
using namespace amrex::literals; // for _rt and _prt
77+
78+
Alignment::compute_constants(refpart);
79+
80+
// find beta*gamma^2
81+
amrex::ParticleReal const betgam2 = 2.0_prt * std::pow(refpart.pt, 2) - 1.0_prt;
82+
83+
m_kV_r2bg2 = m_k * m_V / (2.0_prt * betgam2);
84+
}
85+
6786
/** This is a buncher functor, so that a variable of this type can be used like a
6887
* buncher function.
6988
*
89+
* The @see compute_constants method must be called before pushing particles through this operator.
90+
*
7091
* @param x particle position in x
7192
* @param y particle position in y
7293
* @param t particle position in t
7394
* @param px particle momentum in x
7495
* @param py particle momentum in y
7596
* @param pt particle momentum in t
7697
* @param idcpu particle global index (unused)
77-
* @param refpart reference particle
98+
* @param refpart reference particle (unused)
7899
*/
79100
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
80101
void operator() (
81-
amrex::ParticleReal & AMREX_RESTRICT x,
82-
amrex::ParticleReal & AMREX_RESTRICT y,
83-
amrex::ParticleReal & AMREX_RESTRICT t,
84-
amrex::ParticleReal & AMREX_RESTRICT px,
85-
amrex::ParticleReal & AMREX_RESTRICT py,
86-
amrex::ParticleReal & AMREX_RESTRICT pt,
87-
[[maybe_unused]] uint64_t & AMREX_RESTRICT idcpu,
88-
RefPart const & refpart) const {
89-
102+
amrex::ParticleReal & AMREX_RESTRICT x,
103+
amrex::ParticleReal & AMREX_RESTRICT y,
104+
amrex::ParticleReal & AMREX_RESTRICT t,
105+
amrex::ParticleReal & AMREX_RESTRICT px,
106+
amrex::ParticleReal & AMREX_RESTRICT py,
107+
amrex::ParticleReal & AMREX_RESTRICT pt,
108+
[[maybe_unused]] uint64_t & AMREX_RESTRICT idcpu,
109+
[[maybe_unused]] RefPart const & AMREX_RESTRICT refpart
110+
) const
111+
{
90112
using namespace amrex::literals; // for _rt and _prt
91113

92114
// shift due to alignment errors of the element
93115
shift_in(x, y, px, py);
94116

95-
// access reference particle values to find (beta*gamma)^2
96-
amrex::ParticleReal const pt_ref = refpart.pt;
97-
amrex::ParticleReal const betgam2 = std::pow(pt_ref, 2) - 1.0_prt;
98-
99117
// intialize output values of momenta
100118
amrex::ParticleReal pxout = px;
101119
amrex::ParticleReal pyout = py;
102120
amrex::ParticleReal ptout = pt;
103121

104122
// advance position and momentum
105-
pxout = px + m_k*m_V/(2.0_prt*betgam2)*x;
106-
pyout = py + m_k*m_V/(2.0_prt*betgam2)*y;
107-
ptout = pt - m_k*m_V*t;
123+
pxout = px + m_kV_r2bg2 * x;
124+
pyout = py + m_kV_r2bg2 * y;
125+
ptout = pt - m_k * m_V * t;
108126

109127
// assign updated momenta
110128
px = pxout;
@@ -136,6 +154,11 @@ namespace impactx::elements
136154

137155
amrex::ParticleReal m_V; //! normalized (max) RF voltage drop.
138156
amrex::ParticleReal m_k; //! RF wavenumber in 1/m.
157+
158+
private:
159+
// constants that are independent of the individually tracked particle,
160+
// see: compute_constants() to refresh
161+
amrex::ParticleReal m_kV_r2bg2; //! m_k*m_V/(2.0_prt*betgam2)
139162
};
140163

141164
} // namespace impactx

0 commit comments

Comments
 (0)