Skip to content

Commit

Permalink
Added operator to push reference particle in global coordinates to al…
Browse files Browse the repository at this point in the history
…l elements (#149)

* Added math to push the reference particle in global coordinates to all
existing elements.

* Elements: Pass by Reference
  * Pass the reference particle by reference, so we can manipulate it
    in elements.
  * Remove true "no-op" implementations with a comment.
  * Add Doxygen comments.

* Push the Reference Particle

Co-authored-by: Axel Huebl <[email protected]>
  • Loading branch information
cemitch99 and ax3l authored Jun 27, 2022
1 parent 1421304 commit d2476c8
Show file tree
Hide file tree
Showing 11 changed files with 188 additions and 10 deletions.
4 changes: 2 additions & 2 deletions src/particles/ImpactXParticleContainer.H
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,8 @@ namespace impactx
*
* @returns refpart
*/
RefPart
GetRefParticle () const;
RefPart &
GetRefParticle ();

/** Get particle shape
*/
Expand Down
4 changes: 2 additions & 2 deletions src/particles/ImpactXParticleContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ namespace impactx
m_refpart = refpart;
}

RefPart
ImpactXParticleContainer::GetRefParticle () const
RefPart &
ImpactXParticleContainer::GetRefParticle ()
{
return m_refpart;
}
Expand Down
12 changes: 7 additions & 5 deletions src/particles/Push.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,18 +126,20 @@ namespace detail
// ...

// preparing to access reference particle data: RefPart
RefPart ref_part;
ref_part = pc.GetRefParticle();
RefPart & ref_part = pc.GetRefParticle();

// loop over all beamline elements
for (auto & element_variant : lattice) {
// here we just access the element by its respective type
std::visit([=](auto&& element) {
std::visit([=, &ref_part](auto&& element) {
// push beam particles relative to reference particle
detail::PushSingleParticle<decltype(element)> const pushSingleParticle(
element, aos_ptr, part_px, part_py, part_pt, ref_part);

// loop over particles in the box
// loop over beam particles in the box
amrex::ParallelFor(np, pushSingleParticle);

// push reference particle in global coordinates
element(ref_part);
}, element_variant);
}; // end loop over all beamline elements
} // end loop over all particle boxes
Expand Down
31 changes: 31 additions & 0 deletions src/particles/elements/ConstF.H
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,37 @@ namespace impactx

}

/** 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;

// assign intermediate parameter
amrex::ParticleReal const s = m_ds/sqrt(pow(pt,2)-1.0_prt);

// advance position and momentum (straight element)
refpart.x = x + s*px;
refpart.y = y + s*py;
refpart.z = z + s*pz;
refpart.t = t - s*pt;

}

private:
amrex::ParticleReal m_ds; //! segment length in m
amrex::ParticleReal m_kx; //! focusing x strength in 1/m
Expand Down
11 changes: 11 additions & 0 deletions src/particles/elements/DipEdge.H
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,17 @@ namespace impactx
py = py + R43*y;
}

/** This pushes the reference particle.
*
* @param[in,out] refpart reference particle
*/
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
void operator() (
[[maybe_unused]] RefPart & AMREX_RESTRICT refpart) const {

// nothing to do: this is a zero-length element
}

private:
amrex::ParticleReal m_psi; //! pole face angle in rad
amrex::ParticleReal m_rc; //! bend radius in m
Expand Down
34 changes: 33 additions & 1 deletion src/particles/elements/Drift.H
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ namespace impactx
amrex::ParticleReal const y = p.pos(1);
amrex::ParticleReal const t = p.pos(2);

// intialize output values of momenta
// initialize output values of momenta
amrex::ParticleReal pxout = px;
amrex::ParticleReal pyout = py;
amrex::ParticleReal ptout = pt;
Expand All @@ -77,6 +77,38 @@ namespace impactx
px = pxout;
py = pyout;
pt = ptout;

}

/** 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;

// assign intermediate parameter
amrex::ParticleReal const s = m_ds/sqrt(pow(pt,2)-1.0_prt);

// advance position and momentum (drift)
refpart.x = x + s*px;
refpart.y = y + s*py;
refpart.z = z + s*pz;
refpart.t = t - s*pt;

}

private:
Expand Down
11 changes: 11 additions & 0 deletions src/particles/elements/Multipole.H
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,17 @@ namespace impactx

}

/** This pushes the reference particle.
*
* @param[in,out] refpart reference particle
*/
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
void operator() (
[[maybe_unused]] RefPart & AMREX_RESTRICT refpart) const {

// nothing to do: this is a zero-length element
}

private:
int m_multipole; //! multipole index
int m_mfactorial; //! factorial of multipole index
Expand Down
11 changes: 11 additions & 0 deletions src/particles/elements/NonlinearLens.H
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,17 @@ namespace impactx

}

/** This pushes the reference particle.
*
* @param[in,out] refpart reference particle
*/
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
void operator() (
[[maybe_unused]] RefPart & AMREX_RESTRICT refpart) const {

// nothing to do: this is a zero-length element
}

private:
amrex::ParticleReal m_knll; //! integrated strength of the nonlinear lens (m)
amrex::ParticleReal m_cnll; //! distance of singularities from the origin (m)
Expand Down
31 changes: 31 additions & 0 deletions src/particles/elements/Quad.H
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,37 @@ namespace impactx

}

/** 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;

// assign intermediate parameter
amrex::ParticleReal const s = m_ds/sqrt(pow(pt,2)-1.0_prt);

// advance position and momentum (straight element)
refpart.x = x + s*px;
refpart.y = y + s*py;
refpart.z = z + s*pz;
refpart.t = t - s*pt;

}

private:
amrex::ParticleReal m_ds; //! segment length in m
amrex::ParticleReal m_k; //! quadrupole strength in 1/m
Expand Down
37 changes: 37 additions & 0 deletions src/particles/elements/Sbend.H
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,43 @@ namespace impactx

}

/** 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;

// assign intermediate parameter
amrex::ParticleReal const theta = m_ds/m_rc;
amrex::ParticleReal const B = sqrt(pow(pt,2)-1.0_prt)/m_rc;

// advance position and momentum (bend)
refpart.px = px*cos(theta) - pz*sin(theta);
refpart.py = py;
refpart.pz = pz*cos(theta) + px*sin(theta);
refpart.pt = pt;

refpart.x = x + (refpart.pz - pz)/B;
refpart.y = y + (theta/B)*py;
refpart.z = z - (refpart.px - px)/B;
refpart.t = t - (theta/B)*pt;

}

private:
amrex::ParticleReal m_ds; //! segment length in m
amrex::ParticleReal m_rc; //! bend radius in m
Expand Down
12 changes: 12 additions & 0 deletions src/particles/elements/ShortRF.H
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,18 @@ namespace impactx

}

/** This pushes the reference particle.
*
* @param[in,out] refpart reference particle
*/
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
void operator() (
[[maybe_unused]] RefPart & AMREX_RESTRICT refpart) const {

// nothing to do: this is a zero-length element

}

private:
amrex::ParticleReal m_V; //! normalized (max) RF voltage drop.
amrex::ParticleReal m_k; //! RF wavenumber in 1/m.
Expand Down

0 comments on commit d2476c8

Please sign in to comment.