diff --git a/src/models/physics_models/interface.jl b/src/models/physics_models/interface.jl index 5654735..a345754 100644 --- a/src/models/physics_models/interface.jl +++ b/src/models/physics_models/interface.jl @@ -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 diff --git a/src/models/physics_models/qed/compute.jl b/src/models/physics_models/qed/compute.jl index ce94d16..239c805 100644 --- a/src/models/physics_models/qed/compute.jl +++ b/src/models/physics_models/qed/compute.jl @@ -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)" diff --git a/src/models/physics_models/qed/parse.jl b/src/models/physics_models/qed/parse.jl index 31f2e85..7b8f6e0 100644 --- a/src/models/physics_models/qed/parse.jl +++ b/src/models/physics_models/qed/parse.jl @@ -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 diff --git a/src/models/physics_models/qed/particle.jl b/src/models/physics_models/qed/particle.jl index f41fa8b..a21021e 100644 --- a/src/models/physics_models/qed/particle.jl +++ b/src/models/physics_models/qed/particle.jl @@ -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