n-Pair Trident Scattering Process
In this file, we set up an n-pair trident scattering process. A trident process looks like $k e^- \to e^- (e^- e^+)^n$.
You can download this file as a jupyter notebook.
using QEDFeynmanDiagramsWe need QEDcore of the QEDjl-project for base functionality and a process type, for which we can use the Mocks submodule from QEDbase for this tutorial. Downstream, a ScatteringProcess from QEDprocesses.jl could be used, for example.
using QEDcore
using QEDbase.MocksLet's decide how many pairs our trident should produce:
n = 2;Now we setup the scattering process accordingly. We only consider a single spin/polarization combination here. For an example with many spin and polarization combinations, refer to the n-photon Compton example
proc = QEDbase.Mocks.MockProcessSP(
(Electron(), Photon()), # incoming particles
(Electron(), ntuple(_ -> Electron(), n)..., ntuple(_ -> Positron(), n)...), # outgoing particles
(SpinUp(), PolX()), # incoming particle spin/pols
(SpinUp(), ntuple(_ -> SpinUp(), 2 * n)...), # outgoing particle spin/pols
)QEDbase.Mocks.MockProcessSP{Tuple{Electron, Photon}, Tuple{Electron, Electron, Electron, Positron, Positron}, Tuple{SpinUp, PolarizationX}, NTuple{5, SpinUp}}((electron, photon), (electron, electron, electron, positron, positron), (spin up, x-polarized), (spin up, spin up, spin up, spin up, spin up))The number_of_diagrams function returns how many valid Feynman diagrams there are for a given process.
number_of_diagrams(proc)252Next, we can generate the DAG representing the computation for our scattering process' squared matrix element. This uses ComputableDAGs.jl.
dag = graph(proc)Graph:
Nodes: Total: 943, QEDFeynmanDiagrams.ComputeTask_Propagator: 60, QEDFeynmanDiagrams.ComputeTask_CollectPairs: 60,
QEDFeynmanDiagrams.ComputeTask_CollectTriples: 1, QEDFeynmanDiagrams.ComputeTask_BaseState: 7, QEDFeynmanDiagrams.ComputeTask_Triple: 30,
QEDFeynmanDiagrams.ComputeTask_PairNegated: 9, QEDFeynmanDiagrams.ComputeTask_PropagatePairs: 60, QEDFeynmanDiagrams.ComputeTask_TripleNegated: 150,
ComputableDAGs.DataTask: 505, QEDFeynmanDiagrams.ComputeTask_Pair: 60, QEDFeynmanDiagrams.ComputeTask_SpinPolCumulation: 1
Edges: 1553
Total Compute Effort: 0.0
Total Data Transfer: 0.0
Total Compute Intensity: 0.0
To continue, we will need ComputableDAGs.jl.
using ComputableDAGsNow we need an input for the function, which is a QEDcore.PhaseSpacePoint. For now, we generate random momenta for every particle. In the future, QEDevents will be able to generate physical PhaseSpacePoints.
psp = PhaseSpacePoint(
proc,
MockModel(),
FlatPhaseSpaceLayout(TwoBodyRestSystem()),
tuple((rand(SFourMomentum) for _ in 1:number_incoming_particles(proc))...),
tuple((rand(SFourMomentum) for _ in 1:number_outgoing_particles(proc))...),
)PhaseSpacePoint:
process: QEDbase.Mocks.MockProcessSP{Tuple{Electron, Photon}, Tuple{Electron, Electron, Electron, Positron, Positron}, Tuple{SpinUp, PolarizationX}, NTuple{5, SpinUp}}((electron, photon), (electron, electron, electron, positron, positron), (spin up, x-polarized), (spin up, spin up, spin up, spin up, spin up))
model: mock model
phase space layout: FlatPhaseSpaceLayout{TwoBodyTargetSystem{Energy{2}}}(TwoBodyTargetSystem{Energy{2}}(Energy{2}()))
incoming particles:
-> incoming electron: [0.046497460104267474, 0.7231872842126934, 0.8564535184316862, 0.7593243740505685]
-> incoming photon: [0.7337632916099343, 0.1368027978056554, 0.8330314048213406, 0.2868426931578971]
outgoing particles:
-> outgoing electron: [0.1032993303871862, 0.1316595311828468, 0.4569626935057627, 0.4324047748563856]
-> outgoing electron: [0.16363060458841117, 0.14079302692857, 0.05735869974431995, 0.8434009733741221]
-> outgoing electron: [0.778302199299943, 0.7440927157102011, 0.7297663322829567, 0.7761959119099375]
-> outgoing positron: [0.8338192459745578, 0.4268252361951489, 0.4911682937973807, 0.5434596700355626]
-> outgoing positron: [0.15093621960209236, 0.4606526124463929, 0.3184177873742151, 0.5341560278079245]
With the DAG, the process, and an input type to use, we can now generate the actual computable function:
func = compute_function(dag, proc, cpu_st(), @__MODULE__);Finally, we can test that the function actually runs and computes something by simply calling it on the PhaseSpacePoint:
func(psp)0.004449133083094162We can benchmark the execution speed too:
using BenchmarkTools
@benchmark func($psp)BenchmarkTools.Trial: 10000 samples with 1 evaluation per sample.
Range (min … max): 46.046 μs … 4.865 ms ┊ GC (min … max): 0.00% … 93.86%
Time (median): 48.952 μs ┊ GC (median): 0.00%
Time (mean ± σ): 53.610 μs ± 117.929 μs ┊ GC (mean ± σ): 5.85% ± 2.65%
▂▅▆▇████▇▆▆▅▄▃▂▂▁ ▁▁▁▁▁▁ ▁▁ ▃
▇██████████████████▇▇▆▆▆▆▆▄▂▆▅▆▇▇████████████████▇█▆▇▇▇▇▅▆▄▅ █
46 μs Histogram: log(frequency) by time 69.2 μs <
Memory estimate: 68.98 KiB, allocs estimate: 661.This page was generated using Literate.jl.