Compare commits
39 Commits
901944bd8b
...
experiment
Author | SHA1 | Date | |
---|---|---|---|
3a5d4fedd7 | |||
723c460cf6 | |||
810695171a | |||
70127817b3 | |||
d121daf206 | |||
f5157b6395 | |||
961b616ad1 | |||
ddfc9191d5 | |||
ae99be7207 | |||
371467c2bc | |||
1d957bc128 | |||
d036f21862 | |||
2e16b0dca7 | |||
86ad9ed5e8 | |||
0d9b066915 | |||
b39bc480a1 | |||
b7f8e4a6b3 | |||
71219f101e | |||
f3dab45f31 | |||
2784c82c23 | |||
78717c2b43 | |||
4584285126 | |||
fc31299d1e | |||
f4747bfc9d | |||
daf22ecdb0 | |||
17c2df800c | |||
fce9110e2a | |||
52e7bf43ad | |||
8bbbc72bfc | |||
6a02f3bee6 | |||
5be483c4c1 | |||
4c05167901 | |||
6186776059 | |||
c6ebf91079 | |||
a198f37f8e | |||
312d93cb4c | |||
007d970a12 | |||
3ac9954d32 | |||
7098d1801a |
@@ -17,9 +17,9 @@ jobs:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Julia environment
|
||||
uses: https://github.com/julia-actions/setup-julia@v2
|
||||
uses: https://github.com/julia-actions/setup-julia@v1.9.2
|
||||
with:
|
||||
version: '1.10'
|
||||
version: '1.9.2'
|
||||
|
||||
- name: Instantiate
|
||||
run: |
|
||||
@@ -58,9 +58,9 @@ jobs:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Julia environment
|
||||
uses: https://github.com/julia-actions/setup-julia@v2
|
||||
uses: https://github.com/julia-actions/setup-julia@v1.9.2
|
||||
with:
|
||||
version: '1.10'
|
||||
version: '1.9.2'
|
||||
|
||||
- name: Build docs
|
||||
run: |
|
||||
|
@@ -1,10 +1,9 @@
|
||||
authors = ["Anton Reinhard <anton.reinhard@proton.me>"]
|
||||
name = "MetagraphOptimization"
|
||||
uuid = "3e869610-d48d-4942-ba70-c1b702a33ca4"
|
||||
authors = ["Anton Reinhard <anton.reinhard@proton.me>"]
|
||||
version = "0.1.0"
|
||||
|
||||
[deps]
|
||||
AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e"
|
||||
AccurateArithmetic = "22286c92-06ac-501d-9306-4abd417d9753"
|
||||
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
|
||||
Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"
|
||||
@@ -14,13 +13,11 @@ JuliaFormatter = "98e50ef6-434e-11e9-1051-2b60c6c9e899"
|
||||
KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c"
|
||||
NumaAllocators = "21436f30-1b4a-4f08-87af-e26101bb5379"
|
||||
QEDbase = "10e22c08-3ccb-4172-bfcf-7d7aa3d04d93"
|
||||
QEDcore = "35dc0263-cb5f-4c33-a114-1d7f54ab753e"
|
||||
QEDprocesses = "46de9c38-1bb3-4547-a1ec-da24d767fdad"
|
||||
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
|
||||
Roots = "f2b01f46-fcfa-551c-844a-d8ac1e96c665"
|
||||
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
|
||||
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
|
||||
oneAPI = "8f75cd03-7ff8-4ecb-9b8f-daf728133b1b"
|
||||
|
||||
[extras]
|
||||
CUDA_Runtime_jll = "76a88914-d11a-5bdc-97e0-2f5a05c973a2"
|
||||
|
@@ -1,123 +0,0 @@
|
||||
using MetagraphOptimization
|
||||
using QEDbase
|
||||
using QEDcore
|
||||
using Random
|
||||
using UUIDs
|
||||
|
||||
RNG = Random.MersenneTwister(123)
|
||||
|
||||
function mock_machine()
|
||||
return Machine(
|
||||
[
|
||||
MetagraphOptimization.NumaNode(
|
||||
0,
|
||||
1,
|
||||
MetagraphOptimization.default_strategy(MetagraphOptimization.NumaNode),
|
||||
-1.0,
|
||||
UUIDs.uuid1(),
|
||||
),
|
||||
],
|
||||
[-1.0;;],
|
||||
)
|
||||
end
|
||||
|
||||
function congruent_input(processDescription::QEDProcessDescription, omega::Number)
|
||||
# generate an input sample for given e + nk -> e' + k' process, where the nk are equal
|
||||
massSum = 0
|
||||
inputMasses = Vector{Float64}()
|
||||
for (particle, n) in processDescription.inParticles
|
||||
for _ in 1:n
|
||||
massSum += mass(particle)
|
||||
push!(inputMasses, mass(particle))
|
||||
end
|
||||
end
|
||||
outputMasses = Vector{Float64}()
|
||||
for (particle, n) in processDescription.outParticles
|
||||
for _ in 1:n
|
||||
massSum += mass(particle)
|
||||
push!(outputMasses, mass(particle))
|
||||
end
|
||||
end
|
||||
|
||||
initialMomenta = [
|
||||
i == 1 ? SFourMomentum(1, 0, 0, 0) : SFourMomentum(omega, 0, 0, omega) for
|
||||
i in 1:length(inputMasses)
|
||||
]
|
||||
|
||||
# add some extra random mass to allow for some momentum
|
||||
ss = sqrt(sum(initialMomenta) * sum(initialMomenta))
|
||||
|
||||
result = Vector{QEDProcessInput}()
|
||||
sizehint!(result, 16)
|
||||
|
||||
spin_pol_combinations = Iterators.product(
|
||||
[SpinUp, SpinDown], [SpinUp, SpinDown], [PolX, PolY], [PolX, PolY]
|
||||
)
|
||||
for (in_spin, out_spin, in_pol, out_pol) in spin_pol_combinations
|
||||
|
||||
# get the electron first, then the n photons
|
||||
particles = Vector{QEDParticle}()
|
||||
|
||||
for (particle, n) in processDescription.inParticles
|
||||
if particle <: FermionStateful
|
||||
mom = initialMomenta[1]
|
||||
push!(particles, particle(mom, in_spin()))
|
||||
elseif particle <: PhotonStateful
|
||||
for i in 1:n
|
||||
mom = initialMomenta[i + 1]
|
||||
push!(particles, particle(mom, in_pol()))
|
||||
end
|
||||
else
|
||||
@assert false
|
||||
end
|
||||
end
|
||||
|
||||
final_momenta = MetagraphOptimization.generate_physical_massive_moms(
|
||||
RNG, ss, outputMasses
|
||||
)
|
||||
index = 1
|
||||
for (particle, n) in processDescription.outParticles
|
||||
for _ in 1:n
|
||||
if particle <: FermionStateful
|
||||
push!(particles, particle(final_momenta[index], out_spin()))
|
||||
elseif particle <: PhotonStateful
|
||||
push!(particles, particle(final_momenta[index], out_pol()))
|
||||
end
|
||||
index += 1
|
||||
end
|
||||
end
|
||||
|
||||
inFerms = MetagraphOptimization._svector_from_type(
|
||||
processDescription, FermionStateful{Incoming,in_spin}, particles
|
||||
)
|
||||
outFerms = MetagraphOptimization._svector_from_type(
|
||||
processDescription, FermionStateful{Outgoing,out_spin}, particles
|
||||
)
|
||||
inAntiferms = MetagraphOptimization._svector_from_type(
|
||||
processDescription, AntiFermionStateful{Incoming,in_spin}, particles
|
||||
)
|
||||
outAntiferms = MetagraphOptimization._svector_from_type(
|
||||
processDescription, AntiFermionStateful{Outgoing,out_spin}, particles
|
||||
)
|
||||
inPhotons = MetagraphOptimization._svector_from_type(
|
||||
processDescription, PhotonStateful{Incoming,in_pol}, particles
|
||||
)
|
||||
outPhotons = MetagraphOptimization._svector_from_type(
|
||||
processDescription, PhotonStateful{Outgoing,out_pol}, particles
|
||||
)
|
||||
|
||||
processInput = QEDProcessInput(
|
||||
processDescription,
|
||||
inFerms,
|
||||
outFerms,
|
||||
inAntiferms,
|
||||
outAntiferms,
|
||||
inPhotons,
|
||||
outPhotons,
|
||||
)
|
||||
|
||||
push!(result, processInput)
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
@@ -6,8 +6,6 @@ A module containing tools to work on DAGs.
|
||||
module MetagraphOptimization
|
||||
|
||||
using QEDbase
|
||||
using QEDcore
|
||||
using QEDprocesses
|
||||
|
||||
# graph types
|
||||
export DAG
|
||||
@@ -116,6 +114,7 @@ import Base.delete!
|
||||
import Base.insert!
|
||||
import Base.collect
|
||||
|
||||
|
||||
include("devices/interface.jl")
|
||||
include("task/type.jl")
|
||||
include("node/type.jl")
|
||||
@@ -197,8 +196,10 @@ include("devices/impl.jl")
|
||||
|
||||
include("devices/numa/impl.jl")
|
||||
include("devices/cuda/impl.jl")
|
||||
include("devices/rocm/impl.jl")
|
||||
include("devices/oneapi/impl.jl")
|
||||
# can currently not use AMDGPU because of incompatability with the newest rocm drivers
|
||||
# include("devices/rocm/impl.jl")
|
||||
# oneapi seems also broken for now
|
||||
# include("devices/oneapi/impl.jl")
|
||||
|
||||
include("scheduler/interface.jl")
|
||||
include("scheduler/greedy.jl")
|
||||
|
@@ -84,13 +84,11 @@ Compute a sum over the vector. Use an algorithm that accounts for accumulated er
|
||||
Linearly many FLOP with growing data.
|
||||
"""
|
||||
function compute(::ComputeTaskABC_Sum, data...)::Float64
|
||||
return sum_kbn([data...])
|
||||
|
||||
#=s = 0.0im
|
||||
s = 0.0im
|
||||
for d in data
|
||||
s += d
|
||||
end
|
||||
return s=#
|
||||
return s
|
||||
end
|
||||
|
||||
function compute(::ComputeTaskABC_Sum, data::AbstractArray)::Float64
|
||||
|
@@ -27,6 +27,9 @@ Return a ProcessInput of randomly generated [`ABCParticle`](@ref)s from a [`ABCP
|
||||
Note: This uses RAMBO to create a valid process with conservation of momentum and energy.
|
||||
"""
|
||||
function gen_process_input(processDescription::ABCProcessDescription)
|
||||
inParticleTypes = keys(processDescription.inParticles)
|
||||
outParticleTypes = keys(processDescription.outParticles)
|
||||
|
||||
massSum = 0
|
||||
inputMasses = Vector{Float64}()
|
||||
for (particle, n) in processDescription.inParticles
|
||||
@@ -63,7 +66,8 @@ function gen_process_input(processDescription::ABCProcessDescription)
|
||||
index = 1
|
||||
for (particle, n) in processDescription.outParticles
|
||||
for _ in 1:n
|
||||
push!(outputParticles, particle(final_momenta[index]))
|
||||
mom = final_momenta[index]
|
||||
push!(outputParticles, particle(SFourMomentum(-mom.E, mom.px, mom.py, mom.pz)))
|
||||
index += 1
|
||||
end
|
||||
end
|
||||
|
@@ -5,9 +5,9 @@ using StaticArrays
|
||||
|
||||
Return the particle as is and initialize the Value.
|
||||
"""
|
||||
function compute(::ComputeTaskQED_P, data::QEDParticleValue{P}) where {P<:QEDParticle}
|
||||
function compute(::ComputeTaskQED_P, data::QEDParticleValue{P}) where {P <: QEDParticle}
|
||||
# TODO do we actually need this for anything?
|
||||
return ParticleValue{P,DiracMatrix}(data.p, one(DiracMatrix))
|
||||
return ParticleValue{P, DiracMatrix}(data.p, one(DiracMatrix))
|
||||
end
|
||||
|
||||
"""
|
||||
@@ -15,12 +15,10 @@ end
|
||||
|
||||
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::PV
|
||||
) where {P<:QEDParticle,PV<:QEDParticleValue{P}}
|
||||
function compute(::ComputeTaskQED_U, data::PV) where {P <: QEDParticle, PV <: QEDParticleValue{P}}
|
||||
part::P = data.p
|
||||
state = base_state(particle(part), direction(part), momentum(part), spin_or_pol(part))
|
||||
return ParticleValue{P,typeof(state)}(
|
||||
return ParticleValue{P, typeof(state)}(
|
||||
data.p,
|
||||
state, # will return a SLorentzVector{ComplexF64}, BiSpinor or AdjointBiSpinor
|
||||
)
|
||||
@@ -32,10 +30,10 @@ end
|
||||
Compute a vertex. Preserve momentum and particle types (e + gamma->p etc.) to create resulting particle, multiply values together and times a vertex factor.
|
||||
"""
|
||||
function compute(
|
||||
::ComputeTaskQED_V, data1::PV1, data2::PV2
|
||||
) where {
|
||||
P1<:QEDParticle,P2<:QEDParticle,PV1<:QEDParticleValue{P1},PV2<:QEDParticleValue{P2}
|
||||
}
|
||||
::ComputeTaskQED_V,
|
||||
data1::PV1,
|
||||
data2::PV2,
|
||||
) where {P1 <: QEDParticle, P2 <: QEDParticle, PV1 <: QEDParticleValue{P1}, PV2 <: QEDParticleValue{P2}}
|
||||
p3 = QED_conserve_momentum(data1.p, data2.p)
|
||||
P3 = interaction_result(P1, P2)
|
||||
state = QED_vertex()
|
||||
@@ -50,7 +48,7 @@ function compute(
|
||||
state = state * data2.v
|
||||
end
|
||||
|
||||
dataOut = ParticleValue{P3,typeof(state)}(P3(momentum(p3)), state)
|
||||
dataOut = ParticleValue{P3, typeof(state)}(P3(momentum(p3)), state)
|
||||
return dataOut
|
||||
end
|
||||
|
||||
@@ -64,11 +62,10 @@ For valid inputs, both input particles should have the same momenta at this poin
|
||||
12 FLOP.
|
||||
"""
|
||||
function compute(
|
||||
::ComputeTaskQED_S2, data1::ParticleValue{P1}, data2::ParticleValue{P2}
|
||||
) where {
|
||||
P1<:Union{AntiFermionStateful,FermionStateful},
|
||||
P2<:Union{AntiFermionStateful,FermionStateful},
|
||||
}
|
||||
::ComputeTaskQED_S2,
|
||||
data1::ParticleValue{P1},
|
||||
data2::ParticleValue{P2},
|
||||
) where {P1 <: Union{AntiFermionStateful, FermionStateful}, P2 <: Union{AntiFermionStateful, FermionStateful}}
|
||||
#@assert isapprox(data1.p.momentum, data2.p.momentum, rtol = sqrt(eps()), atol = sqrt(eps())) "$(data1.p.momentum) vs. $(data2.p.momentum)"
|
||||
|
||||
inner = QED_inner_edge(propagation_result(P1)(momentum(data1.p)))
|
||||
@@ -82,8 +79,10 @@ function compute(
|
||||
end
|
||||
|
||||
function compute(
|
||||
::ComputeTaskQED_S2, data1::ParticleValue{P1}, data2::ParticleValue{P2}
|
||||
) where {P1<:PhotonStateful,P2<:PhotonStateful}
|
||||
::ComputeTaskQED_S2,
|
||||
data1::ParticleValue{P1},
|
||||
data2::ParticleValue{P2},
|
||||
) where {P1 <: PhotonStateful, P2 <: PhotonStateful}
|
||||
# TODO: assert that data1 and data2 are opposites
|
||||
inner = QED_inner_edge(data1.p)
|
||||
# inner edge is just a scalar, data1 and data2 are photon states that are just Complex numbers here
|
||||
@@ -95,7 +94,7 @@ end
|
||||
|
||||
Compute inner edge (1 input particle, 1 output particle).
|
||||
"""
|
||||
function compute(::ComputeTaskQED_S1, data::QEDParticleValue{P}) where {P<:QEDParticle}
|
||||
function compute(::ComputeTaskQED_S1, data::QEDParticleValue{P}) where {P <: QEDParticle}
|
||||
newP = propagation_result(P)
|
||||
new_p = newP(momentum(data.p))
|
||||
# inner edge is just a scalar, can multiply from either side
|
||||
|
@@ -1,28 +1,14 @@
|
||||
|
||||
ComputeTaskQED_Sum() = ComputeTaskQED_Sum(0)
|
||||
|
||||
function _svector_from_type(
|
||||
processDescription::QEDProcessDescription, type::Type{T}, particles
|
||||
) where {DIR<:ParticleDirection,T<:QEDParticle{DIR}}
|
||||
if DIR <: Incoming
|
||||
l = 0
|
||||
for (k, v) in in_particles(processDescription)
|
||||
if T <: k
|
||||
l = v
|
||||
break
|
||||
end
|
||||
end
|
||||
return SVector{l,T}(filter(x -> typeof(x) <: T, particles))
|
||||
elseif DIR <: Outgoing
|
||||
l = 0
|
||||
for (k, v) in out_particles(processDescription)
|
||||
if T <: k
|
||||
l = v
|
||||
break
|
||||
end
|
||||
end
|
||||
return SVector{l,T}(filter(x -> typeof(x) <: T, particles))
|
||||
function _svector_from_type(processDescription::QEDProcessDescription, type, particles)
|
||||
if haskey(in_particles(processDescription), type)
|
||||
return SVector{in_particles(processDescription)[type], type}(filter(x -> typeof(x) <: type, particles))
|
||||
end
|
||||
if haskey(out_particles(processDescription), type)
|
||||
return SVector{out_particles(processDescription)[type], type}(filter(x -> typeof(x) <: type, particles))
|
||||
end
|
||||
return SVector{0, type}()
|
||||
end
|
||||
|
||||
"""
|
||||
@@ -52,6 +38,7 @@ function gen_process_input(processDescription::QEDProcessDescription)
|
||||
# add some extra random mass to allow for some momentum
|
||||
massSum += rand(rng[threadid()]) * (length(inputMasses) + length(outputMasses))
|
||||
|
||||
|
||||
particles = Vector{QEDParticle}()
|
||||
initialMomenta = generate_initial_moms(massSum, inputMasses)
|
||||
index = 1
|
||||
@@ -72,34 +59,15 @@ function gen_process_input(processDescription::QEDProcessDescription)
|
||||
end
|
||||
end
|
||||
|
||||
inFerms = _svector_from_type(
|
||||
processDescription, FermionStateful{Incoming,SpinUp}, particles
|
||||
)
|
||||
outFerms = _svector_from_type(
|
||||
processDescription, FermionStateful{Outgoing,SpinUp}, particles
|
||||
)
|
||||
inAntiferms = _svector_from_type(
|
||||
processDescription, AntiFermionStateful{Incoming,SpinUp}, particles
|
||||
)
|
||||
outAntiferms = _svector_from_type(
|
||||
processDescription, AntiFermionStateful{Outgoing,SpinUp}, particles
|
||||
)
|
||||
inPhotons = _svector_from_type(
|
||||
processDescription, PhotonStateful{Incoming,PolX}, particles
|
||||
)
|
||||
outPhotons = _svector_from_type(
|
||||
processDescription, PhotonStateful{Outgoing,PolX}, particles
|
||||
)
|
||||
inFerms = _svector_from_type(processDescription, FermionStateful{Incoming, SpinUp}, particles)
|
||||
outFerms = _svector_from_type(processDescription, FermionStateful{Outgoing, SpinUp}, particles)
|
||||
inAntiferms = _svector_from_type(processDescription, AntiFermionStateful{Incoming, SpinUp}, particles)
|
||||
outAntiferms = _svector_from_type(processDescription, AntiFermionStateful{Outgoing, SpinUp}, particles)
|
||||
inPhotons = _svector_from_type(processDescription, PhotonStateful{Incoming, PolX}, particles)
|
||||
outPhotons = _svector_from_type(processDescription, PhotonStateful{Outgoing, PolX}, particles)
|
||||
|
||||
processInput = QEDProcessInput(
|
||||
processDescription,
|
||||
inFerms,
|
||||
outFerms,
|
||||
inAntiferms,
|
||||
outAntiferms,
|
||||
inPhotons,
|
||||
outPhotons,
|
||||
)
|
||||
processInput =
|
||||
QEDProcessInput(processDescription, inFerms, outFerms, inAntiferms, outAntiferms, inPhotons, outPhotons)
|
||||
|
||||
return processInput
|
||||
end
|
||||
@@ -120,13 +88,9 @@ function gen_graph(process_description::QEDProcessDescription)
|
||||
|
||||
# TODO: Not all diagram outputs should always be summed at the end, if they differ by fermion exchange they need to be diffed
|
||||
# Should not matter for n-Photon Compton processes though
|
||||
sum_node = insert_node!(
|
||||
graph, make_node(ComputeTaskQED_Sum(0)); track=false, invalidate_cache=false
|
||||
)
|
||||
global_data_out = insert_node!(
|
||||
graph, make_node(DataTask(COMPLEX_SIZE)); track=false, invalidate_cache=false
|
||||
)
|
||||
insert_edge!(graph, sum_node, global_data_out; track=false, invalidate_cache=false)
|
||||
sum_node = insert_node!(graph, make_node(ComputeTaskQED_Sum(0)), track = false, invalidate_cache = false)
|
||||
global_data_out = insert_node!(graph, make_node(DataTask(COMPLEX_SIZE)), track = false, invalidate_cache = false)
|
||||
insert_edge!(graph, sum_node, global_data_out, track = false, invalidate_cache = false)
|
||||
|
||||
# remember the data out nodes for connection
|
||||
dataOutNodes = Dict()
|
||||
@@ -135,22 +99,16 @@ function gen_graph(process_description::QEDProcessDescription)
|
||||
# generate data in and U tasks
|
||||
data_in = insert_node!(
|
||||
graph,
|
||||
make_node(DataTask(PARTICLE_VALUE_SIZE), String(particle));
|
||||
track=false,
|
||||
invalidate_cache=false,
|
||||
make_node(DataTask(PARTICLE_VALUE_SIZE), String(particle)),
|
||||
track = false,
|
||||
invalidate_cache = false,
|
||||
) # read particle data node
|
||||
compute_u = insert_node!(
|
||||
graph, make_node(ComputeTaskQED_U()); track=false, invalidate_cache=false
|
||||
) # compute U node
|
||||
data_out = insert_node!(
|
||||
graph,
|
||||
make_node(DataTask(PARTICLE_VALUE_SIZE));
|
||||
track=false,
|
||||
invalidate_cache=false,
|
||||
) # transfer data out from u (one ABCParticleValue object)
|
||||
compute_u = insert_node!(graph, make_node(ComputeTaskQED_U()), track = false, invalidate_cache = false) # compute U node
|
||||
data_out =
|
||||
insert_node!(graph, make_node(DataTask(PARTICLE_VALUE_SIZE)), track = false, invalidate_cache = false) # transfer data out from u (one ABCParticleValue object)
|
||||
|
||||
insert_edge!(graph, data_in, compute_u; track=false, invalidate_cache=false)
|
||||
insert_edge!(graph, compute_u, data_out; track=false, invalidate_cache=false)
|
||||
insert_edge!(graph, data_in, compute_u, track = false, invalidate_cache = false)
|
||||
insert_edge!(graph, compute_u, data_out, track = false, invalidate_cache = false)
|
||||
|
||||
# remember the data_out node for future edges
|
||||
dataOutNodes[String(particle)] = data_out
|
||||
@@ -166,30 +124,19 @@ function gen_graph(process_description::QEDProcessDescription)
|
||||
data_in1 = dataOutNodes[String(vertex.in1)]
|
||||
data_in2 = dataOutNodes[String(vertex.in2)]
|
||||
|
||||
compute_V = insert_node!(
|
||||
graph,
|
||||
make_node(ComputeTaskQED_V());
|
||||
track=false,
|
||||
invalidate_cache=false,
|
||||
) # compute vertex
|
||||
compute_V = insert_node!(graph, make_node(ComputeTaskQED_V()), track = false, invalidate_cache = false) # compute vertex
|
||||
|
||||
insert_edge!(
|
||||
graph, data_in1, compute_V; track=false, invalidate_cache=false
|
||||
)
|
||||
insert_edge!(
|
||||
graph, data_in2, compute_V; track=false, invalidate_cache=false
|
||||
)
|
||||
insert_edge!(graph, data_in1, compute_V, track = false, invalidate_cache = false)
|
||||
insert_edge!(graph, data_in2, compute_V, track = false, invalidate_cache = false)
|
||||
|
||||
data_V_out = insert_node!(
|
||||
graph,
|
||||
make_node(DataTask(PARTICLE_VALUE_SIZE));
|
||||
track=false,
|
||||
invalidate_cache=false,
|
||||
make_node(DataTask(PARTICLE_VALUE_SIZE)),
|
||||
track = false,
|
||||
invalidate_cache = false,
|
||||
)
|
||||
|
||||
insert_edge!(
|
||||
graph, compute_V, data_V_out; track=false, invalidate_cache=false
|
||||
)
|
||||
insert_edge!(graph, compute_V, data_V_out, track = false, invalidate_cache = false)
|
||||
|
||||
if (vertex.out == tie.in1 || vertex.out == tie.in2)
|
||||
# out particle is part of the tie -> there will be an S2 task with it later, don't make S1 task
|
||||
@@ -198,27 +145,19 @@ function gen_graph(process_description::QEDProcessDescription)
|
||||
end
|
||||
|
||||
# otherwise, add S1 task
|
||||
compute_S1 = insert_node!(
|
||||
graph,
|
||||
make_node(ComputeTaskQED_S1());
|
||||
track=false,
|
||||
invalidate_cache=false,
|
||||
) # compute propagator
|
||||
compute_S1 =
|
||||
insert_node!(graph, make_node(ComputeTaskQED_S1()), track = false, invalidate_cache = false) # compute propagator
|
||||
|
||||
insert_edge!(
|
||||
graph, data_V_out, compute_S1; track=false, invalidate_cache=false
|
||||
)
|
||||
insert_edge!(graph, data_V_out, compute_S1, track = false, invalidate_cache = false)
|
||||
|
||||
data_S1_out = insert_node!(
|
||||
graph,
|
||||
make_node(DataTask(PARTICLE_VALUE_SIZE));
|
||||
track=false,
|
||||
invalidate_cache=false,
|
||||
make_node(DataTask(PARTICLE_VALUE_SIZE)),
|
||||
track = false,
|
||||
invalidate_cache = false,
|
||||
)
|
||||
|
||||
insert_edge!(
|
||||
graph, compute_S1, data_S1_out; track=false, invalidate_cache=false
|
||||
)
|
||||
insert_edge!(graph, compute_S1, data_S1_out, track = false, invalidate_cache = false)
|
||||
|
||||
# overrides potentially different nodes from previous diagrams, which is intentional
|
||||
dataOutNodes[String(vertex.out)] = data_S1_out
|
||||
@@ -229,23 +168,16 @@ function gen_graph(process_description::QEDProcessDescription)
|
||||
data_in1 = dataOutNodes[String(tie.in1)]
|
||||
data_in2 = dataOutNodes[String(tie.in2)]
|
||||
|
||||
compute_S2 = insert_node!(
|
||||
graph, make_node(ComputeTaskQED_S2()); track=false, invalidate_cache=false
|
||||
)
|
||||
compute_S2 = insert_node!(graph, make_node(ComputeTaskQED_S2()), track = false, invalidate_cache = false)
|
||||
|
||||
data_S2 = insert_node!(
|
||||
graph,
|
||||
make_node(DataTask(PARTICLE_VALUE_SIZE));
|
||||
track=false,
|
||||
invalidate_cache=false,
|
||||
)
|
||||
data_S2 = insert_node!(graph, make_node(DataTask(PARTICLE_VALUE_SIZE)), track = false, invalidate_cache = false)
|
||||
|
||||
insert_edge!(graph, data_in1, compute_S2; track=false, invalidate_cache=false)
|
||||
insert_edge!(graph, data_in2, compute_S2; track=false, invalidate_cache=false)
|
||||
insert_edge!(graph, data_in1, compute_S2, track = false, invalidate_cache = false)
|
||||
insert_edge!(graph, data_in2, compute_S2, track = false, invalidate_cache = false)
|
||||
|
||||
insert_edge!(graph, compute_S2, data_S2; track=false, invalidate_cache=false)
|
||||
insert_edge!(graph, compute_S2, data_S2, track = false, invalidate_cache = false)
|
||||
|
||||
insert_edge!(graph, data_S2, sum_node; track=false, invalidate_cache=false)
|
||||
insert_edge!(graph, data_S2, sum_node, track = false, invalidate_cache = false)
|
||||
add_child!(task(sum_node))
|
||||
end
|
||||
|
||||
|
@@ -45,9 +45,9 @@ The [`FeynmanTie`](@ref) represents the final inner edge of the diagram.
|
||||
"""
|
||||
struct FeynmanDiagram
|
||||
vertices::Vector{Set{FeynmanVertex}}
|
||||
tie::Ref{Union{FeynmanTie,Missing}}
|
||||
tie::Ref{Union{FeynmanTie, Missing}}
|
||||
particles::Vector{FeynmanParticle}
|
||||
type_ids::Dict{Type,Int64} # lut for number of used ids for a particle type
|
||||
type_ids::Dict{Type, Int64} # lut for number of used ids for a particle type
|
||||
end
|
||||
|
||||
"""
|
||||
@@ -69,7 +69,7 @@ function FeynmanDiagram(pd::QEDProcessDescription)
|
||||
push!(parts, FeynmanParticle(type, i))
|
||||
end
|
||||
end
|
||||
ids = Dict{Type,Int64}()
|
||||
ids = Dict{Type, Int64}()
|
||||
for t in types(QEDModel())
|
||||
if (isincoming(t))
|
||||
ids[t] = get(pd.inParticles, t, 0)
|
||||
@@ -83,17 +83,13 @@ end
|
||||
|
||||
function particle_after_tie(p::FeynmanParticle, t::FeynmanTie)
|
||||
if p == t.in1 || p == t.in2
|
||||
return FeynmanParticle(FermionStateful{Incoming,SpinUp}, -1) # placeholder particle and id for tied particles
|
||||
return FeynmanParticle(FermionStateful{Incoming, SpinUp}, -1) # placeholder particle and id for tied particles
|
||||
end
|
||||
return p
|
||||
end
|
||||
|
||||
function vertex_after_tie(v::FeynmanVertex, t::FeynmanTie)
|
||||
return FeynmanVertex(
|
||||
particle_after_tie(v.in1, t),
|
||||
particle_after_tie(v.in2, t),
|
||||
particle_after_tie(v.out, t),
|
||||
)
|
||||
return FeynmanVertex(particle_after_tie(v.in1, t), particle_after_tie(v.in2, t), particle_after_tie(v.out, t))
|
||||
end
|
||||
|
||||
function vertex_after_tie(v::FeynmanVertex, t::Missing)
|
||||
@@ -108,9 +104,7 @@ function vertex_set_after_tie(vs::Set{FeynmanVertex}, t::Missing)
|
||||
return vs
|
||||
end
|
||||
|
||||
function vertex_set_after_tie(
|
||||
vs::Set{FeynmanVertex}, t1::Union{FeynmanTie,Missing}, t2::Union{FeynmanTie,Missing}
|
||||
)
|
||||
function vertex_set_after_tie(vs::Set{FeynmanVertex}, t1::Union{FeynmanTie, Missing}, t2::Union{FeynmanTie, Missing})
|
||||
return Set{FeynmanVertex}(vertex_after_tie(vertex_after_tie(v, t1), t2) for v in vs)
|
||||
end
|
||||
|
||||
@@ -144,8 +138,7 @@ function ==(t1::FeynmanTie, t2::FeynmanTie)
|
||||
end
|
||||
|
||||
function ==(d1::FeynmanDiagram, d2::FeynmanDiagram)
|
||||
if (!ismissing(d1.tie[]) && ismissing(d2.tie[])) ||
|
||||
(ismissing(d1.tie[]) && !ismissing(d2.tie[]))
|
||||
if (!ismissing(d1.tie[]) && ismissing(d2.tie[])) || (ismissing(d1.tie[]) && !ismissing(d2.tie[]))
|
||||
return false
|
||||
end
|
||||
if d1.particles != d2.particles
|
||||
@@ -157,8 +150,7 @@ function ==(d1::FeynmanDiagram, d2::FeynmanDiagram)
|
||||
|
||||
# TODO can i prove that this works?
|
||||
for (v1, v2) in zip(d1.vertices, d2.vertices)
|
||||
if vertex_set_after_tie(v1, d1.tie[], d2.tie[]) !=
|
||||
vertex_set_after_tie(v2, d1.tie[], d2.tie[])
|
||||
if vertex_set_after_tie(v1, d1.tie[], d2.tie[]) != vertex_set_after_tie(v2, d1.tie[], d2.tie[])
|
||||
return false
|
||||
end
|
||||
end
|
||||
@@ -170,11 +162,8 @@ function ==(d1::FeynmanDiagram, d2::FeynmanDiagram)
|
||||
)=#
|
||||
end
|
||||
|
||||
function copy(fd::FeynmanDiagram)
|
||||
return FeynmanDiagram(
|
||||
deepcopy(fd.vertices), copy(fd.tie[]), deepcopy(fd.particles), copy(fd.type_ids)
|
||||
)
|
||||
end
|
||||
copy(fd::FeynmanDiagram) =
|
||||
FeynmanDiagram(deepcopy(fd.vertices), copy(fd.tie[]), deepcopy(fd.particles), copy(fd.type_ids))
|
||||
|
||||
"""
|
||||
id_for_type(d::FeynmanDiagram, t::Type{<:QEDParticle})
|
||||
@@ -240,7 +229,7 @@ end
|
||||
|
||||
Return a vector of the particles after applying the vertices and tie of the diagram up to the given level. If no level is given, apply all. The tie comes last and is its own "level".
|
||||
"""
|
||||
function get_particles(fd::FeynmanDiagram, level::Int=-1)
|
||||
function get_particles(fd::FeynmanDiagram, level::Int = -1)
|
||||
if level == -1
|
||||
level = length(fd.vertices) + 1
|
||||
end
|
||||
@@ -376,14 +365,8 @@ function possible_vertices(fd::FeynmanDiagram)
|
||||
p1 = particles[i]
|
||||
p2 = particles[j]
|
||||
if (caninteract(p1.particle, p2.particle))
|
||||
interaction_res = propagation_result(
|
||||
interaction_result(p1.particle, p2.particle)
|
||||
)
|
||||
v = FeynmanVertex(
|
||||
p1,
|
||||
p2,
|
||||
FeynmanParticle(interaction_res, id_for_type(fd, interaction_res)),
|
||||
)
|
||||
interaction_res = propagation_result(interaction_result(p1.particle, p2.particle))
|
||||
v = FeynmanVertex(p1, p2, FeynmanParticle(interaction_res, id_for_type(fd, interaction_res)))
|
||||
#@assert !(v.out in particles) "$v is in $fd"
|
||||
if !can_apply_vertex(fully_generated_particles, v)
|
||||
continue
|
||||
@@ -462,12 +445,12 @@ end
|
||||
Returns true iff the given feynman diagram is an (empty) diagram of a compton process like ke->k^ne
|
||||
"""
|
||||
function is_compton(fd::FeynmanDiagram)
|
||||
return fd.type_ids[FermionStateful{Incoming}] == 1 &&
|
||||
fd.type_ids[FermionStateful{Outgoing}] == 1 &&
|
||||
fd.type_ids[AntiFermionStateful{Incoming}] == 0 &&
|
||||
fd.type_ids[AntiFermionStateful{Outgoing}] == 0 &&
|
||||
fd.type_ids[PhotonStateful{Incoming}] >= 1 &&
|
||||
fd.type_ids[PhotonStateful{Outgoing}] >= 1
|
||||
return fd.type_ids[FermionStateful{Incoming, SpinUp}] == 1 &&
|
||||
fd.type_ids[FermionStateful{Outgoing, SpinUp}] == 1 &&
|
||||
fd.type_ids[AntiFermionStateful{Incoming, SpinUp}] == 0 &&
|
||||
fd.type_ids[AntiFermionStateful{Outgoing, SpinUp}] == 0 &&
|
||||
fd.type_ids[PhotonStateful{Incoming, PolX}] >= 1 &&
|
||||
fd.type_ids[PhotonStateful{Outgoing, PolX}] >= 1
|
||||
end
|
||||
|
||||
"""
|
||||
@@ -477,19 +460,19 @@ Helper function for [`gen_compton_diagrams`](@Ref). Generates a single diagram f
|
||||
"""
|
||||
function gen_compton_diagram_from_order(order::Vector{Int}, inFerm, outFerm, n::Int, m::Int)
|
||||
photons = vcat(
|
||||
[FeynmanParticle(PhotonStateful{Incoming,PolX}, i) for i in 1:n],
|
||||
[FeynmanParticle(PhotonStateful{Outgoing,PolX}, i) for i in 1:m],
|
||||
[FeynmanParticle(PhotonStateful{Incoming, PolX}, i) for i in 1:n],
|
||||
[FeynmanParticle(PhotonStateful{Outgoing, PolX}, i) for i in 1:m],
|
||||
)
|
||||
|
||||
new_diagram = FeynmanDiagram(
|
||||
[],
|
||||
missing,
|
||||
[inFerm, outFerm, photons...],
|
||||
Dict{Type,Int64}(
|
||||
FermionStateful{Incoming,SpinUp} => 1,
|
||||
FermionStateful{Outgoing,SpinUp} => 1,
|
||||
PhotonStateful{Incoming,PolX} => n,
|
||||
PhotonStateful{Outgoing,PolX} => m,
|
||||
Dict{Type, Int64}(
|
||||
FermionStateful{Incoming, SpinUp} => 1,
|
||||
FermionStateful{Outgoing, SpinUp} => 1,
|
||||
PhotonStateful{Incoming, PolX} => n,
|
||||
PhotonStateful{Outgoing, PolX} => m,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -501,9 +484,9 @@ function gen_compton_diagram_from_order(order::Vector{Int}, inFerm, outFerm, n::
|
||||
while left_index <= right_index
|
||||
# left side
|
||||
v_left = FeynmanVertex(
|
||||
FeynmanParticle(FermionStateful{Incoming,SpinUp}, iterations),
|
||||
FeynmanParticle(FermionStateful{Incoming, SpinUp}, iterations),
|
||||
photons[order[left_index]],
|
||||
FeynmanParticle(FermionStateful{Incoming,SpinUp}, iterations + 1),
|
||||
FeynmanParticle(FermionStateful{Incoming, SpinUp}, iterations + 1),
|
||||
)
|
||||
left_index += 1
|
||||
add_vertex!(new_diagram, v_left)
|
||||
@@ -514,9 +497,9 @@ function gen_compton_diagram_from_order(order::Vector{Int}, inFerm, outFerm, n::
|
||||
|
||||
# right side
|
||||
v_right = FeynmanVertex(
|
||||
FeynmanParticle(FermionStateful{Outgoing,SpinUp}, iterations),
|
||||
FeynmanParticle(FermionStateful{Outgoing, SpinUp}, iterations),
|
||||
photons[order[right_index]],
|
||||
FeynmanParticle(FermionStateful{Outgoing,SpinUp}, iterations + 1),
|
||||
FeynmanParticle(FermionStateful{Outgoing, SpinUp}, iterations + 1),
|
||||
)
|
||||
right_index -= 1
|
||||
add_vertex!(new_diagram, v_right)
|
||||
@@ -529,28 +512,27 @@ function gen_compton_diagram_from_order(order::Vector{Int}, inFerm, outFerm, n::
|
||||
return new_diagram
|
||||
end
|
||||
|
||||
|
||||
"""
|
||||
gen_compton_diagram_from_order_one_side(order::Vector{Int}, inFerm, outFerm, n::Int, m::Int)
|
||||
|
||||
Helper function for [`gen_compton_diagrams`](@Ref). Generates a single diagram for the given order and n input and m output photons.
|
||||
"""
|
||||
function gen_compton_diagram_from_order_one_side(
|
||||
order::Vector{Int}, inFerm, outFerm, n::Int, m::Int
|
||||
)
|
||||
function gen_compton_diagram_from_order_one_side(order::Vector{Int}, inFerm, outFerm, n::Int, m::Int)
|
||||
photons = vcat(
|
||||
[FeynmanParticle(PhotonStateful{Incoming,PolX}, i) for i in 1:n],
|
||||
[FeynmanParticle(PhotonStateful{Outgoing,PolX}, i) for i in 1:m],
|
||||
[FeynmanParticle(PhotonStateful{Incoming, PolX}, i) for i in 1:n],
|
||||
[FeynmanParticle(PhotonStateful{Outgoing, PolX}, i) for i in 1:m],
|
||||
)
|
||||
|
||||
new_diagram = FeynmanDiagram(
|
||||
[],
|
||||
missing,
|
||||
[inFerm, outFerm, photons...],
|
||||
Dict{Type,Int64}(
|
||||
FermionStateful{Incoming,SpinUp} => 1,
|
||||
FermionStateful{Outgoing,SpinUp} => 1,
|
||||
PhotonStateful{Incoming,PolX} => n,
|
||||
PhotonStateful{Outgoing,PolX} => m,
|
||||
Dict{Type, Int64}(
|
||||
FermionStateful{Incoming, SpinUp} => 1,
|
||||
FermionStateful{Outgoing, SpinUp} => 1,
|
||||
PhotonStateful{Incoming, PolX} => n,
|
||||
PhotonStateful{Outgoing, PolX} => m,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -562,9 +544,9 @@ function gen_compton_diagram_from_order_one_side(
|
||||
while left_index <= right_index
|
||||
# left side
|
||||
v_left = FeynmanVertex(
|
||||
FeynmanParticle(FermionStateful{Incoming,SpinUp}, iterations),
|
||||
FeynmanParticle(FermionStateful{Incoming, SpinUp}, iterations),
|
||||
photons[order[left_index]],
|
||||
FeynmanParticle(FermionStateful{Incoming,SpinUp}, iterations + 1),
|
||||
FeynmanParticle(FermionStateful{Incoming, SpinUp}, iterations + 1),
|
||||
)
|
||||
left_index += 1
|
||||
add_vertex!(new_diagram, v_left)
|
||||
@@ -577,9 +559,9 @@ function gen_compton_diagram_from_order_one_side(
|
||||
if (iterations == 1)
|
||||
# right side
|
||||
v_right = FeynmanVertex(
|
||||
FeynmanParticle(FermionStateful{Outgoing,SpinUp}, iterations),
|
||||
FeynmanParticle(FermionStateful{Outgoing, SpinUp}, iterations),
|
||||
photons[order[right_index]],
|
||||
FeynmanParticle(FermionStateful{Outgoing,SpinUp}, iterations + 1),
|
||||
FeynmanParticle(FermionStateful{Outgoing, SpinUp}, iterations + 1),
|
||||
)
|
||||
right_index -= 1
|
||||
add_vertex!(new_diagram, v_right)
|
||||
@@ -594,45 +576,41 @@ function gen_compton_diagram_from_order_one_side(
|
||||
return new_diagram
|
||||
end
|
||||
|
||||
|
||||
"""
|
||||
gen_compton_diagrams(n::Int, m::Int)
|
||||
|
||||
Special case diagram generation for Compton processes, i.e., processes of the form k^ne->k^me
|
||||
"""
|
||||
function gen_compton_diagrams(n::Int, m::Int)
|
||||
inFerm = FeynmanParticle(FermionStateful{Incoming,SpinUp}, 1)
|
||||
outFerm = FeynmanParticle(FermionStateful{Outgoing,SpinUp}, 1)
|
||||
inFerm = FeynmanParticle(FermionStateful{Incoming, SpinUp}, 1)
|
||||
outFerm = FeynmanParticle(FermionStateful{Outgoing, SpinUp}, 1)
|
||||
|
||||
perms = [permutations([i for i in 1:(n + m)])...]
|
||||
|
||||
diagrams = [Vector{FeynmanDiagram}() for i in 1:nthreads()]
|
||||
@threads for order in perms
|
||||
push!(
|
||||
diagrams[threadid()],
|
||||
gen_compton_diagram_from_order(order, inFerm, outFerm, n, m),
|
||||
)
|
||||
push!(diagrams[threadid()], gen_compton_diagram_from_order(order, inFerm, outFerm, n, m))
|
||||
end
|
||||
|
||||
return vcat(diagrams...)
|
||||
end
|
||||
|
||||
|
||||
"""
|
||||
gen_compton_diagrams_one_side(n::Int, m::Int)
|
||||
|
||||
Special case diagram generation for Compton processes, i.e., processes of the form k^ne->k^me, but generating from one end, yielding larger diagrams
|
||||
"""
|
||||
function gen_compton_diagrams_one_side(n::Int, m::Int)
|
||||
inFerm = FeynmanParticle(FermionStateful{Incoming,SpinUp}, 1)
|
||||
outFerm = FeynmanParticle(FermionStateful{Outgoing,SpinUp}, 1)
|
||||
inFerm = FeynmanParticle(FermionStateful{Incoming, SpinUp}, 1)
|
||||
outFerm = FeynmanParticle(FermionStateful{Outgoing, SpinUp}, 1)
|
||||
|
||||
perms = [permutations([i for i in 1:(n + m)])...]
|
||||
|
||||
diagrams = [Vector{FeynmanDiagram}() for i in 1:nthreads()]
|
||||
@threads for order in perms
|
||||
push!(
|
||||
diagrams[threadid()],
|
||||
gen_compton_diagram_from_order_one_side(order, inFerm, outFerm, n, m),
|
||||
)
|
||||
push!(diagrams[threadid()], gen_compton_diagram_from_order_one_side(order, inFerm, outFerm, n, m))
|
||||
end
|
||||
|
||||
return vcat(diagrams...)
|
||||
@@ -646,7 +624,8 @@ From a given feynman diagram in its initial state, e.g. when created through the
|
||||
function gen_diagrams(fd::FeynmanDiagram)
|
||||
if is_compton(fd)
|
||||
return gen_compton_diagrams_one_side(
|
||||
fd.type_ids[PhotonStateful{Incoming}], fd.type_ids[PhotonStateful{Outgoing}]
|
||||
fd.type_ids[PhotonStateful{Incoming, PolX}],
|
||||
fd.type_ids[PhotonStateful{Outgoing, PolX}],
|
||||
)
|
||||
end
|
||||
|
||||
|
@@ -21,7 +21,7 @@ Its template parameter specifies the particle's direction.
|
||||
|
||||
The concrete types contain singletons of the types that they are, like `Photon` and `Electron` from QEDbase, and their state descriptions.
|
||||
"""
|
||||
abstract type QEDParticle{Direction<:ParticleDirection} <: AbstractParticle end
|
||||
abstract type QEDParticle{Direction <: ParticleDirection} <: AbstractParticle end
|
||||
|
||||
"""
|
||||
QEDProcessDescription <: AbstractProcessDescription
|
||||
@@ -31,16 +31,16 @@ A description of a process in the QED-Model. Contains the input and output parti
|
||||
See also: [`in_particles`](@ref), [`out_particles`](@ref), [`parse_process`](@ref)
|
||||
"""
|
||||
struct QEDProcessDescription <: AbstractProcessDescription
|
||||
inParticles::Dict{Type{<:QEDParticle{Incoming}},Int}
|
||||
outParticles::Dict{Type{<:QEDParticle{Outgoing}},Int}
|
||||
inParticles::Dict{Type{<:QEDParticle{Incoming}}, Int}
|
||||
outParticles::Dict{Type{<:QEDParticle{Outgoing}}, Int}
|
||||
end
|
||||
|
||||
QEDParticleValue{ParticleType<:QEDParticle} = Union{
|
||||
ParticleValue{ParticleType,BiSpinor},
|
||||
ParticleValue{ParticleType,AdjointBiSpinor},
|
||||
ParticleValue{ParticleType,DiracMatrix},
|
||||
ParticleValue{ParticleType,SLorentzVector{Float64}},
|
||||
ParticleValue{ParticleType,ComplexF64},
|
||||
QEDParticleValue{ParticleType <: QEDParticle} = Union{
|
||||
ParticleValue{ParticleType, BiSpinor},
|
||||
ParticleValue{ParticleType, AdjointBiSpinor},
|
||||
ParticleValue{ParticleType, DiracMatrix},
|
||||
ParticleValue{ParticleType, SLorentzVector{Float64}},
|
||||
ParticleValue{ParticleType, ComplexF64},
|
||||
}
|
||||
|
||||
"""
|
||||
@@ -48,158 +48,84 @@ QEDParticleValue{ParticleType<:QEDParticle} = Union{
|
||||
|
||||
A photon of the [`QEDModel`](@ref) with its state.
|
||||
"""
|
||||
struct PhotonStateful{Direction<:ParticleDirection,Pol<:AbstractDefinitePolarization} <:
|
||||
QEDParticle{Direction}
|
||||
struct PhotonStateful{Direction <: ParticleDirection, Pol <: AbstractDefinitePolarization} <: QEDParticle{Direction}
|
||||
momentum::SFourMomentum
|
||||
|
||||
function PhotonStateful{Direction,Pol}(
|
||||
mom::SFourMomentum
|
||||
) where {Direction<:ParticleDirection,Pol<:AbstractDefinitePolarization}
|
||||
return new{Direction,Pol}(mom)
|
||||
end
|
||||
|
||||
function PhotonStateful{Direction}(
|
||||
mom::SFourMomentum
|
||||
) where {Direction<:ParticleDirection}
|
||||
return new{Direction,AbstractDefinitePolarization}(mom)
|
||||
end
|
||||
|
||||
function PhotonStateful{Direction}(
|
||||
mom::SFourMomentum, pol::AbstractDefinitePolarization
|
||||
) where {Direction<:ParticleDirection}
|
||||
return new{Direction,typeof(pol)}(mom)
|
||||
end
|
||||
|
||||
function PhotonStateful{Dir,Pol}(ph::PhotonStateful) where {Dir,Pol}
|
||||
return new{Dir,Pol}(ph.momentum)
|
||||
end
|
||||
end
|
||||
|
||||
PhotonStateful{Direction}(mom::SFourMomentum) where {Direction <: ParticleDirection} =
|
||||
PhotonStateful{Direction, PolX}(mom)
|
||||
|
||||
PhotonStateful{Dir, Pol}(ph::PhotonStateful) where {Dir, Pol} = PhotonStateful{Dir, Pol}(ph.momentum)
|
||||
|
||||
"""
|
||||
FermionStateful <: QEDParticle
|
||||
|
||||
A fermion of the [`QEDModel`](@ref) with its state.
|
||||
"""
|
||||
struct FermionStateful{Direction<:ParticleDirection,Spin<:AbstractDefiniteSpin} <:
|
||||
QEDParticle{Direction}
|
||||
struct FermionStateful{Direction <: ParticleDirection, Spin <: AbstractDefiniteSpin} <: QEDParticle{Direction}
|
||||
momentum::SFourMomentum
|
||||
# TODO: mass for electron/muon/tauon representation?
|
||||
|
||||
function FermionStateful{Direction,Spin}(
|
||||
mom::SFourMomentum
|
||||
) where {Direction<:ParticleDirection,Spin<:AbstractDefiniteSpin}
|
||||
return new{Direction,Spin}(mom)
|
||||
end
|
||||
|
||||
function FermionStateful{Direction}(
|
||||
mom::SFourMomentum
|
||||
) where {Direction<:ParticleDirection}
|
||||
return new{Direction,AbstractDefiniteSpin}(mom)
|
||||
end
|
||||
|
||||
function FermionStateful{Direction}(
|
||||
mom::SFourMomentum, spin::AbstractDefiniteSpin
|
||||
) where {Direction<:ParticleDirection}
|
||||
return new{Direction,typeof(spin)}(mom)
|
||||
end
|
||||
|
||||
function FermionStateful{Dir,Spin}(f::FermionStateful) where {Dir,Spin}
|
||||
return new{Dir,Spin}(f.momentum)
|
||||
end
|
||||
end
|
||||
|
||||
FermionStateful{Direction}(mom::SFourMomentum) where {Direction <: ParticleDirection} =
|
||||
FermionStateful{Direction, SpinUp}(mom)
|
||||
|
||||
FermionStateful{Dir, Spin}(f::FermionStateful) where {Dir, Spin} = FermionStateful{Dir, Spin}(f.momentum)
|
||||
|
||||
"""
|
||||
AntiFermionStateful <: QEDParticle
|
||||
|
||||
An anti-fermion of the [`QEDModel`](@ref) with its state.
|
||||
"""
|
||||
struct AntiFermionStateful{Direction<:ParticleDirection,Spin<:AbstractDefiniteSpin} <:
|
||||
QEDParticle{Direction}
|
||||
struct AntiFermionStateful{Direction <: ParticleDirection, Spin <: AbstractDefiniteSpin} <: QEDParticle{Direction}
|
||||
momentum::SFourMomentum
|
||||
# TODO: mass for electron/muon/tauon representation?
|
||||
|
||||
function AntiFermionStateful{Direction,Spin}(
|
||||
mom::SFourMomentum
|
||||
) where {Direction<:ParticleDirection,Spin<:AbstractDefiniteSpin}
|
||||
return new{Direction,Spin}(mom)
|
||||
end
|
||||
|
||||
function AntiFermionStateful{Direction}(
|
||||
mom::SFourMomentum
|
||||
) where {Direction<:ParticleDirection}
|
||||
return new{Direction,AbstractDefiniteSpin}(mom)
|
||||
end
|
||||
|
||||
function AntiFermionStateful{Direction}(
|
||||
mom::SFourMomentum, spin::AbstractDefiniteSpin
|
||||
) where {Direction<:ParticleDirection}
|
||||
return new{Direction,typeof(spin)}(mom)
|
||||
end
|
||||
|
||||
function AntiFermionStateful{Dir,Spin}(f::AntiFermionStateful) where {Dir,Spin}
|
||||
return new{Dir,Spin}(f.momentum)
|
||||
end
|
||||
end
|
||||
|
||||
AntiFermionStateful{Direction}(mom::SFourMomentum) where {Direction <: ParticleDirection} =
|
||||
AntiFermionStateful{Direction, SpinUp}(mom)
|
||||
|
||||
AntiFermionStateful{Dir, Spin}(f::AntiFermionStateful) where {Dir, Spin} = AntiFermionStateful{Dir, Spin}(f.momentum)
|
||||
|
||||
"""
|
||||
interaction_result(t1::Type{T1}, t2::Type{T2}) where {T1 <: QEDParticle, T2 <: QEDParticle}
|
||||
|
||||
For two given particle types that can interact, return the third.
|
||||
"""
|
||||
function interaction_result(
|
||||
t1::Type{T1}, t2::Type{T2}
|
||||
) where {T1<:QEDParticle,T2<:QEDParticle}
|
||||
function interaction_result(t1::Type{T1}, t2::Type{T2}) where {T1 <: QEDParticle, T2 <: QEDParticle}
|
||||
@assert false "Invalid interaction between particles of types $t1 and $t2"
|
||||
end
|
||||
|
||||
function interaction_result(
|
||||
::Type{FermionStateful{Incoming,Spin1}}, ::Type{FermionStateful{Outgoing,Spin2}}
|
||||
) where {Spin1,Spin2}
|
||||
return PhotonStateful{Incoming,PolX}
|
||||
end
|
||||
function interaction_result(
|
||||
::Type{FermionStateful{Incoming,Spin1}}, ::Type{AntiFermionStateful{Incoming,Spin2}}
|
||||
) where {Spin1,Spin2}
|
||||
return PhotonStateful{Incoming,PolX}
|
||||
end
|
||||
function interaction_result(
|
||||
::Type{FermionStateful{Incoming,Spin1}}, ::Type{<:PhotonStateful}
|
||||
) where {Spin1}
|
||||
return FermionStateful{Outgoing,SpinUp}
|
||||
end
|
||||
interaction_result(
|
||||
::Type{FermionStateful{Incoming, Spin1}},
|
||||
::Type{FermionStateful{Outgoing, Spin2}},
|
||||
) where {Spin1, Spin2} = PhotonStateful{Incoming, PolX}
|
||||
interaction_result(
|
||||
::Type{FermionStateful{Incoming, Spin1}},
|
||||
::Type{AntiFermionStateful{Incoming, Spin2}},
|
||||
) where {Spin1, Spin2} = PhotonStateful{Incoming, PolX}
|
||||
interaction_result(::Type{FermionStateful{Incoming, Spin1}}, ::Type{<:PhotonStateful}) where {Spin1} =
|
||||
FermionStateful{Outgoing, SpinUp}
|
||||
|
||||
function interaction_result(
|
||||
::Type{FermionStateful{Outgoing,Spin1}}, ::Type{FermionStateful{Incoming,Spin2}}
|
||||
) where {Spin1,Spin2}
|
||||
return PhotonStateful{Incoming,PolX}
|
||||
end
|
||||
function interaction_result(
|
||||
::Type{FermionStateful{Outgoing,Spin1}}, ::Type{AntiFermionStateful{Outgoing,Spin2}}
|
||||
) where {Spin1,Spin2}
|
||||
return PhotonStateful{Incoming,PolX}
|
||||
end
|
||||
function interaction_result(
|
||||
::Type{FermionStateful{Outgoing,Spin1}}, ::Type{<:PhotonStateful}
|
||||
) where {Spin1}
|
||||
return FermionStateful{Incoming,SpinUp}
|
||||
end
|
||||
interaction_result(
|
||||
::Type{FermionStateful{Outgoing, Spin1}},
|
||||
::Type{FermionStateful{Incoming, Spin2}},
|
||||
) where {Spin1, Spin2} = PhotonStateful{Incoming, PolX}
|
||||
interaction_result(
|
||||
::Type{FermionStateful{Outgoing, Spin1}},
|
||||
::Type{AntiFermionStateful{Outgoing, Spin2}},
|
||||
) where {Spin1, Spin2} = PhotonStateful{Incoming, PolX}
|
||||
interaction_result(::Type{FermionStateful{Outgoing, Spin1}}, ::Type{<:PhotonStateful}) where {Spin1} =
|
||||
FermionStateful{Incoming, SpinUp}
|
||||
|
||||
# antifermion mirror
|
||||
function interaction_result(
|
||||
::Type{AntiFermionStateful{Incoming,Spin}}, t2::Type{<:QEDParticle}
|
||||
) where {Spin}
|
||||
return interaction_result(FermionStateful{Outgoing,Spin}, t2)
|
||||
end
|
||||
function interaction_result(
|
||||
::Type{AntiFermionStateful{Outgoing,Spin}}, t2::Type{<:QEDParticle}
|
||||
) where {Spin}
|
||||
return interaction_result(FermionStateful{Incoming,Spin}, t2)
|
||||
end
|
||||
interaction_result(::Type{AntiFermionStateful{Incoming, Spin}}, t2::Type{<:QEDParticle}) where {Spin} =
|
||||
interaction_result(FermionStateful{Outgoing, Spin}, t2)
|
||||
interaction_result(::Type{AntiFermionStateful{Outgoing, Spin}}, t2::Type{<:QEDParticle}) where {Spin} =
|
||||
interaction_result(FermionStateful{Incoming, Spin}, t2)
|
||||
|
||||
# photon commutativity
|
||||
function interaction_result(t1::Type{<:PhotonStateful}, t2::Type{<:QEDParticle})
|
||||
return interaction_result(t2, t1)
|
||||
end
|
||||
interaction_result(t1::Type{<:PhotonStateful}, t2::Type{<:QEDParticle}) = interaction_result(t2, t1)
|
||||
|
||||
# but prevent stack overflow
|
||||
function interaction_result(t1::Type{<:PhotonStateful}, t2::Type{<:PhotonStateful})
|
||||
@@ -211,34 +137,18 @@ end
|
||||
|
||||
Return the type of the inverted direction. E.g.
|
||||
"""
|
||||
propagation_result(
|
||||
::Type{FermionStateful{Incoming,Spin}}
|
||||
) where {Spin<:AbstractDefiniteSpin} = FermionStateful{Outgoing,Spin}
|
||||
function propagation_result(
|
||||
::Type{FermionStateful{Outgoing,Spin}}
|
||||
) where {Spin<:AbstractDefiniteSpin}
|
||||
return FermionStateful{Incoming,Spin}
|
||||
end
|
||||
function propagation_result(
|
||||
::Type{AntiFermionStateful{Incoming,Spin}}
|
||||
) where {Spin<:AbstractDefiniteSpin}
|
||||
return AntiFermionStateful{Outgoing,Spin}
|
||||
end
|
||||
function propagation_result(
|
||||
::Type{AntiFermionStateful{Outgoing,Spin}}
|
||||
) where {Spin<:AbstractDefiniteSpin}
|
||||
return AntiFermionStateful{Incoming,Spin}
|
||||
end
|
||||
function propagation_result(
|
||||
::Type{PhotonStateful{Incoming,Pol}}
|
||||
) where {Pol<:AbstractDefinitePolarization}
|
||||
return PhotonStateful{Outgoing,Pol}
|
||||
end
|
||||
function propagation_result(
|
||||
::Type{PhotonStateful{Outgoing,Pol}}
|
||||
) where {Pol<:AbstractDefinitePolarization}
|
||||
return PhotonStateful{Incoming,Pol}
|
||||
end
|
||||
propagation_result(::Type{FermionStateful{Incoming, Spin}}) where {Spin <: AbstractDefiniteSpin} =
|
||||
FermionStateful{Outgoing, Spin}
|
||||
propagation_result(::Type{FermionStateful{Outgoing, Spin}}) where {Spin <: AbstractDefiniteSpin} =
|
||||
FermionStateful{Incoming, Spin}
|
||||
propagation_result(::Type{AntiFermionStateful{Incoming, Spin}}) where {Spin <: AbstractDefiniteSpin} =
|
||||
AntiFermionStateful{Outgoing, Spin}
|
||||
propagation_result(::Type{AntiFermionStateful{Outgoing, Spin}}) where {Spin <: AbstractDefiniteSpin} =
|
||||
AntiFermionStateful{Incoming, Spin}
|
||||
propagation_result(::Type{PhotonStateful{Incoming, Pol}}) where {Pol <: AbstractDefinitePolarization} =
|
||||
PhotonStateful{Outgoing, Pol}
|
||||
propagation_result(::Type{PhotonStateful{Outgoing, Pol}}) where {Pol <: AbstractDefinitePolarization} =
|
||||
PhotonStateful{Incoming, Pol}
|
||||
|
||||
"""
|
||||
types(::QEDModel)
|
||||
@@ -247,12 +157,12 @@ Return a Vector of the possible types of particle in the [`QEDModel`](@ref).
|
||||
"""
|
||||
function types(::QEDModel)
|
||||
return [
|
||||
PhotonStateful{Incoming},
|
||||
PhotonStateful{Outgoing},
|
||||
FermionStateful{Incoming},
|
||||
FermionStateful{Outgoing},
|
||||
AntiFermionStateful{Incoming},
|
||||
AntiFermionStateful{Outgoing},
|
||||
PhotonStateful{Incoming, PolX},
|
||||
PhotonStateful{Outgoing, PolX},
|
||||
FermionStateful{Incoming, SpinUp},
|
||||
FermionStateful{Outgoing, SpinUp},
|
||||
AntiFermionStateful{Incoming, SpinUp},
|
||||
AntiFermionStateful{Outgoing, SpinUp},
|
||||
]
|
||||
end
|
||||
|
||||
@@ -279,13 +189,13 @@ function String(::Type{<:AntiFermionStateful})
|
||||
return "p"
|
||||
end
|
||||
|
||||
function unique_name(::Type{PhotonStateful{Dir,Pol}}) where {Dir,Pol}
|
||||
function unique_name(::Type{PhotonStateful{Dir, Pol}}) where {Dir, Pol}
|
||||
return String(PhotonStateful) * String(Dir) * String(Pol)
|
||||
end
|
||||
function unique_name(::Type{FermionStateful{Dir,Spin}}) where {Dir,Spin}
|
||||
function unique_name(::Type{FermionStateful{Dir, Spin}}) where {Dir, Spin}
|
||||
return String(FermionStateful) * String(Dir) * String(Spin)
|
||||
end
|
||||
function unique_name(::Type{AntiFermionStateful{Dir,Spin}}) where {Dir,Spin}
|
||||
function unique_name(::Type{AntiFermionStateful{Dir, Spin}}) where {Dir, Spin}
|
||||
return String(AntiFermionStateful) * String(Dir) * String(Spin)
|
||||
end
|
||||
|
||||
@@ -293,52 +203,27 @@ end
|
||||
@inline particle(::FermionStateful) = Electron()
|
||||
@inline particle(::AntiFermionStateful) = Positron()
|
||||
|
||||
@inline particle(::Type{<:PhotonStateful}) = Photon()
|
||||
@inline particle(::Type{<:FermionStateful}) = Electron()
|
||||
@inline particle(::Type{<:AntiFermionStateful}) = Positron()
|
||||
|
||||
@inline momentum(p::PhotonStateful)::SFourMomentum = p.momentum
|
||||
@inline momentum(p::FermionStateful)::SFourMomentum = p.momentum
|
||||
@inline momentum(p::AntiFermionStateful)::SFourMomentum = p.momentum
|
||||
|
||||
@inline spin_or_pol(
|
||||
p::PhotonStateful{Dir,Pol}
|
||||
) where {Dir,Pol<:AbstractDefinitePolarization} = Pol()
|
||||
@inline spin_or_pol(p::FermionStateful{Dir,Spin}) where {Dir,Spin<:AbstractDefiniteSpin} =
|
||||
Spin()
|
||||
@inline spin_or_pol(
|
||||
p::AntiFermionStateful{Dir,Spin}
|
||||
) where {Dir,Spin<:AbstractDefiniteSpin} = Spin()
|
||||
@inline spin_or_pol(p::PhotonStateful{Dir, Pol}) where {Dir, Pol <: AbstractDefinitePolarization} = Pol()
|
||||
@inline spin_or_pol(p::FermionStateful{Dir, Spin}) where {Dir, Spin <: AbstractDefiniteSpin} = Spin()
|
||||
@inline spin_or_pol(p::AntiFermionStateful{Dir, Spin}) where {Dir, Spin <: AbstractDefiniteSpin} = Spin()
|
||||
|
||||
@inline direction(
|
||||
::Type{P}
|
||||
) where {
|
||||
P<:Union{
|
||||
FermionStateful{Incoming},AntiFermionStateful{Incoming},PhotonStateful{Incoming}
|
||||
},
|
||||
} = Incoming()
|
||||
::Type{P},
|
||||
) where {P <: Union{FermionStateful{Incoming}, AntiFermionStateful{Incoming}, PhotonStateful{Incoming}}} = Incoming()
|
||||
@inline direction(
|
||||
::Type{P}
|
||||
) where {
|
||||
P<:Union{
|
||||
FermionStateful{Outgoing},AntiFermionStateful{Outgoing},PhotonStateful{Outgoing}
|
||||
},
|
||||
} = Outgoing()
|
||||
::Type{P},
|
||||
) where {P <: Union{FermionStateful{Outgoing}, AntiFermionStateful{Outgoing}, PhotonStateful{Outgoing}}} = Outgoing()
|
||||
|
||||
@inline direction(
|
||||
::P
|
||||
) where {
|
||||
P<:Union{
|
||||
FermionStateful{Incoming},AntiFermionStateful{Incoming},PhotonStateful{Incoming}
|
||||
},
|
||||
} = Incoming()
|
||||
::P,
|
||||
) where {P <: Union{FermionStateful{Incoming}, AntiFermionStateful{Incoming}, PhotonStateful{Incoming}}} = Incoming()
|
||||
@inline direction(
|
||||
::P
|
||||
) where {
|
||||
P<:Union{
|
||||
FermionStateful{Outgoing},AntiFermionStateful{Outgoing},PhotonStateful{Outgoing}
|
||||
},
|
||||
} = Outgoing()
|
||||
::P,
|
||||
) where {P <: Union{FermionStateful{Outgoing}, AntiFermionStateful{Outgoing}, PhotonStateful{Outgoing}}} = Outgoing()
|
||||
|
||||
@inline isincoming(::QEDParticle{Incoming}) = true
|
||||
@inline isincoming(::QEDParticle{Outgoing}) = false
|
||||
@@ -354,12 +239,13 @@ end
|
||||
@inline mass(::Type{<:AntiFermionStateful}) = 1.0
|
||||
@inline mass(::Type{<:PhotonStateful}) = 0.0
|
||||
|
||||
@inline invert_momentum(p::FermionStateful{Dir,Spin}) where {Dir,Spin} =
|
||||
FermionStateful{Dir,Spin}(-p.momentum, p.spin)
|
||||
@inline invert_momentum(p::AntiFermionStateful{Dir,Spin}) where {Dir,Spin} =
|
||||
AntiFermionStateful{Dir,Spin}(-p.momentum, p.spin)
|
||||
@inline invert_momentum(k::PhotonStateful{Dir,Spin}) where {Dir,Spin} =
|
||||
PhotonStateful{Dir,Spin}(-k.momentum, k.polarization)
|
||||
@inline invert_momentum(p::FermionStateful{Dir, Spin}) where {Dir, Spin} =
|
||||
FermionStateful{Dir, Spin}(-p.momentum, p.spin)
|
||||
@inline invert_momentum(p::AntiFermionStateful{Dir, Spin}) where {Dir, Spin} =
|
||||
AntiFermionStateful{Dir, Spin}(-p.momentum, p.spin)
|
||||
@inline invert_momentum(k::PhotonStateful{Dir, Spin}) where {Dir, Spin} =
|
||||
PhotonStateful{Dir, Spin}(-k.momentum, k.polarization)
|
||||
|
||||
|
||||
"""
|
||||
caninteract(T1::Type{<:QEDParticle}, T2::Type{<:QEDParticle})
|
||||
@@ -390,17 +276,17 @@ end
|
||||
|
||||
function type_index_from_name(::QEDModel, name::String)
|
||||
if startswith(name, "ki")
|
||||
return (PhotonStateful{Incoming,PolX}, parse(Int, name[3:end]))
|
||||
return (PhotonStateful{Incoming, PolX}, parse(Int, name[3:end]))
|
||||
elseif startswith(name, "ko")
|
||||
return (PhotonStateful{Outgoing,PolX}, parse(Int, name[3:end]))
|
||||
return (PhotonStateful{Outgoing, PolX}, parse(Int, name[3:end]))
|
||||
elseif startswith(name, "ei")
|
||||
return (FermionStateful{Incoming,SpinUp}, parse(Int, name[3:end]))
|
||||
return (FermionStateful{Incoming, SpinUp}, parse(Int, name[3:end]))
|
||||
elseif startswith(name, "eo")
|
||||
return (FermionStateful{Outgoing,SpinUp}, parse(Int, name[3:end]))
|
||||
return (FermionStateful{Outgoing, SpinUp}, parse(Int, name[3:end]))
|
||||
elseif startswith(name, "pi")
|
||||
return (AntiFermionStateful{Incoming,SpinUp}, parse(Int, name[3:end]))
|
||||
return (AntiFermionStateful{Incoming, SpinUp}, parse(Int, name[3:end]))
|
||||
elseif startswith(name, "po")
|
||||
return (AntiFermionStateful{Outgoing,SpinUp}, parse(Int, name[3:end]))
|
||||
return (AntiFermionStateful{Outgoing, SpinUp}, parse(Int, name[3:end]))
|
||||
else
|
||||
throw("Invalid name for a particle in the QED model")
|
||||
end
|
||||
@@ -427,8 +313,8 @@ Return the factor of a vertex in a QED feynman diagram.
|
||||
return -1im * e * gamma()
|
||||
end
|
||||
|
||||
@inline function QED_inner_edge(p::QEDParticle)
|
||||
return QEDbase.propagator(particle(p), p.momentum)
|
||||
@inline function QED_inner_edge(p::QEDParticle)::DiracMatrix
|
||||
return propagator(particle(p), p.momentum)
|
||||
end
|
||||
|
||||
"""
|
||||
@@ -437,22 +323,15 @@ end
|
||||
Calculate and return a new particle from two given interacting ones at a vertex.
|
||||
"""
|
||||
function QED_conserve_momentum(
|
||||
p1::P1, p2::P2
|
||||
p1::P1,
|
||||
p2::P2,
|
||||
) where {
|
||||
Dir1<:ParticleDirection,
|
||||
Dir2<:ParticleDirection,
|
||||
SpinPol1<:AbstractSpinOrPolarization,
|
||||
SpinPol2<:AbstractSpinOrPolarization,
|
||||
P1<:Union{
|
||||
FermionStateful{Dir1,SpinPol1},
|
||||
AntiFermionStateful{Dir1,SpinPol1},
|
||||
PhotonStateful{Dir1,SpinPol1},
|
||||
},
|
||||
P2<:Union{
|
||||
FermionStateful{Dir2,SpinPol2},
|
||||
AntiFermionStateful{Dir2,SpinPol2},
|
||||
PhotonStateful{Dir2,SpinPol2},
|
||||
},
|
||||
Dir1 <: ParticleDirection,
|
||||
Dir2 <: ParticleDirection,
|
||||
SpinPol1 <: AbstractSpinOrPolarization,
|
||||
SpinPol2 <: AbstractSpinOrPolarization,
|
||||
P1 <: Union{FermionStateful{Dir1, SpinPol1}, AntiFermionStateful{Dir1, SpinPol1}, PhotonStateful{Dir1, SpinPol1}},
|
||||
P2 <: Union{FermionStateful{Dir2, SpinPol2}, AntiFermionStateful{Dir2, SpinPol2}, PhotonStateful{Dir2, SpinPol2}},
|
||||
}
|
||||
P3 = interaction_result(P1, P2)
|
||||
p1_mom = p1.momentum
|
||||
@@ -478,14 +357,14 @@ Input for a QED Process. Contains the [`QEDProcessDescription`](@ref) of the pro
|
||||
|
||||
See also: [`gen_process_input`](@ref)
|
||||
"""
|
||||
struct QEDProcessInput{N1,N2,N3,N4,N5,N6,S1,S2,S3,S4,P1,P2} <: AbstractProcessInput
|
||||
struct QEDProcessInput{N1, N2, N3, N4, N5, N6} <: AbstractProcessInput
|
||||
process::QEDProcessDescription
|
||||
inFerms::SVector{N1,FermionStateful{Incoming,S1}}
|
||||
outFerms::SVector{N2,FermionStateful{Outgoing,S2}}
|
||||
inAntiferms::SVector{N3,AntiFermionStateful{Incoming,S3}}
|
||||
outAntiferms::SVector{N4,AntiFermionStateful{Outgoing,S4}}
|
||||
inPhotons::SVector{N5,PhotonStateful{Incoming,P1}}
|
||||
outPhotons::SVector{N6,PhotonStateful{Outgoing,P2}}
|
||||
inFerms::SVector{N1, FermionStateful{Incoming, SpinUp}}
|
||||
outFerms::SVector{N2, FermionStateful{Outgoing, SpinUp}}
|
||||
inAntiferms::SVector{N3, AntiFermionStateful{Incoming, SpinUp}}
|
||||
outAntiferms::SVector{N4, AntiFermionStateful{Outgoing, SpinUp}}
|
||||
inPhotons::SVector{N5, PhotonStateful{Incoming, PolX}}
|
||||
outPhotons::SVector{N6, PhotonStateful{Outgoing, PolX}}
|
||||
end
|
||||
|
||||
"""
|
||||
@@ -500,9 +379,8 @@ function copy(process::QEDProcessDescription)
|
||||
return QEDProcessDescription(copy(process.inParticles), copy(process.outParticles))
|
||||
end
|
||||
|
||||
function ==(p1::QEDProcessDescription, p2::QEDProcessDescription)
|
||||
return p1.inParticles == p2.inParticles && p1.outParticles == p2.outParticles
|
||||
end
|
||||
==(p1::QEDProcessDescription, p2::QEDProcessDescription) =
|
||||
p1.inParticles == p2.inParticles && p1.outParticles == p2.outParticles
|
||||
|
||||
function in_particles(process::QEDProcessDescription)
|
||||
return process.inParticles
|
||||
@@ -512,9 +390,7 @@ function out_particles(process::QEDProcessDescription)
|
||||
return process.outParticles
|
||||
end
|
||||
|
||||
function get_particle(
|
||||
input::QEDProcessInput, t::Type{Particle}, n::Int
|
||||
)::Particle where {Particle}
|
||||
function get_particle(input::QEDProcessInput, t::Type{Particle}, n::Int)::Particle where {Particle}
|
||||
if (t <: FermionStateful{Incoming})
|
||||
return input.inFerms[n]
|
||||
elseif (t <: FermionStateful{Outgoing})
|
||||
|
@@ -27,8 +27,7 @@ function optimize_step!(optimizer::RandomWalkOptimizer, graph::DAG)
|
||||
# push
|
||||
|
||||
# choose one of fuse/split/reduce
|
||||
# TODO refactor fusions so they actually work
|
||||
option = rand(r, 2:3)
|
||||
option = rand(r, 1:3)
|
||||
if option == 1 && !isempty(operations.nodeFusions)
|
||||
push_operation!(graph, rand(r, collect(operations.nodeFusions)))
|
||||
return true
|
||||
|
34
src/trie.jl
34
src/trie.jl
@@ -48,7 +48,7 @@ function insert_helper!(
|
||||
trie::NodeIdTrie{NodeType},
|
||||
node::NodeType,
|
||||
depth::Int,
|
||||
) where {TaskType <: AbstractDataTask, NodeType <: DataTaskNode{TaskType}}
|
||||
) where {TaskType <: AbstractTask, NodeType <: Union{DataTaskNode{TaskType}, ComputeTaskNode{TaskType}}}
|
||||
if (length(children(node)) == depth)
|
||||
push!(trie.value, node)
|
||||
return nothing
|
||||
@@ -62,26 +62,6 @@ function insert_helper!(
|
||||
end
|
||||
return insert_helper!(trie.children[id], node, depth)
|
||||
end
|
||||
# TODO: Remove this workaround once https://github.com/JuliaLang/julia/issues/54404 is fixed in julia 1.10+
|
||||
function insert_helper!(
|
||||
trie::NodeIdTrie{NodeType},
|
||||
node::NodeType,
|
||||
depth::Int,
|
||||
) where {TaskType <: AbstractComputeTask, NodeType <: ComputeTaskNode{TaskType}}
|
||||
if (length(children(node)) == depth)
|
||||
push!(trie.value, node)
|
||||
return nothing
|
||||
end
|
||||
|
||||
depth = depth + 1
|
||||
id = node.children[depth].id
|
||||
|
||||
if (!haskey(trie.children, id))
|
||||
trie.children[id] = NodeIdTrie{NodeType}()
|
||||
end
|
||||
return insert_helper!(trie.children[id], node, depth)
|
||||
end
|
||||
|
||||
|
||||
"""
|
||||
insert!(trie::NodeTrie, node::Node)
|
||||
@@ -91,17 +71,7 @@ Insert the given node into the trie. It's sorted by its type in the first layer,
|
||||
function insert!(
|
||||
trie::NodeTrie,
|
||||
node::NodeType,
|
||||
) where {TaskType <: AbstractDataTask, NodeType <: DataTaskNode{TaskType}}
|
||||
if (!haskey(trie.children, NodeType))
|
||||
trie.children[NodeType] = NodeIdTrie{NodeType}()
|
||||
end
|
||||
return insert_helper!(trie.children[NodeType], node, 0)
|
||||
end
|
||||
# TODO: Remove this workaround once https://github.com/JuliaLang/julia/issues/54404 is fixed in julia 1.10+
|
||||
function insert!(
|
||||
trie::NodeTrie,
|
||||
node::NodeType,
|
||||
) where {TaskType <: AbstractComputeTask, NodeType <: ComputeTaskNode{TaskType}}
|
||||
) where {TaskType <: AbstractTask, NodeType <: Union{DataTaskNode{TaskType}, ComputeTaskNode{TaskType}}}
|
||||
if (!haskey(trie.children, NodeType))
|
||||
trie.children[NodeType] = NodeIdTrie{NodeType}()
|
||||
end
|
||||
|
@@ -1,8 +1,6 @@
|
||||
using MetagraphOptimization
|
||||
using Random
|
||||
|
||||
RNG = Random.MersenneTwister(321)
|
||||
|
||||
function test_known_graph(name::String, n, fusion_test = true)
|
||||
@testset "Test $name Graph ($n)" begin
|
||||
graph = parse_dag(joinpath(@__DIR__, "..", "input", "$name.txt"), ABCModel())
|
||||
@@ -11,7 +9,7 @@ function test_known_graph(name::String, n, fusion_test = true)
|
||||
if (fusion_test)
|
||||
test_node_fusion(graph)
|
||||
end
|
||||
test_random_walk(RNG, graph, n)
|
||||
test_random_walk(graph, n)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -45,7 +43,7 @@ function test_node_fusion(g::DAG)
|
||||
end
|
||||
end
|
||||
|
||||
function test_random_walk(RNG, g::DAG, n::Int64)
|
||||
function test_random_walk(g::DAG, n::Int64)
|
||||
@testset "Test Random Walk ($n)" begin
|
||||
# the purpose here is to do "random" operations and reverse them again and validate that the graph stays the same and doesn't diverge
|
||||
reset_graph!(g)
|
||||
@@ -56,18 +54,18 @@ function test_random_walk(RNG, g::DAG, n::Int64)
|
||||
|
||||
for i in 1:n
|
||||
# choose push or pop
|
||||
if rand(RNG, Bool)
|
||||
if rand(Bool)
|
||||
# push
|
||||
opt = get_operations(g)
|
||||
|
||||
# choose one of fuse/split/reduce
|
||||
option = rand(RNG, 1:3)
|
||||
option = rand(1:3)
|
||||
if option == 1 && !isempty(opt.nodeFusions)
|
||||
push_operation!(g, rand(RNG, collect(opt.nodeFusions)))
|
||||
push_operation!(g, rand(collect(opt.nodeFusions)))
|
||||
elseif option == 2 && !isempty(opt.nodeReductions)
|
||||
push_operation!(g, rand(RNG, collect(opt.nodeReductions)))
|
||||
push_operation!(g, rand(collect(opt.nodeReductions)))
|
||||
elseif option == 3 && !isempty(opt.nodeSplits)
|
||||
push_operation!(g, rand(RNG, collect(opt.nodeSplits)))
|
||||
push_operation!(g, rand(collect(opt.nodeSplits)))
|
||||
else
|
||||
i = i - 1
|
||||
end
|
||||
@@ -89,6 +87,8 @@ function test_random_walk(RNG, g::DAG, n::Int64)
|
||||
end
|
||||
end
|
||||
|
||||
Random.seed!(0)
|
||||
|
||||
test_known_graph("AB->AB", 10000)
|
||||
test_known_graph("AB->ABBB", 10000)
|
||||
test_known_graph("AB->ABBBBB", 1000, false)
|
||||
|
@@ -9,7 +9,7 @@ import MetagraphOptimization.ABCParticle
|
||||
import MetagraphOptimization.interaction_result
|
||||
|
||||
const RTOL = sqrt(eps(Float64))
|
||||
RNG = Random.MersenneTwister(0)
|
||||
RNG = Random.default_rng()
|
||||
|
||||
function check_particle_reverse_moment(p1::SFourMomentum, p2::SFourMomentum)
|
||||
@test isapprox(abs(p1.E), abs(p2.E))
|
||||
@@ -123,8 +123,6 @@ expected_result = execute(graph, process_2_4, machine, particles_2_4)
|
||||
end
|
||||
end
|
||||
|
||||
#=
|
||||
TODO: fix precision(?) issues
|
||||
@testset "AB->ABBB after random walk" begin
|
||||
for i in 1:50
|
||||
graph = parse_dag(joinpath(@__DIR__, "..", "input", "AB->ABBB.txt"), ABCModel())
|
||||
@@ -134,7 +132,6 @@ TODO: fix precision(?) issues
|
||||
@test isapprox(execute(graph, process_2_4, machine, particles_2_4), expected_result; rtol = RTOL)
|
||||
end
|
||||
end
|
||||
=#
|
||||
|
||||
@testset "AB->AB large sum fusion" begin
|
||||
for _ in 1:20
|
||||
@@ -234,19 +231,3 @@ end
|
||||
@test isapprox(execute(graph, process_2_2, machine, particles_2_2), expected_result; rtol = RTOL)
|
||||
end
|
||||
end
|
||||
|
||||
@testset "$(process) after random walk" for process in ["ke->ke", "ke->kke", "ke->kkke"]
|
||||
process = parse_process("ke->kkke", QEDModel())
|
||||
inputs = [gen_process_input(process) for _ in 1:100]
|
||||
graph = gen_graph(process)
|
||||
gt = execute.(Ref(graph), Ref(process), Ref(machine), inputs)
|
||||
for i in 1:50
|
||||
graph = gen_graph(process)
|
||||
|
||||
optimize!(RandomWalkOptimizer(RNG), graph, 100)
|
||||
@test is_valid(graph)
|
||||
|
||||
func = get_compute_function(graph, process, machine)
|
||||
@test isapprox(func.(inputs), gt; rtol = RTOL)
|
||||
end
|
||||
end
|
||||
|
@@ -1,7 +1,7 @@
|
||||
using MetagraphOptimization
|
||||
using Random
|
||||
|
||||
RNG = Random.MersenneTwister(0)
|
||||
RNG = Random.default_rng()
|
||||
|
||||
graph = parse_dag(joinpath(@__DIR__, "..", "input", "AB->ABBB.txt"), ABCModel())
|
||||
|
||||
|
@@ -15,24 +15,24 @@ import MetagraphOptimization.QED_vertex
|
||||
|
||||
def_momentum = SFourMomentum(1.0, 0.0, 0.0, 0.0)
|
||||
|
||||
RNG = Random.MersenneTwister(0)
|
||||
RNG = Random.default_rng()
|
||||
|
||||
testparticleTypes = [
|
||||
PhotonStateful{Incoming,PolX},
|
||||
PhotonStateful{Outgoing,PolX},
|
||||
FermionStateful{Incoming,SpinUp},
|
||||
FermionStateful{Outgoing,SpinUp},
|
||||
AntiFermionStateful{Incoming,SpinUp},
|
||||
AntiFermionStateful{Outgoing,SpinUp},
|
||||
PhotonStateful{Incoming, PolX},
|
||||
PhotonStateful{Outgoing, PolX},
|
||||
FermionStateful{Incoming, SpinUp},
|
||||
FermionStateful{Outgoing, SpinUp},
|
||||
AntiFermionStateful{Incoming, SpinUp},
|
||||
AntiFermionStateful{Outgoing, SpinUp},
|
||||
]
|
||||
|
||||
testparticleTypesPropagated = [
|
||||
PhotonStateful{Outgoing,PolX},
|
||||
PhotonStateful{Incoming,PolX},
|
||||
FermionStateful{Outgoing,SpinUp},
|
||||
FermionStateful{Incoming,SpinUp},
|
||||
AntiFermionStateful{Outgoing,SpinUp},
|
||||
AntiFermionStateful{Incoming,SpinUp},
|
||||
PhotonStateful{Outgoing, PolX},
|
||||
PhotonStateful{Incoming, PolX},
|
||||
FermionStateful{Outgoing, SpinUp},
|
||||
FermionStateful{Incoming, SpinUp},
|
||||
AntiFermionStateful{Outgoing, SpinUp},
|
||||
AntiFermionStateful{Incoming, SpinUp},
|
||||
]
|
||||
|
||||
function compton_groundtruth(input::QEDProcessInput)
|
||||
@@ -57,8 +57,8 @@ function compton_groundtruth(input::QEDProcessInput)
|
||||
virt2_mom = p1.momentum + k1.momentum
|
||||
@test isapprox(p2.momentum + k2.momentum, virt2_mom)
|
||||
|
||||
s_p2_k1 = QEDbase.propagator(Electron(), virt1_mom)
|
||||
s_p1_k1 = QEDbase.propagator(Electron(), virt2_mom)
|
||||
s_p2_k1 = propagator(Electron(), virt1_mom)
|
||||
s_p1_k1 = propagator(Electron(), virt2_mom)
|
||||
|
||||
diagram1 = u_p2 * (eps_1 * QED_vertex()) * s_p2_k1 * (eps_2 * QED_vertex()) * u_p1
|
||||
diagram2 = u_p2 * (eps_2 * QED_vertex()) * s_p1_k1 * (eps_1 * QED_vertex()) * u_p1
|
||||
@@ -66,6 +66,7 @@ function compton_groundtruth(input::QEDProcessInput)
|
||||
return diagram1 + diagram2
|
||||
end
|
||||
|
||||
|
||||
@testset "Interaction Result" begin
|
||||
import MetagraphOptimization.QED_conserve_momentum
|
||||
|
||||
@@ -87,11 +88,7 @@ end
|
||||
@test issame(typeof(resultParticle), interaction_result(p1, p2))
|
||||
|
||||
totalMom = zero(SFourMomentum)
|
||||
for (p, mom) in [
|
||||
(p1, testParticle1.momentum),
|
||||
(p2, testParticle2.momentum),
|
||||
(p3, resultParticle.momentum),
|
||||
]
|
||||
for (p, mom) in [(p1, testParticle1.momentum), (p2, testParticle2.momentum), (p3, resultParticle.momentum)]
|
||||
if (typeof(direction(p)) <: Incoming)
|
||||
totalMom += mom
|
||||
else
|
||||
@@ -99,7 +96,7 @@ end
|
||||
end
|
||||
end
|
||||
|
||||
@test isapprox(totalMom, zero(SFourMomentum); atol=sqrt(eps()))
|
||||
@test isapprox(totalMom, zero(SFourMomentum); atol = sqrt(eps()))
|
||||
end
|
||||
end
|
||||
|
||||
@@ -116,63 +113,41 @@ end
|
||||
@test parse_process("ke->ke", QEDModel()) == parse_process("ek->ek", QEDModel())
|
||||
@test parse_process("ke->ke", QEDModel()) == parse_process("ke->ek", QEDModel())
|
||||
|
||||
@test parse_process("kkke->eep", QEDModel()) ==
|
||||
parse_process("kkek->epe", QEDModel())
|
||||
@test parse_process("kkke->eep", QEDModel()) == parse_process("kkek->epe", QEDModel())
|
||||
end
|
||||
|
||||
@testset "Known processes" begin
|
||||
compton_process = QEDProcessDescription(
|
||||
Dict{Type,Int}(
|
||||
PhotonStateful{Incoming,PolX} => 1, FermionStateful{Incoming,SpinUp} => 1
|
||||
),
|
||||
Dict{Type,Int}(
|
||||
PhotonStateful{Outgoing,PolX} => 1, FermionStateful{Outgoing,SpinUp} => 1
|
||||
),
|
||||
Dict{Type, Int}(PhotonStateful{Incoming, PolX} => 1, FermionStateful{Incoming, SpinUp} => 1),
|
||||
Dict{Type, Int}(PhotonStateful{Outgoing, PolX} => 1, FermionStateful{Outgoing, SpinUp} => 1),
|
||||
)
|
||||
|
||||
@test parse_process("ke->ke", QEDModel()) == compton_process
|
||||
|
||||
positron_compton_process = QEDProcessDescription(
|
||||
Dict{Type,Int}(
|
||||
PhotonStateful{Incoming,PolX} => 1,
|
||||
AntiFermionStateful{Incoming,SpinUp} => 1,
|
||||
),
|
||||
Dict{Type,Int}(
|
||||
PhotonStateful{Outgoing,PolX} => 1,
|
||||
AntiFermionStateful{Outgoing,SpinUp} => 1,
|
||||
),
|
||||
Dict{Type, Int}(PhotonStateful{Incoming, PolX} => 1, AntiFermionStateful{Incoming, SpinUp} => 1),
|
||||
Dict{Type, Int}(PhotonStateful{Outgoing, PolX} => 1, AntiFermionStateful{Outgoing, SpinUp} => 1),
|
||||
)
|
||||
|
||||
@test parse_process("kp->kp", QEDModel()) == positron_compton_process
|
||||
|
||||
trident_process = QEDProcessDescription(
|
||||
Dict{Type,Int}(
|
||||
PhotonStateful{Incoming,PolX} => 1, FermionStateful{Incoming,SpinUp} => 1
|
||||
),
|
||||
Dict{Type,Int}(
|
||||
FermionStateful{Outgoing,SpinUp} => 2,
|
||||
AntiFermionStateful{Outgoing,SpinUp} => 1,
|
||||
),
|
||||
Dict{Type, Int}(PhotonStateful{Incoming, PolX} => 1, FermionStateful{Incoming, SpinUp} => 1),
|
||||
Dict{Type, Int}(FermionStateful{Outgoing, SpinUp} => 2, AntiFermionStateful{Outgoing, SpinUp} => 1),
|
||||
)
|
||||
|
||||
@test parse_process("ke->eep", QEDModel()) == trident_process
|
||||
|
||||
pair_production_process = QEDProcessDescription(
|
||||
Dict{Type,Int}(PhotonStateful{Incoming,PolX} => 2),
|
||||
Dict{Type,Int}(
|
||||
FermionStateful{Outgoing,SpinUp} => 1,
|
||||
AntiFermionStateful{Outgoing,SpinUp} => 1,
|
||||
),
|
||||
Dict{Type, Int}(PhotonStateful{Incoming, PolX} => 2),
|
||||
Dict{Type, Int}(FermionStateful{Outgoing, SpinUp} => 1, AntiFermionStateful{Outgoing, SpinUp} => 1),
|
||||
)
|
||||
|
||||
@test parse_process("kk->pe", QEDModel()) == pair_production_process
|
||||
|
||||
pair_annihilation_process = QEDProcessDescription(
|
||||
Dict{Type,Int}(
|
||||
FermionStateful{Incoming,SpinUp} => 1,
|
||||
AntiFermionStateful{Incoming,SpinUp} => 1,
|
||||
),
|
||||
Dict{Type,Int}(PhotonStateful{Outgoing,PolX} => 2),
|
||||
Dict{Type, Int}(FermionStateful{Incoming, SpinUp} => 1, AntiFermionStateful{Incoming, SpinUp} => 1),
|
||||
Dict{Type, Int}(PhotonStateful{Outgoing, PolX} => 2),
|
||||
)
|
||||
|
||||
@test parse_process("pe->kk", QEDModel()) == pair_annihilation_process
|
||||
@@ -186,18 +161,12 @@ end
|
||||
|
||||
for i in 1:100
|
||||
input = gen_process_input(process)
|
||||
@test length(input.inFerms) ==
|
||||
get(process.inParticles, FermionStateful{Incoming,SpinUp}, 0)
|
||||
@test length(input.inAntiferms) ==
|
||||
get(process.inParticles, AntiFermionStateful{Incoming,SpinUp}, 0)
|
||||
@test length(input.inPhotons) ==
|
||||
get(process.inParticles, PhotonStateful{Incoming,PolX}, 0)
|
||||
@test length(input.outFerms) ==
|
||||
get(process.outParticles, FermionStateful{Outgoing,SpinUp}, 0)
|
||||
@test length(input.outAntiferms) ==
|
||||
get(process.outParticles, AntiFermionStateful{Outgoing,SpinUp}, 0)
|
||||
@test length(input.outPhotons) ==
|
||||
get(process.outParticles, PhotonStateful{Outgoing,PolX}, 0)
|
||||
@test length(input.inFerms) == get(process.inParticles, FermionStateful{Incoming, SpinUp}, 0)
|
||||
@test length(input.inAntiferms) == get(process.inParticles, AntiFermionStateful{Incoming, SpinUp}, 0)
|
||||
@test length(input.inPhotons) == get(process.inParticles, PhotonStateful{Incoming, PolX}, 0)
|
||||
@test length(input.outFerms) == get(process.outParticles, FermionStateful{Outgoing, SpinUp}, 0)
|
||||
@test length(input.outAntiferms) == get(process.outParticles, AntiFermionStateful{Outgoing, SpinUp}, 0)
|
||||
@test length(input.outPhotons) == get(process.outParticles, PhotonStateful{Outgoing, PolX}, 0)
|
||||
|
||||
@test isapprox(
|
||||
sum([
|
||||
@@ -210,7 +179,7 @@ end
|
||||
getfield.(input.outAntiferms, :momentum)...,
|
||||
getfield.(input.outPhotons, :momentum)...,
|
||||
]);
|
||||
atol=sqrt(eps()),
|
||||
atol = sqrt(eps()),
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -242,97 +211,97 @@ end
|
||||
graph = DAG()
|
||||
|
||||
# s to output (exit node)
|
||||
d_exit = insert_node!(graph, make_node(DataTask(16)); track=false)
|
||||
d_exit = insert_node!(graph, make_node(DataTask(16)), track = false)
|
||||
|
||||
sum_node = insert_node!(graph, make_node(ComputeTaskQED_Sum(2)); track=false)
|
||||
sum_node = insert_node!(graph, make_node(ComputeTaskQED_Sum(2)), track = false)
|
||||
|
||||
d_s0_sum = insert_node!(graph, make_node(DataTask(16)); track=false)
|
||||
d_s1_sum = insert_node!(graph, make_node(DataTask(16)); track=false)
|
||||
d_s0_sum = insert_node!(graph, make_node(DataTask(16)), track = false)
|
||||
d_s1_sum = insert_node!(graph, make_node(DataTask(16)), track = false)
|
||||
|
||||
# final s compute
|
||||
s0 = insert_node!(graph, make_node(ComputeTaskQED_S2()); track=false)
|
||||
s1 = insert_node!(graph, make_node(ComputeTaskQED_S2()); track=false)
|
||||
s0 = insert_node!(graph, make_node(ComputeTaskQED_S2()), track = false)
|
||||
s1 = insert_node!(graph, make_node(ComputeTaskQED_S2()), track = false)
|
||||
|
||||
# data from v0 and v1 to s0
|
||||
d_v0_s0 = insert_node!(graph, make_node(DataTask(96)); track=false)
|
||||
d_v1_s0 = insert_node!(graph, make_node(DataTask(96)); track=false)
|
||||
d_v2_s1 = insert_node!(graph, make_node(DataTask(96)); track=false)
|
||||
d_v3_s1 = insert_node!(graph, make_node(DataTask(96)); track=false)
|
||||
d_v0_s0 = insert_node!(graph, make_node(DataTask(96)), track = false)
|
||||
d_v1_s0 = insert_node!(graph, make_node(DataTask(96)), track = false)
|
||||
d_v2_s1 = insert_node!(graph, make_node(DataTask(96)), track = false)
|
||||
d_v3_s1 = insert_node!(graph, make_node(DataTask(96)), track = false)
|
||||
|
||||
# v0 and v1 compute
|
||||
v0 = insert_node!(graph, make_node(ComputeTaskQED_V()); track=false)
|
||||
v1 = insert_node!(graph, make_node(ComputeTaskQED_V()); track=false)
|
||||
v2 = insert_node!(graph, make_node(ComputeTaskQED_V()); track=false)
|
||||
v3 = insert_node!(graph, make_node(ComputeTaskQED_V()); track=false)
|
||||
v0 = insert_node!(graph, make_node(ComputeTaskQED_V()), track = false)
|
||||
v1 = insert_node!(graph, make_node(ComputeTaskQED_V()), track = false)
|
||||
v2 = insert_node!(graph, make_node(ComputeTaskQED_V()), track = false)
|
||||
v3 = insert_node!(graph, make_node(ComputeTaskQED_V()), track = false)
|
||||
|
||||
# data from uPhIn, uPhOut, uElIn, uElOut to v0 and v1
|
||||
d_uPhIn_v0 = insert_node!(graph, make_node(DataTask(96)); track=false)
|
||||
d_uElIn_v0 = insert_node!(graph, make_node(DataTask(96)); track=false)
|
||||
d_uPhOut_v1 = insert_node!(graph, make_node(DataTask(96)); track=false)
|
||||
d_uElOut_v1 = insert_node!(graph, make_node(DataTask(96)); track=false)
|
||||
d_uPhIn_v0 = insert_node!(graph, make_node(DataTask(96)), track = false)
|
||||
d_uElIn_v0 = insert_node!(graph, make_node(DataTask(96)), track = false)
|
||||
d_uPhOut_v1 = insert_node!(graph, make_node(DataTask(96)), track = false)
|
||||
d_uElOut_v1 = insert_node!(graph, make_node(DataTask(96)), track = false)
|
||||
|
||||
# data from uPhIn, uPhOut, uElIn, uElOut to v2 and v3
|
||||
d_uPhOut_v2 = insert_node!(graph, make_node(DataTask(96)); track=false)
|
||||
d_uElIn_v2 = insert_node!(graph, make_node(DataTask(96)); track=false)
|
||||
d_uPhIn_v3 = insert_node!(graph, make_node(DataTask(96)); track=false)
|
||||
d_uElOut_v3 = insert_node!(graph, make_node(DataTask(96)); track=false)
|
||||
d_uPhOut_v2 = insert_node!(graph, make_node(DataTask(96)), track = false)
|
||||
d_uElIn_v2 = insert_node!(graph, make_node(DataTask(96)), track = false)
|
||||
d_uPhIn_v3 = insert_node!(graph, make_node(DataTask(96)), track = false)
|
||||
d_uElOut_v3 = insert_node!(graph, make_node(DataTask(96)), track = false)
|
||||
|
||||
# uPhIn, uPhOut, uElIn and uElOut computes
|
||||
uPhIn = insert_node!(graph, make_node(ComputeTaskQED_U()); track=false)
|
||||
uPhOut = insert_node!(graph, make_node(ComputeTaskQED_U()); track=false)
|
||||
uElIn = insert_node!(graph, make_node(ComputeTaskQED_U()); track=false)
|
||||
uElOut = insert_node!(graph, make_node(ComputeTaskQED_U()); track=false)
|
||||
uPhIn = insert_node!(graph, make_node(ComputeTaskQED_U()), track = false)
|
||||
uPhOut = insert_node!(graph, make_node(ComputeTaskQED_U()), track = false)
|
||||
uElIn = insert_node!(graph, make_node(ComputeTaskQED_U()), track = false)
|
||||
uElOut = insert_node!(graph, make_node(ComputeTaskQED_U()), track = false)
|
||||
|
||||
# data into U
|
||||
d_uPhIn = insert_node!(graph, make_node(DataTask(16), "ki1"); track=false)
|
||||
d_uPhOut = insert_node!(graph, make_node(DataTask(16), "ko1"); track=false)
|
||||
d_uElIn = insert_node!(graph, make_node(DataTask(16), "ei1"); track=false)
|
||||
d_uElOut = insert_node!(graph, make_node(DataTask(16), "eo1"); track=false)
|
||||
d_uPhIn = insert_node!(graph, make_node(DataTask(16), "ki1"), track = false)
|
||||
d_uPhOut = insert_node!(graph, make_node(DataTask(16), "ko1"), track = false)
|
||||
d_uElIn = insert_node!(graph, make_node(DataTask(16), "ei1"), track = false)
|
||||
d_uElOut = insert_node!(graph, make_node(DataTask(16), "eo1"), track = false)
|
||||
|
||||
# now for all the edges
|
||||
insert_edge!(graph, d_uPhIn, uPhIn; track=false)
|
||||
insert_edge!(graph, d_uPhOut, uPhOut; track=false)
|
||||
insert_edge!(graph, d_uElIn, uElIn; track=false)
|
||||
insert_edge!(graph, d_uElOut, uElOut; track=false)
|
||||
insert_edge!(graph, d_uPhIn, uPhIn, track = false)
|
||||
insert_edge!(graph, d_uPhOut, uPhOut, track = false)
|
||||
insert_edge!(graph, d_uElIn, uElIn, track = false)
|
||||
insert_edge!(graph, d_uElOut, uElOut, track = false)
|
||||
|
||||
insert_edge!(graph, uPhIn, d_uPhIn_v0; track=false)
|
||||
insert_edge!(graph, uPhOut, d_uPhOut_v1; track=false)
|
||||
insert_edge!(graph, uElIn, d_uElIn_v0; track=false)
|
||||
insert_edge!(graph, uElOut, d_uElOut_v1; track=false)
|
||||
insert_edge!(graph, uPhIn, d_uPhIn_v0, track = false)
|
||||
insert_edge!(graph, uPhOut, d_uPhOut_v1, track = false)
|
||||
insert_edge!(graph, uElIn, d_uElIn_v0, track = false)
|
||||
insert_edge!(graph, uElOut, d_uElOut_v1, track = false)
|
||||
|
||||
insert_edge!(graph, uPhIn, d_uPhIn_v3; track=false)
|
||||
insert_edge!(graph, uPhOut, d_uPhOut_v2; track=false)
|
||||
insert_edge!(graph, uElIn, d_uElIn_v2; track=false)
|
||||
insert_edge!(graph, uElOut, d_uElOut_v3; track=false)
|
||||
insert_edge!(graph, uPhIn, d_uPhIn_v3, track = false)
|
||||
insert_edge!(graph, uPhOut, d_uPhOut_v2, track = false)
|
||||
insert_edge!(graph, uElIn, d_uElIn_v2, track = false)
|
||||
insert_edge!(graph, uElOut, d_uElOut_v3, track = false)
|
||||
|
||||
insert_edge!(graph, d_uPhIn_v0, v0; track=false)
|
||||
insert_edge!(graph, d_uPhOut_v1, v1; track=false)
|
||||
insert_edge!(graph, d_uElIn_v0, v0; track=false)
|
||||
insert_edge!(graph, d_uElOut_v1, v1; track=false)
|
||||
insert_edge!(graph, d_uPhIn_v0, v0, track = false)
|
||||
insert_edge!(graph, d_uPhOut_v1, v1, track = false)
|
||||
insert_edge!(graph, d_uElIn_v0, v0, track = false)
|
||||
insert_edge!(graph, d_uElOut_v1, v1, track = false)
|
||||
|
||||
insert_edge!(graph, d_uPhIn_v3, v3; track=false)
|
||||
insert_edge!(graph, d_uPhOut_v2, v2; track=false)
|
||||
insert_edge!(graph, d_uElIn_v2, v2; track=false)
|
||||
insert_edge!(graph, d_uElOut_v3, v3; track=false)
|
||||
insert_edge!(graph, d_uPhIn_v3, v3, track = false)
|
||||
insert_edge!(graph, d_uPhOut_v2, v2, track = false)
|
||||
insert_edge!(graph, d_uElIn_v2, v2, track = false)
|
||||
insert_edge!(graph, d_uElOut_v3, v3, track = false)
|
||||
|
||||
insert_edge!(graph, v0, d_v0_s0; track=false)
|
||||
insert_edge!(graph, v1, d_v1_s0; track=false)
|
||||
insert_edge!(graph, v2, d_v2_s1; track=false)
|
||||
insert_edge!(graph, v3, d_v3_s1; track=false)
|
||||
insert_edge!(graph, v0, d_v0_s0, track = false)
|
||||
insert_edge!(graph, v1, d_v1_s0, track = false)
|
||||
insert_edge!(graph, v2, d_v2_s1, track = false)
|
||||
insert_edge!(graph, v3, d_v3_s1, track = false)
|
||||
|
||||
insert_edge!(graph, d_v0_s0, s0; track=false)
|
||||
insert_edge!(graph, d_v1_s0, s0; track=false)
|
||||
insert_edge!(graph, d_v0_s0, s0, track = false)
|
||||
insert_edge!(graph, d_v1_s0, s0, track = false)
|
||||
|
||||
insert_edge!(graph, d_v2_s1, s1; track=false)
|
||||
insert_edge!(graph, d_v3_s1, s1; track=false)
|
||||
insert_edge!(graph, d_v2_s1, s1, track = false)
|
||||
insert_edge!(graph, d_v3_s1, s1, track = false)
|
||||
|
||||
insert_edge!(graph, s0, d_s0_sum; track=false)
|
||||
insert_edge!(graph, s1, d_s1_sum; track=false)
|
||||
insert_edge!(graph, s0, d_s0_sum, track = false)
|
||||
insert_edge!(graph, s1, d_s1_sum, track = false)
|
||||
|
||||
insert_edge!(graph, d_s0_sum, sum_node; track=false)
|
||||
insert_edge!(graph, d_s1_sum, sum_node; track=false)
|
||||
insert_edge!(graph, d_s0_sum, sum_node, track = false)
|
||||
insert_edge!(graph, d_s1_sum, sum_node, track = false)
|
||||
|
||||
insert_edge!(graph, sum_node, d_exit; track=false)
|
||||
insert_edge!(graph, sum_node, d_exit, track = false)
|
||||
|
||||
input = [gen_process_input(process) for _ in 1:1000]
|
||||
|
||||
@@ -345,12 +314,9 @@ end
|
||||
@test isapprox(compton_function.(input), compton_groundtruth.(input))
|
||||
end
|
||||
|
||||
@testset "Equal results after optimization" for optimizer in [
|
||||
ReductionOptimizer(), RandomWalkOptimizer(MersenneTwister(0))
|
||||
]
|
||||
@testset "Process $proc_str" for proc_str in [
|
||||
"ke->ke", "kp->kp", "kk->ep", "ep->kk", "ke->kke", "ke->kkke"
|
||||
]
|
||||
@testset "Equal results after optimization" for optimizer in
|
||||
[ReductionOptimizer(), RandomWalkOptimizer(MersenneTwister(0))]
|
||||
@testset "Process $proc_str" for proc_str in ["ke->ke", "kp->kp", "kk->ep", "ep->kk", "ke->kke", "ke->kkke"]
|
||||
model = QEDModel()
|
||||
process = parse_process(proc_str, model)
|
||||
machine = Machine(
|
||||
|
Reference in New Issue
Block a user