Particles and Phase Space Points

There are three layers of abstraction from particles to phase space points in the QEDjl project:

This manual is intended to showcase the basic usage of these types and their implementations in QEDcore.

using QEDcore

To use concrete process definitions and models, we also need to use QEDprocesses.jl

using QEDprocesses

Particle Types

QEDcore currently defines the three basic particle types of QED, Electron, Positron, and Photon, and a type hierarchy for them:

@assert Photon <: MajoranaBoson
@assert Electron <: Fermion
@assert Positron <: AntiFermion

All of these are subtypes of QEDbase.AbstractParticleType. There are also convenience functions in Julia convention:

@assert is_boson(Photon())
@assert is_particle(Electron())
@assert is_anti_particle(Positron())

@assert !is_boson(Electron())
@assert !is_anti_particle(Electron())
@assert !is_fermion(Photon())

These functions are part of QEDbase.jl's particle interface.

ParticleStateful

ParticleStateful is the implementation of QEDbase's QEDbase.AbstractParticleStateful interface. It represents a particle with a direction (as used in the context of scattering processes, QEDbase.Incoming, QEDbase.Outgoing, or QEDbase.UnknownDirection), a particle species (Electron, Positron, Photon, ...), and a 4-momentum vector.

ps = ParticleStateful(Incoming(), Electron(), rand(SFourMomentum))
ParticleStateful: incoming electron
    momentum: [0.9275039500555082, 0.6182887742371763, 0.021672833546936943, 0.03828965907821291]

The relevant accessor functions for the interface are implemented:

particle_direction(ps)
incoming
particle_species(ps)
electron
momentum(ps)
4-element SFourMomentum with indices SOneTo(4):
 0.9275039500555082
 0.6182887742371763
 0.021672833546936943
 0.03828965907821291

Phase Space Points

A PhaseSpacePoint is the combination of incoming and outgoing ParticleStatefuls. It also contains information about the scattering process, model, and phase space that it is created for.

Constructors

psp = PhaseSpacePoint(
    Compton(),                      # scattering process
    PerturbativeQED(),              # physics model
    PhasespaceDefinition(           # phase space definition
        SphericalCoordinateSystem(),# coordinate system
        ElectronRestFrame(),        # frame of reference
    ),
    (   # momenta of the incoming particles
        rand(SFourMomentum),
        rand(SFourMomentum),
    ),
    (   # momenta of the outgoing particles
        rand(SFourMomentum),
        rand(SFourMomentum),
    ),
)
PhaseSpacePoint:
    process: one-photon Compton scattering
    model: perturbative QED
    phasespace definition: spherical coordinates in electron rest frame
    incoming particles:
     -> incoming electron: [0.5337235656982577, 0.4889202477657373, 0.8065858311215568, 0.905199795355832]
     -> incoming photon: [0.14093588148891834, 0.6889516169020181, 0.030474597161012862, 0.9382112394018999]
    outgoing particles:
     -> outgoing electron: [0.893626166860406, 0.6269760273653339, 0.7339438532604702, 0.3493995676798878]
     -> outgoing photon: [0.4881844659143383, 0.37870637253600714, 0.14886991729085197, 0.5523888575348856]

This version of the constructor automatically creates ParticleStateful obejcts from the momenta, matching the particles of the process. In the case of Compton, this is means an incoming electron and photon, and outgoing electron and photon.

Automatic checks make sure that the number of 4-momenta given matches the necessary number of 4-momenta for the process (this adds 0 overhead at runtime because it is inferred from type information alone).

    PhaseSpacePoint(
        Compton(),
        PerturbativeQED(),
        PhasespaceDefinition(SphericalCoordinateSystem(), ElectronRestFrame()),
        (rand(SFourMomentum),), # incorrect number of incoming momenta, should be 2
        (rand(SFourMomentum), rand(SFourMomentum)),
    )
┌ Error: InvalidInputError("expected 2 incoming particles for the process but got 1")
└ @ Main particles.md:115

Alternatively, a PhaseSpacePoint can also be constructed from already existing ParticleStateful objects.

psp = PhaseSpacePoint(
    Compton(),                      # scattering process
    PerturbativeQED(),              # physics model
    PhasespaceDefinition(           # phase space definition
        SphericalCoordinateSystem(),# coordinate system
        ElectronRestFrame(),        # frame of reference
    ),
    (   # incoming particles
        ParticleStateful(Incoming(), Electron(), rand(SFourMomentum)),
        ParticleStateful(Incoming(), Photon(), rand(SFourMomentum)),
    ),
    (   # outgoing particles
        ParticleStateful(Outgoing(), Electron(), rand(SFourMomentum)),
        ParticleStateful(Outgoing(), Photon(), rand(SFourMomentum)),
    ),
)
PhaseSpacePoint:
    process: one-photon Compton scattering
    model: perturbative QED
    phasespace definition: spherical coordinates in electron rest frame
    incoming particles:
     -> incoming electron: [0.6225426040804004, 0.32534780478179337, 0.6931224440881611, 0.1527136171639749]
     -> incoming photon: [0.14912910089674625, 0.6858849294523561, 0.34301645654588053, 0.7964362261605737]
    outgoing particles:
     -> outgoing electron: [0.1264935386170699, 0.3091575852016043, 0.637517264982275, 0.9951181745626174]
     -> outgoing photon: [0.02935369236825358, 0.00852918710766759, 0.7879010397848306, 0.9449353022431461]

Similar to the constructor from momenta, this checks that the given ParticleStatefuls fit to the given process and throws otherwise. Again, since this can be infered from type information alone, it adds no overhead.

    PhaseSpacePoint(
        Compton(),
        PerturbativeQED(),
        PhasespaceDefinition(SphericalCoordinateSystem(), ElectronRestFrame()),
        (   # incoming particles
            ParticleStateful(Incoming(), Positron(), rand(SFourMomentum)), # incorrect particle type
            ParticleStateful(Incoming(), Photon(), rand(SFourMomentum)),
        ),
        (   # outgoing particles
            ParticleStateful(Outgoing(), Electron(), rand(SFourMomentum)),
            ParticleStateful(Outgoing(), Photon(), rand(SFourMomentum)),
        ),
    )
┌ Error: InvalidInputError("expected incoming electron but got incoming positron")
└ @ Main particles.md:162
Note

While these constructors check that the given types make sense and work together, they do not check whether the given momenta make a physical phase space point or that the incoming or outgoing particles have on-shell 4-momenta.

Accessors

The phase space point provides some convenient accessors to the stateful particles within:

psp[Incoming(), 1]  # the first incoming particle
ParticleStateful: incoming electron
    momentum: [0.6225426040804004, 0.32534780478179337, 0.6931224440881611, 0.1527136171639749]
psp[Outgoing(), 2]  # the second outgoing particle
ParticleStateful: outgoing photon
    momentum: [0.02935369236825358, 0.00852918710766759, 0.7879010397848306, 0.9449353022431461]
particles(psp, Incoming()) # all incoming particles as a tuple
(incoming electron: [0.6225426040804004, 0.32534780478179337, 0.6931224440881611, 0.1527136171639749], incoming photon: [0.14912910089674625, 0.6858849294523561, 0.34301645654588053, 0.7964362261605737])

Momentum accessors:

momentum(psp, Incoming(), Electron(), 1) # the momentum of the first incoming electron
4-element SFourMomentum with indices SOneTo(4):
 0.6225426040804004
 0.32534780478179337
 0.6931224440881611
 0.1527136171639749

When only one particle of the species exists in the particle set, the 1 can be ommitted for convenience.

@assert ans == momentum(psp, Incoming(), Electron())
Note

This method throws when multiple (or zero) particles of the given direction and species exist in the phase space point.

When the index of the required momentum is known at compile time, a Val(N) can be used instead of N. This performs bounds checks at compile time and removes loops from the runtime execution

using BenchmarkTools
judge(
    median(@benchmark momentum($psp, Incoming(), Photon(), Val(1))),
    median(@benchmark momentum($psp, Incoming(), Photon(), 1)),
)
BenchmarkTools.TrialJudgement: 
  time:   -89.80% => improvement (5.00% tolerance)
  memory: -100.00% => improvement (1.00% tolerance)
Note

This is only faster when N is actually known at compile time, for example when it is a literal integer or a function's type parameter. For dynamic values of N, prefer the Int variant or in case of loops, directly loop over the tuple of momenta.

Some more overloads for the momentum function exist, for a complete list please refer to its documentation: QEDbase.momentum, QEDbase.momenta.

Finally, process, model, and phase_space_definition can be used to request the object in question:

process(psp)
one-photon Compton scattering
    incoming: electron (all spins), photon (all polarizations)
    outgoing: electron (all spins), photon (all polarizations)
model(psp)
perturbative QED
phase_space_definition(psp)
PhasespaceDefinition
    coordinate system: spherical coordinates
    frame: electron rest frame

In/Out Phase Space Points

As a special case, phase space points are allowed to only contain the incoming or outgoing particle momenta. These types can be helpful for overloading some functions that don't require the entire phase space point to exist.

function in_sum(in_psp::AbstractInPhaseSpacePoint)
    return sum(momenta(in_psp, Incoming()))
end

psp = InPhaseSpacePoint(
    Compton(),
    PerturbativeQED(),
    PhasespaceDefinition(SphericalCoordinateSystem(), ElectronRestFrame()),
    (rand(SFourMomentum), rand(SFourMomentum)),
)

in_sum(psp)
4-element SFourMomentum with indices SOneTo(4):
 1.3385830858713899
 1.0640522907100594
 1.177847246293277
 1.1794422879133486

Every full PhaseSpacePoint is both an InPhaseSpacePoint and an OutPhaseSpacePoint, too. For example, the in_sum function defined above still works with a full PhaseSpacePoint:

psp = PhaseSpacePoint(
    Compton(),
    PerturbativeQED(),
    PhasespaceDefinition(SphericalCoordinateSystem(), ElectronRestFrame()),
    (rand(SFourMomentum), rand(SFourMomentum)),
    (rand(SFourMomentum), rand(SFourMomentum)),
)

in_sum(psp)
4-element SFourMomentum with indices SOneTo(4):
 1.4213578131249887
 1.362676269176312
 0.9387326775899087
 0.5129625706739324

But an InPhaseSpacePoint is not an OutPhaseSpacePoint and vice versa. We cannot call in_sum on an OutPhaseSpacePoint:

psp = OutPhaseSpacePoint(
    Compton(),
    PerturbativeQED(),
    PhasespaceDefinition(SphericalCoordinateSystem(), ElectronRestFrame()),
    (rand(SFourMomentum), rand(SFourMomentum)),
)

    in_sum(psp)
┌ Error: MethodError(Main.in_sum, (PhaseSpacePoint of one-photon Compton scattering,), 0x0000000000007b40)
└ @ Main particles.md:280

This page was generated using Literate.jl.