Congruent incoming photons implementation #11

Merged
rubydragon merged 9 commits from congruent_in_ph into refactor 2024-07-10 14:04:13 +02:00
4 changed files with 107 additions and 23 deletions
Showing only changes of commit b5d92b729c - Show all commits

View File

@ -19,6 +19,17 @@ struct ParticleValue{ParticleType <: AbstractParticleStateful, ValueType}
v::ValueType
end
"""
TBW
particle value + spin/pol info, only used on the external legs (u tasks)
"""
struct ParticleValueSP{ParticleType <: AbstractParticleStateful, SP <: AbstractSpinOrPolarization, ValueType}
p::ParticleType
v::ValueType
sp::SP
end
"""
AbstractProcessDescription <: AbstractProblemInstance

View File

@ -3,17 +3,24 @@ using StaticArrays
function input_expr(name::String, psp::PhaseSpacePoint)
(type, index) = type_index_from_name(QEDModel(), name)
return ParticleValue(type(momentum(psp, particle_direction(type), particle_species(type), index)), 0.0im)
return ParticleValueSP(
type(momentum(psp, particle_direction(type), particle_species(type), index)),
0.0im,
spin_or_pol(process(psp), type, index),
)
end
"""
compute(::ComputeTaskQED_U, data::QEDParticleValue)
compute(::ComputeTaskQED_U, data::ParticleValueSP)
Compute an outer edge. Return the particle value with the same particle and the value multiplied by an outer_edge factor.
"""
function compute(::ComputeTaskQED_U, data::ParticleValue{P, V}) where {P <: ParticleStateful, V <: ValueType}
function compute(
::ComputeTaskQED_U,
data::ParticleValueSP{P, SP, V},
) where {P <: ParticleStateful, V <: ValueType, SP <: AbstractSpinOrPolarization}
part::P = data.p
state = base_state(particle_species(part), particle_direction(part), momentum(part), spin_or_pol(part))
state = base_state(particle_species(part), particle_direction(part), momentum(part), SP())
return ParticleValue{P, typeof(state)}(
data.p,
state, # will return a SLorentzVector{ComplexF64}, BiSpinor or AdjointBiSpinor
@ -21,7 +28,7 @@ function compute(::ComputeTaskQED_U, data::ParticleValue{P, V}) where {P <: Part
end
"""
compute(::ComputeTaskQED_V, data1::QEDParticleValue, data2::QEDParticleValue)
compute(::ComputeTaskQED_V, data1::ParticleValue, data2::ParticleValue)
Compute a vertex. Preserve momentum and particle types (e + gamma->p etc.) to create resulting particle, multiply values together and times a vertex factor.
"""
@ -49,7 +56,7 @@ function compute(
end
"""
compute(::ComputeTaskQED_S2, data1::QEDParticleValue, data2::QEDParticleValue)
compute(::ComputeTaskQED_S2, data1::ParticleValue, data2::ParticleValue)
Compute a final inner edge (2 input particles, no output particle).
@ -59,8 +66,8 @@ For valid inputs, both input particles should have the same momenta at this poin
"""
function compute(
::ComputeTaskQED_S2,
data1::ParticleValue{ParticleStateful{D1, S1}, V1},
data2::ParticleValue{ParticleStateful{D2, S2}, V2},
data1::ParticleValue{P1, V1},
data2::ParticleValue{P2, V2},
) where {
D1 <: ParticleDirection,
D2 <: ParticleDirection,
@ -68,6 +75,9 @@ function compute(
S2 <: Union{Electron, Positron},
V1 <: ValueType,
V2 <: ValueType,
EL <: AbstractFourMomentum,
P1 <: ParticleStateful{D1, S1, EL},
P2 <: ParticleStateful{D2, S2, EL},
}
#@assert isapprox(data1.p.momentum, data2.p.momentum, rtol = sqrt(eps()), atol = sqrt(eps())) "$(data1.p.momentum) vs. $(data2.p.momentum)"

View File

@ -1,10 +1,18 @@
# TODO generalize this somehow, probably using AllSpin/AllPol as defaults
"""
parse_process(string::AbstractString, model::QEDModel)
Parse a string representation of a process, such as "ke->ke" into the corresponding [`QEDProcessDescription`](@ref).
"""
function parse_process(str::AbstractString, model::QEDModel)
function parse_process(
str::AbstractString,
model::QEDModel,
inphpol::AbstractDefinitePolarization,
inelspin::AbstractDefiniteSpin,
outphpol::AbstractDefinitePolarization,
outelspin::AbstractDefiniteSpin,
)
inParticles = Dict(
ParticleStateful{Incoming, Photon, SFourMomentum} => 0,
ParticleStateful{Incoming, Electron, SFourMomentum} => 0,
@ -48,13 +56,14 @@ function parse_process(str::AbstractString, model::QEDModel)
throw("Encountered unknown characters in the output part of process \"$str\"")
end
in_ph = inParticles[ParticleStateful{Incoming, Photon, SFourMomentum}]
in_el = inParticles[ParticleStateful{Incoming, Electron, SFourMomentum}]
in_pos = inParticles[ParticleStateful{Incoming, Positron, SFourMomentum}]
out_ph = outParticles[ParticleStateful{Outgoing, Photon, SFourMomentum}]
out_el = outParticles[ParticleStateful{Outgoing, Electron, SFourMomentum}]
out_pos = outParticles[ParticleStateful{Outgoing, Positron, SFourMomentum}]
in_spin_pols = tuple([i <= in_ph ? inphpol : inelspin for i in 1:(in_ph + in_el)]...)
out_spin_pols = tuple([i <= out_ph ? outphpol : outelspin for i in 1:(out_ph + out_el)]...)
return GenericQEDProcess(
inParticles[ParticleStateful{Incoming, Photon, SFourMomentum}],
outParticles[ParticleStateful{Outgoing, Photon, SFourMomentum}],
inParticles[ParticleStateful{Incoming, Electron, SFourMomentum}],
outParticles[ParticleStateful{Outgoing, Electron, SFourMomentum}],
inParticles[ParticleStateful{Incoming, Positron, SFourMomentum}],
outParticles[ParticleStateful{Outgoing, Positron, SFourMomentum}],
)
return GenericQEDProcess(in_ph, out_ph, in_el, out_el, in_pos, out_pos, in_spin_pols, out_spin_pols)
end

View File

@ -25,29 +25,83 @@ _assert_particle_type_tuple(t::Tuple{AbstractParticleType, Vararg}) = _assert_pa
_assert_particle_type_tuple(t::Any) =
throw(InvalidInputError("invalid input, provide a tuple of AbstractParticleTypes to construct a GenericQEDProcess"))
struct GenericQEDProcess{INT, OUTT} <: AbstractProcessDefinition where {INT <: Tuple, OUTT <: Tuple}
struct GenericQEDProcess{INT, OUTT, INSP, OUTSP} <:
AbstractProcessDefinition where {INT <: Tuple, OUTT <: Tuple, INSP <: Tuple, OUTSP <: Tuple}
incoming_particles::INT
outgoing_particles::OUTT
function GenericQEDProcess(in_particles::INT, out_particles::OUTT) where {INT <: Tuple, OUTT <: Tuple}
incoming_spins_pols::INSP
outgoing_spins_pols::OUTSP
function GenericQEDProcess(
in_particles::INT,
out_particles::OUTT,
in_sp::INSP,
out_sp::OUTSP,
) where {INT <: Tuple, OUTT <: Tuple, INSP <: Tuple, OUTSP <: Tuple}
_assert_particle_type_tuple(in_particles)
_assert_particle_type_tuple(out_particles)
return new{INT, OUTT}(in_particles, out_particles)
# TODO: check in_sp/out_sp fits to particles (spin->fermion, pol->photon)
return new{INT, OUTT, INSP, OUTSP}(in_particles, out_particles, in_sp, out_sp)
end
"""
GenericQEDProcess(in_ph::Int, out_ph::Int, in_el::Int, out_el::Int, in_po::Int, out_po::Int)
GenericQEDProcess{INSP, OUTSP}(in_ph::Int, out_ph::Int, in_el::Int, out_el::Int, in_po::Int, out_po::Int, in_sp::INSP, out_sp::OUTSP)
Convenience constructor from numbers of input/output photons, electrons and positrons.
`in_sp` and `out_sp` are tuples of the spin and polarization configurations of the given particles. Their order is Photons, then Electrons, then Positrons for both incoming and outgoing particles.
# TODO: make default for in_sp and out_sp available for convenience
"""
function GenericQEDProcess(in_ph::Int, out_ph::Int, in_el::Int, out_el::Int, in_po::Int, out_po::Int)
function GenericQEDProcess(
in_ph::Int,
out_ph::Int,
in_el::Int,
out_el::Int,
in_po::Int,
out_po::Int,
in_sp::INSP,
out_sp::OUTSP,
) where {INSP <: Tuple, OUTSP <: Tuple}
in_p = ntuple(i -> i <= in_ph ? Photon() : i <= in_ph + in_el ? Electron() : Positron(), in_ph + in_el + in_po)
out_p = ntuple(
i -> i <= out_ph ? Photon() : i <= out_ph + out_el ? Electron() : Positron(),
out_ph + out_el + out_po,
)
return GenericQEDProcess(in_p, out_p)
return GenericQEDProcess(in_p, out_p, in_sp, out_sp)
end
end
function spin_or_pol(
process::GenericQEDProcess,
type::Type{ParticleStateful{DIR, SPECIES, EL}},
n::Int,
) where {DIR <: ParticleDirection, SPECIES <: AbstractParticleType, EL <: AbstractFourMomentum}
i = 0
c = n
for p in particles(process, DIR())
i += 1
if p == SPECIES()
c -= 1
end
if c == 0
break
end
end
if c != 0 || n <= 0
throw(InvalidInputError("could not get $n-th spin/pol of $(DIR()) $species, does not exist"))
end
if DIR <: Incoming
return process.incoming_spins_pols[i]
elseif DIR <: Outgoing
return process.outgoing_spins_pols[i]
else
throw(InvalidInputError("unknown direction $(DIR()) given"))
end
end