Particles and Phase Space Points
There are three layers of abstraction from particles to phase space points in the QEDjl project:
QEDbase.AbstractParticleType
: Base type for singleton particle type definitions. We also call these species.QEDbase.AbstractParticleStateful
: Base type for particles with a direction and carrying a momentum.QEDbase.AbstractPhaseSpacePoint
: Representation of a point in the phase space for a combination of anQEDbase.AbstractProcessDefinition
,QEDbase.AbstractModelDefinition
, andQEDbase.AbstractPhaseSpaceLayout
.
This manual is intended to showcase the basic usage of these types and their implementations in QEDcore.
using QEDcore
To use concrete process definitions, models and phase-space layouts, we use the QEDbase.Mocks
module
using QEDbase.Mocks
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.02363927418981082, 0.510944761099263, 0.6629091630574231, 0.770295347371123]
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.02363927418981082
0.510944761099263
0.6629091630574231
0.770295347371123
Phase Space Points
A PhaseSpacePoint
is the combination of incoming and outgoing ParticleStateful
s. It also contains information about the scattering process, model, and phase space that it is created for.
Constructors
psp = PhaseSpacePoint(
MockProcess( # scattering process
(MockFermion(), MockBoson()),
(MockFermion(), MockBoson()),
),
MockModel(), # physics model
MockOutPhaseSpaceLayout( # layout for outgoing phase space
MockInPhaseSpaceLayout{ # layout for incoming phase space
MockMomentum, # momentum type
}(),
),
( # momenta of the incoming particles
rand(MockMomentum),
rand(MockMomentum),
),
( # momenta of the outgoing particles
rand(MockMomentum),
rand(MockMomentum),
),
)
PhaseSpacePoint:
process: mock process (2 -> 2)
model: mock model
phase space layout: mock out phase space layout
incoming particles:
-> incoming mock fermion: [0.1835286487537704, 0.22184780266273818, 0.9942709311161635, 0.6383801507043314]
-> incoming mock boson: [0.9176101493858461, 0.8884829567357764, 0.32125602203132875, 0.708889914290739]
outgoing particles:
-> outgoing mock fermion: [0.8742318469181241, 0.3559448095981185, 0.4614376618524959, 0.9036002719258899]
-> outgoing mock boson: [0.5765008524101958, 0.7753729454115815, 0.9078159743030692, 0.5640646916392439]
This version of the constructor automatically creates ParticleStateful
obejcts from the momenta, matching the particles of the process. In the case of our example process, this is means an incoming mock fermion and mock boson, and outgoing mock fermion and mock boson.
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(
MockProcess((MockFermion(), MockBoson()), (MockFermion(), MockBoson())),
MockModel(),
MockOutPhaseSpaceLayout(MockInPhaseSpaceLayout{MockMomentum}()),
(rand(MockMomentum),), # incorrect number of incoming momenta, should be 2
(rand(MockMomentum), rand(MockMomentum)),
)
┌ Error: InvalidInputError("expected 2 incoming particles for the process but got 1")
└ @ Main particles.md:131
Alternatively, a PhaseSpacePoint
can also be constructed from already existing ParticleStateful
objects.
psp = PhaseSpacePoint(
MockProcess((MockFermion(), MockBoson()), (MockFermion(), MockBoson())),
MockModel(),
MockOutPhaseSpaceLayout(MockInPhaseSpaceLayout{MockMomentum}()),
( # incoming particles
ParticleStateful(Incoming(), MockFermion(), rand(MockMomentum)),
ParticleStateful(Incoming(), MockBoson(), rand(MockMomentum)),
),
( # outgoing particles
ParticleStateful(Outgoing(), MockFermion(), rand(MockMomentum)),
ParticleStateful(Outgoing(), MockBoson(), rand(MockMomentum)),
),
)
PhaseSpacePoint:
process: mock process (2 -> 2)
model: mock model
phase space layout: mock out phase space layout
incoming particles:
-> incoming mock fermion: [0.2833616077208011, 0.26837659290029825, 0.23213306458515182, 0.9038935470602284]
-> incoming mock boson: [0.5252275780483193, 0.8969318804013285, 0.8823151081257558, 0.7905164168626416]
outgoing particles:
-> outgoing mock fermion: [0.02143310486154515, 0.8941689131046751, 0.8221035206201985, 0.20837381420846313]
-> outgoing mock boson: [0.13151199095636223, 0.8140724723762806, 0.4461293672921248, 0.3691791252007537]
Similar to the constructor from momenta, this checks that the given ParticleStateful
s fit to the given process and throws otherwise. Again, since this can be infered from type information alone, it adds no overhead.
PhaseSpacePoint(
MockProcess((MockFermion(), MockBoson()), (MockFermion(), MockBoson())),
MockModel(),
MockOutPhaseSpaceLayout(MockInPhaseSpaceLayout{MockMomentum}()),
( # incoming particles
ParticleStateful(Incoming(), MockBoson(), rand(MockMomentum)), # wrong particle type
ParticleStateful(Incoming(), MockBoson(), rand(MockMomentum)),
),
( # outgoing particles
ParticleStateful(Outgoing(), MockFermion(), rand(MockMomentum)),
ParticleStateful(Outgoing(), MockBoson(), rand(MockMomentum)),
),
)
┌ Error: InvalidInputError("expected incoming mock fermion but got incoming mock boson")
└ @ Main particles.md:178
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 mock fermion
momentum: [0.2833616077208011, 0.26837659290029825, 0.23213306458515182, 0.9038935470602284]
psp[Outgoing(), 2] # the second outgoing particle
ParticleStateful: outgoing mock boson
momentum: [0.13151199095636223, 0.8140724723762806, 0.4461293672921248, 0.3691791252007537]
particles(psp, Incoming()) # all incoming particles as a tuple
(incoming mock fermion: [0.2833616077208011, 0.26837659290029825, 0.23213306458515182, 0.9038935470602284], incoming mock boson: [0.5252275780483193, 0.8969318804013285, 0.8823151081257558, 0.7905164168626416])
Momentum accessors:
momentum(psp, Incoming(), MockFermion(), 1) # the momentum of the first incoming electron
4-element QEDbase.Mocks.MockMomentum{Float64} with indices SOneTo(4):
0.2833616077208011
0.26837659290029825
0.23213306458515182
0.9038935470602284
When only one particle of the species exists in the particle set, the 1 can be ommitted for convenience.
@assert ans == momentum(psp, Incoming(), MockFermion())
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(), MockBoson(), Val(1))),
median(@benchmark momentum($psp, Incoming(), MockBoson(), 1)),
)
BenchmarkTools.TrialJudgement:
time: -89.34% => improvement (5.00% tolerance)
memory: -100.00% => improvement (1.00% tolerance)
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_layout
can be used to request the object in question:
process(psp)
mock process (2 -> 2)
model(psp)
mock model
phase_space_layout(psp)
mock out phase space layout
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(
MockProcess((MockFermion(), MockBoson()), (MockFermion(), MockBoson())),
MockModel(),
MockOutPhaseSpaceLayout(MockInPhaseSpaceLayout{MockMomentum}()),
(rand(MockMomentum), rand(MockMomentum)),
)
in_sum(psp)
4-element QEDbase.Mocks.MockMomentum{Float64} with indices SOneTo(4):
1.3917903101676408
1.6565444246846388
0.9747850657664887
0.768333119709199
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(
MockProcess((MockFermion(), MockBoson()), (MockFermion(), MockBoson())),
MockModel(),
MockOutPhaseSpaceLayout(MockInPhaseSpaceLayout{MockMomentum}()),
(rand(MockMomentum), rand(MockMomentum)),
(rand(MockMomentum), rand(MockMomentum)),
)
in_sum(psp)
4-element QEDbase.Mocks.MockMomentum{Float64} with indices SOneTo(4):
1.5358021022133586
0.44708673368132956
1.692934016528264
0.9208031245554051
But an InPhaseSpacePoint
is not an OutPhaseSpacePoint
and vice versa. We cannot call in_sum
on an OutPhaseSpacePoint
:
psp = OutPhaseSpacePoint(
MockProcess((MockFermion(), MockBoson()), (MockFermion(), MockBoson())),
MockModel(),
MockOutPhaseSpaceLayout(MockInPhaseSpaceLayout{MockMomentum}()),
(rand(MockMomentum), rand(MockMomentum)),
)
in_sum(psp)
┌ Error: MethodError(Main.in_sum, (PhaseSpacePoint of mock process (2 -> 2),), 0x0000000000007b79)
└ @ Main particles.md:307
This page was generated using Literate.jl.