Skip to content

Commit

Permalink
Review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
AntonReinhard committed Aug 26, 2024
1 parent c11b320 commit 117a5ba
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 109 deletions.
2 changes: 1 addition & 1 deletion src/QEDprocesses.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export PerturbativeQED

# specific scattering processes
export Compton, omega_prime
export GenericQEDProcess, isphysical
export ScatteringProcess, isphysical

using QEDbase
using QEDcore
Expand Down
14 changes: 14 additions & 0 deletions src/models/perturbative_qed.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,17 @@ function Base.show(io::IO, ::PerturbativeQED)
print(io, "perturbative QED")
return nothing
end

"""
isphysical(proc::AbstractProcessDefinition, model::PerturbativeQED)
A utility function that returns whether a given `AbstractProcessDefinition` conserves the number and charge of fermions and has at least 2 participating particles.
"""
function isphysical(proc::AbstractProcessDefinition, ::PerturbativeQED)
return (
number_particles(proc, Incoming(), Electron()) +
number_particles(proc, Outgoing(), Positron()) ==
number_particles(proc, Incoming(), Positron()) +
number_particles(proc, Outgoing(), Electron())
) && number_particles(proc, Incoming()) + number_particles(proc, Outgoing()) >= 2
end
14 changes: 6 additions & 8 deletions src/processes/generic_process/perturbative/cross_section.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,19 @@
# They will be implemented using the QEDFeynmanDiagrams project when that is released.

#=
function QEDbase._incident_flux(psp::InPhaseSpacePoint{<:GenericQEDProcess,PerturbativeQED}) end
function QEDbase._incident_flux(psp::InPhaseSpacePoint{<:ScatteringProcess,PerturbativeQED}) end
function QEDbase._matrix_element(psp::PhaseSpacePoint{<:GenericQEDProcess,PerturbativeQED})
function QEDbase._matrix_element_squared(psp::PhaseSpacePoint{<:ScatteringProcess,PerturbativeQED})
proc = process(psp)
# by using FeynmanDiagramGenerator.jl
return sqrt(proc.matrix_element_squared(psp))
return proc.matrix_element_squared(psp)
end
function QEDbase._averaging_norm(proc::<:GenericQEDProcess) end
function QEDbase._averaging_norm(proc::<:ScatteringProcess) end
function QEDbase._is_in_phasespace(psp::PhaseSpacePoint{<:GenericQEDProcess,PerturbativeQED}) end
function QEDbase._is_in_phasespace(psp::PhaseSpacePoint{<:ScatteringProcess,PerturbativeQED}) end
function QEDbase._phase_space_factor(
psp::PhaseSpacePoint{<:GenericQEDProcess,PerturbativeQED,CustomPhasespaceDefinition}
psp::PhaseSpacePoint{<:ScatteringProcess,PerturbativeQED,CustomPhasespaceDefinition}
) end
function QEDbase._total_probability(in_psp::InPhaseSpacePoint{<:GenericQEDProcess,PerturbativeQED}) end
=#
103 changes: 44 additions & 59 deletions src/processes/generic_process/process.jl
Original file line number Diff line number Diff line change
@@ -1,62 +1,61 @@
"""
GenericQEDProcess <: AbstractProcessDefinition
ScatteringProcess <: AbstractProcessDefinition
An implementation of the `AbstractProcessDefinition` interface for a generic particle process in QED
with any number of incoming and outgoing particles, and any combination of spins or polarizations for the particles set.
Generic implementation for scattering processes of arbitrary particles. Currently, only calculations in combination with `PerturbativeQED` are supported.
However, this is supposed to describe scattering processes with any number of incoming and outgoing particles, and any combination of spins or polarizations for the particles.
The [`isphysical`](@ref) function can be used to check whether the process is possible in QED.
The [`isphysical`](@ref) function can be used to check whether the process is possible in perturbative QED.
!!! note
!!! warning
The computation of cross sections and probabilities is currently unimplemented.
## Constructors
ScatteringProcess(
in_particles::Tuple{AbstractParticleType},
out_particles::Tuple{AbstractParticleType},
[in_sp::Tuple{AbstractSpinOrPolarization},
out_sp::Tuple{AbstractSpinOrPolarization}]
)
Constructor for a ScatteringProcess with the given incoming and outgoing particles and their respective spins and pols.
The constructor asserts that the particles are compatible with their respective spins and polarizations. If the assertion fails, an
`InvalidInputError` is thrown.
The `in_sp` and `out_sp` parameters can be omitted in which case all spins and polarizations will be set to `AllSpin` and `AllPol` for every fermion and boson, respectively.
"""
struct GenericQEDProcess{INT,OUTT,INSP,OUTSP} <:
struct ScatteringProcess{INT,OUTT,INSP,OUTSP} <:
AbstractProcessDefinition where {INT<:Tuple,OUTT<:Tuple,INSP<:Tuple,OUTSP<:Tuple}
incoming_particles::INT
outgoing_particles::OUTT

incoming_spin_pols::INSP
outgoing_spin_pols::OUTSP

"""
GenericQEDProcess(
in_particles::Tuple{AbstractParticleType},
out_particles::Tuple{AbstractParticleType},
in_sp::Tuple{AbstractSpinOrPolarization},
out_sp::Tuple{AbstractSpinOrPolarization}
)
Constructor for a GenericQEDProcess with the given incoming and outgoing particles and their respective spins and pols.
The constructor asserts that the particles are compatible with their respective spins and polarizations. If the assertion fails, an
`InvalidInputError` is thrown.
"""
function GenericQEDProcess(
in_particles::INT, out_particles::OUTT, in_spin_pols::INSP, out_spin_pols::OUTSP
) where {INT<:Tuple,OUTT<:Tuple,INSP<:Tuple,OUTSP<:Tuple}
_assert_particle_type_tuple(in_particles)
_assert_particle_type_tuple(out_particles)

function ScatteringProcess(
in_particles::NTuple{I,AbstractParticleType},
out_particles::NTuple{O,AbstractParticleType},
in_spin_pols::NTuple{I,AbstractSpinOrPolarization},
out_spin_pols::NTuple{O,AbstractSpinOrPolarization},
) where {I,O}
_assert_spin_pol_particle_compatability(in_particles, in_spin_pols)
_assert_spin_pol_particle_compatability(out_particles, out_spin_pols)

return new{INT,OUTT,INSP,OUTSP}(
return new{
typeof(in_particles),
typeof(out_particles),
typeof(in_spin_pols),
typeof(out_spin_pols),
}(
in_particles, out_particles, in_spin_pols, out_spin_pols
)
end
end

"""
GenericQEDProcess(in_particles::Tuple{AbstractParticleType}, out_particles::Tuple{AbstractParticleType})
Constructor for a GenericQEDProcess, setting `AllPol` and `AllSpin` for every boson and fermion, respectively.
"""
function GenericQEDProcess(
in_particles::INT, out_particles::OUTT
) where {INT<:Tuple,OUTT<:Tuple}
# this will be called again by the default constructor, but it produces a nicer warning here
# than the following spin/pol generation failing because is_fermion or is_boson isn't defined on not allowed types
_assert_particle_type_tuple(in_particles)
_assert_particle_type_tuple(out_particles)

function ScatteringProcess(
in_particles::NTuple{I,AbstractParticleType},
out_particles::NTuple{O,AbstractParticleType},
) where {I,O}
in_spin_pols = ntuple(
x -> is_fermion(in_particles[x]) ? AllSpin() : AllPolarization(),
length(in_particles),
Expand All @@ -65,37 +64,23 @@ function GenericQEDProcess(
x -> is_fermion(out_particles[x]) ? AllSpin() : AllPolarization(),
length(out_particles),
)
return GenericQEDProcess(in_particles, out_particles, in_spin_pols, out_spin_pols)
return ScatteringProcess(in_particles, out_particles, in_spin_pols, out_spin_pols)
end

function QEDbase.incoming_particles(proc::GenericQEDProcess)
function QEDbase.incoming_particles(proc::ScatteringProcess)
return proc.incoming_particles
end
function QEDbase.outgoing_particles(proc::GenericQEDProcess)
function QEDbase.outgoing_particles(proc::ScatteringProcess)
return proc.outgoing_particles
end
function QEDbase.incoming_spin_pols(proc::GenericQEDProcess)
function QEDbase.incoming_spin_pols(proc::ScatteringProcess)
return proc.incoming_spin_pols
end
function QEDbase.outgoing_spin_pols(proc::GenericQEDProcess)
function QEDbase.outgoing_spin_pols(proc::ScatteringProcess)
return proc.outgoing_spin_pols
end

"""
isphysical(proc::GenericQEDProcess)
A utility function that returns whether a given GenericQEDProcess conserves the number and charge of fermions and has at least 2 participating particles.
"""
function isphysical(proc::GenericQEDProcess)
return (
number_particles(proc, Incoming(), Electron()) +
number_particles(proc, Outgoing(), Positron()) ==
number_particles(proc, Incoming(), Positron()) +
number_particles(proc, Outgoing(), Electron())
) && number_particles(proc, Incoming()) + number_particles(proc, Outgoing()) >= 2
end

function Base.show(io::IO, proc::GenericQEDProcess)
function Base.show(io::IO, proc::ScatteringProcess)
print(io, "generic QED process \"")
for p in incoming_particles(proc)
print(io, _particle_to_letter(p))
Expand All @@ -108,7 +93,7 @@ function Base.show(io::IO, proc::GenericQEDProcess)
return nothing
end

function Base.show(io::IO, ::MIME"text/plain", proc::GenericQEDProcess)
function Base.show(io::IO, ::MIME"text/plain", proc::ScatteringProcess)
println(io, "generic QED process")
for dir in (Incoming(), Outgoing())
first = true
Expand Down
21 changes: 3 additions & 18 deletions src/processes/generic_process/utility.jl
Original file line number Diff line number Diff line change
@@ -1,23 +1,8 @@
_assert_particle_type_tuple(::Tuple{}) = nothing
function _assert_particle_type_tuple(t::Tuple{AbstractParticleType,Vararg})
return _assert_particle_type_tuple(t[2:end])
end
function _assert_particle_type_tuple(t::Any)
throw(
InvalidInputError(
"invalid input, provide a tuple of AbstractParticleTypes to construct a GenericQEDProcess",
),
)
end

# recursion success, all particles are compatible with their spin/pol
_assert_spin_pol_particle_compatability(::Tuple{}, ::Tuple{}) = nothing
function _assert_spin_pol_particle_compatability(::Tuple{}, ::Tuple{Vararg})
throw(InvalidInputError("more spins/pols than particles given"))
end
function _assert_spin_pol_particle_compatability(::Tuple{Vararg}, ::Tuple{})
throw(InvalidInputError("more particles than spins/pols given"))
end

# recursion base case: check first particle against first spin/pol, then recurse
# note: the length of the tuples is expected to be the same, the constructor ensures this by using NTuples
function _assert_spin_pol_particle_compatability(
particles::Tuple{AbstractParticleType,Vararg},
spin_pols::Tuple{AbstractSpinOrPolarization,Vararg},
Expand Down
2 changes: 1 addition & 1 deletion test/processes/generic_process/groundtruths.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
POLS = [PolX(), PolY(), AllPol()]
SPINS = [SpinUp(), SpinDown(), AllSpin()]

function _groundtruth_is_physical(proc::GenericQEDProcess)
function _groundtruth_is_physical(proc::ScatteringProcess, ::PerturbativeQED)
incoming_electrons = number_particles(proc, Incoming(), Electron())
incoming_positrons = number_particles(proc, Incoming(), Positron())
outgoing_electrons = number_particles(proc, Outgoing(), Electron())
Expand Down
46 changes: 24 additions & 22 deletions test/processes/generic_process/process.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ include("groundtruths.jl")
const RNG = MersenneTwister(77697185)

PARTICLES = [Electron(), Positron(), Photon()]
POLS = [PolX(), PolY(), AllPol()]
SPINS = [SpinUp(), SpinDown(), AllSpin()]
POLS = [PolX(), PolY(), AllPol(), SyncedPolarization(1)]
SPINS = [SpinUp(), SpinDown(), AllSpin(), SyncedSpin(1)]
POL_AND_SPIN_COMBINATIONS = Iterators.product(SPINS, POLS, SPINS, POLS)
BUF = IOBuffer()

@testset "constructor" begin
@testset "default" begin
proc = GenericQEDProcess((Photon(), Electron()), (Photon(), Electron()))
proc = ScatteringProcess((Photon(), Electron()), (Photon(), Electron()))

@test QEDprocesses.spin_pols(proc, Incoming())[1] == AllPol()
@test QEDprocesses.spin_pols(proc, Incoming())[2] == AllSpin()
Expand All @@ -28,14 +28,14 @@ BUF = IOBuffer()
@test String(take!(BUF)) ==
"generic QED process\n incoming: photon ($(AllPol())), electron ($(AllSpin()))\n outgoing: photon ($(AllPol())), electron ($(AllSpin()))\n"

@test isphysical(proc)
@test isphysical(proc, PerturbativeQED())
end

@testset "all spins+pols" begin
@testset "$in_spin, $in_pol, $out_spin, $out_pol" for (
in_spin, in_pol, out_spin, out_pol
) in POL_AND_SPIN_COMBINATIONS
proc = GenericQEDProcess(
proc = ScatteringProcess(
(Photon(), Electron()),
(Photon(), Electron()),
(in_pol, in_spin),
Expand All @@ -54,34 +54,34 @@ BUF = IOBuffer()
@test String(take!(BUF)) ==
"generic QED process\n incoming: photon ($(in_pol)), electron ($(in_spin))\n outgoing: photon ($(out_pol)), electron ($(out_spin))\n"

@test isphysical(proc)
@test isphysical(proc, PerturbativeQED())
end
end

@testset "invalid types passed" begin
struct INVALID_PARTICLE end

@test_throws InvalidInputError(
"invalid input, provide a tuple of AbstractParticleTypes to construct a GenericQEDProcess",
) GenericQEDProcess((INVALID_PARTICLE(), Electron()), (Photon(), Electron()))
@test_throws MethodError ScatteringProcess(
(INVALID_PARTICLE(), Electron()), (Photon(), Electron())
)

@test_throws InvalidInputError(
"invalid input, provide a tuple of AbstractParticleTypes to construct a GenericQEDProcess",
) GenericQEDProcess((Photon(), Electron()), (Photon(), INVALID_PARTICLE()))
@test_throws MethodError ScatteringProcess(
(Photon(), Electron()), (Photon(), INVALID_PARTICLE())
)
end

@testset "incompatible spin/pols" begin
@test_throws InvalidInputError(
"particle \"electron\" is a fermion and should have a spin, but has \"all polarizations\"",
) GenericQEDProcess(
) ScatteringProcess(
(Electron(), Photon()),
(Electron(), Photon()),
(AllPol(), AllPol()),
(AllSpin(), AllPol()),
)
@test_throws InvalidInputError(
"particle \"photon\" is a boson and should have a polarization, but has \"all spins\"",
) GenericQEDProcess(
) ScatteringProcess(
(Electron(), Photon()),
(Electron(), Photon()),
(AllSpin(), AllSpin()),
Expand All @@ -93,13 +93,13 @@ BUF = IOBuffer()
IN_PARTICLES = Tuple(rand(RNG, PARTICLES, 2))
OUT_PARTICLES = Tuple(rand(RNG, PARTICLES, 2))
@testset "2 particles, 1 spin/pol" begin
@test_throws InvalidInputError("more particles than spins/pols given") GenericQEDProcess(
@test_throws MethodError ScatteringProcess(
IN_PARTICLES,
OUT_PARTICLES,
_random_spin_pols(RNG, IN_PARTICLES)[1:1],
_random_spin_pols(RNG, OUT_PARTICLES),
)
@test_throws InvalidInputError("more particles than spins/pols given") GenericQEDProcess(
@test_throws MethodError ScatteringProcess(
IN_PARTICLES,
OUT_PARTICLES,
_random_spin_pols(RNG, IN_PARTICLES),
Expand All @@ -108,13 +108,13 @@ BUF = IOBuffer()
end

@testset "2 particles, 3 spin/pols" begin
@test_throws InvalidInputError("more spins/pols than particles given") GenericQEDProcess(
@test_throws MethodError ScatteringProcess(
IN_PARTICLES,
OUT_PARTICLES,
(_random_spin_pols(RNG, IN_PARTICLES)..., AllPol()),
_random_spin_pols(RNG, OUT_PARTICLES),
)
@test_throws InvalidInputError("more spins/pols than particles given") GenericQEDProcess(
@test_throws MethodError ScatteringProcess(
IN_PARTICLES,
OUT_PARTICLES,
_random_spin_pols(RNG, IN_PARTICLES),
Expand All @@ -128,7 +128,7 @@ end
@testset "$n -> $m processes" for (n, m) in Base.product((2, 4), (3, 5))
IN_PARTICLES = Tuple(rand(RNG, PARTICLES, n))
OUT_PARTICLES = Tuple(rand(RNG, PARTICLES, m))
proc = GenericQEDProcess(IN_PARTICLES, OUT_PARTICLES)
proc = ScatteringProcess(IN_PARTICLES, OUT_PARTICLES)
@testset "process $(proc)" begin
@test incoming_particles(proc) == IN_PARTICLES
@test outgoing_particles(proc) == OUT_PARTICLES
Expand All @@ -137,12 +137,13 @@ end
@test incoming_spin_pols(proc) == _groundtruth_spin_pols(IN_PARTICLES)
@test outgoing_spin_pols(proc) == _groundtruth_spin_pols(OUT_PARTICLES)

@test isphysical(proc) == _groundtruth_is_physical(proc)
@test isphysical(proc, PerturbativeQED()) ==
_groundtruth_is_physical(proc, PerturbativeQED())
end

IN_SPIN_POLS = _random_spin_pols(RNG, IN_PARTICLES)
OUT_SPIN_POLS = _random_spin_pols(RNG, OUT_PARTICLES)
proc = GenericQEDProcess(IN_PARTICLES, OUT_PARTICLES, IN_SPIN_POLS, OUT_SPIN_POLS)
proc = ScatteringProcess(IN_PARTICLES, OUT_PARTICLES, IN_SPIN_POLS, OUT_SPIN_POLS)
@testset "process $(proc) with set spins/pols" begin
@test incoming_particles(proc) == IN_PARTICLES
@test outgoing_particles(proc) == OUT_PARTICLES
Expand All @@ -151,7 +152,8 @@ end
@test incoming_spin_pols(proc) == IN_SPIN_POLS
@test outgoing_spin_pols(proc) == OUT_SPIN_POLS

@test isphysical(proc) == _groundtruth_is_physical(proc)
@test isphysical(proc, PerturbativeQED()) ==
_groundtruth_is_physical(proc, PerturbativeQED())
end
end
end

0 comments on commit 117a5ba

Please sign in to comment.