From 1548437ddb53d06c8c0cedf35696b35802494ba1 Mon Sep 17 00:00:00 2001 From: Anton Reinhard Date: Wed, 19 Jun 2024 15:40:25 +0200 Subject: [PATCH 1/3] Add concrete particle types from base --- src/QEDcore.jl | 7 ++ src/particles/particle_types.jl | 202 ++++++++++++++++++++++++++++++++ src/particles/spinors.jl | 6 +- test/particles/types.jl | 73 ++++++++++++ test/runtests.jl | 4 + 5 files changed, 289 insertions(+), 3 deletions(-) create mode 100644 src/particles/particle_types.jl create mode 100644 test/particles/types.jl diff --git a/src/QEDcore.jl b/src/QEDcore.jl index c42bed0..782b285 100644 --- a/src/QEDcore.jl +++ b/src/QEDcore.jl @@ -15,6 +15,12 @@ export BiSpinor, AdjointBiSpinor, DiracMatrix # gamma matrices export gamma, GAMMA, DiracGammaRepresentation, slashed +# particle types +export AbstractParticleSpinor +export FermionLike, Fermion, AntiFermion, MajoranaFermion +export BosonLike, Boson, AntiBoson, MajoranaBoson +export Electron, Positron, Photon + # particle spinors export BASE_PARTICLE_SPINOR, BASE_ANTIPARTICLE_SPINOR export IncomingFermionSpinor, @@ -35,5 +41,6 @@ include("algebraic_objects/lorentz_vector.jl") include("algebraic_objects/gamma_matrices.jl") include("particles/spinors.jl") +include("particles/particle_types.jl") end diff --git a/src/particles/particle_types.jl b/src/particles/particle_types.jl new file mode 100644 index 0000000..2ef3c72 --- /dev/null +++ b/src/particles/particle_types.jl @@ -0,0 +1,202 @@ +############### +# The particle types +# +# In this file, we define the types of particles, their states and directions, and +# implement the abstact particle interface accordingly. +############### + +import QEDbase: is_particle, is_anti_particle, is_boson, is_fermion, mass, charge + +""" + AbstractParticleSpinor + +TBW +""" +abstract type AbstractParticleSpinor end + +""" +Abstract base types for particle species that act like fermions in the sense of particle statistics. + +!!! note "particle interface" + Every concrete subtype of [`FermionLike`](@ref) has `is_fermion(::FermionLike) = true`. +""" +abstract type FermionLike <: QEDbase.AbstractParticleType end + +is_fermion(::FermionLike) = true + +""" +Abstract base type for fermions as distinct from [`AntiFermion`](@ref)s. + +!!! note "particle interface" + All subtypes of `Fermion` have + ```julia + is_fermion(::Fermion) = true + is_particle(::Fermion) = true + is_anti_particle(::Fermion) = false + ``` + +""" +abstract type Fermion <: FermionLike end + +is_particle(::Fermion) = true + +is_anti_particle(::Fermion) = false + +""" +Abstract base type for anti-fermions as distinct from its particle counterpart `Fermion`. + +!!! note "particle interface" + All subtypes of `AntiFermion` have + ```julia + is_fermion(::AntiFermion) = true + is_particle(::AntiFermion) = false + is_anti_particle(::AntiFermion) = true + ``` +""" +abstract type AntiFermion <: FermionLike end + +is_particle(::AntiFermion) = false + +is_anti_particle(::AntiFermion) = true + +""" +Abstract base type for majorana-fermions, i.e. fermions which are their own anti-particles. + +!!! note "particle interface" + All subtypes of `MajoranaFermion` have + ```julia + is_fermion(::MajoranaFermion) = true + is_particle(::MajoranaFermion) = true + is_anti_particle(::MajoranaFermion) = true + ``` + +""" +abstract type MajoranaFermion <: FermionLike end + +is_particle(::MajoranaFermion) = true + +is_anti_particle(::MajoranaFermion) = true + +""" +Concrete type for *electrons* as a particle species. Mostly used for dispatch. + +```jldoctest +julia> using QEDbase + +julia> Electron() +electron +``` + +!!! note "particle interface" + Besides being a subtype of [`Fermion`](@ref), objects of type `Electron` have + + ```julia + mass(::Electron) = 1.0 + charge(::Electron) = -1.0 + ``` +""" +struct Electron <: Fermion end +mass(::Electron) = 1.0 +charge(::Electron) = -1.0 +Base.show(io::IO, ::Electron) = print(io, "electron") + +""" +Concrete type for *positrons* as a particle species. Mostly used for dispatch. + +```jldoctest +julia> using QEDbase + +julia> Positron() +positron +``` + +!!! note "particle interface" + Besides being a subtype of [`AntiFermion`](@ref), objects of type `Positron` have + + ```julia + mass(::Positron) = 1.0 + charge(::Positron) = 1.0 + ``` +""" +struct Positron <: AntiFermion end +mass(::Positron) = 1.0 +charge(::Positron) = 1.0 +Base.show(io::IO, ::Positron) = print(io, "positron") + +""" +Abstract base types for particle species that act like bosons in the sense of particle statistics. + +!!! note "particle interface" + Every concrete subtype of `BosonLike` has `is_boson(::BosonLike) = true`. +""" +abstract type BosonLike <: QEDbase.AbstractParticleType end + +is_boson(::BosonLike) = true + +""" +Abstract base type for bosons as distinct from its anti-particle counterpart [`AntiBoson`](@ref). + +!!! note "particle interface" + All subtypes of `Boson` have + ```julia + is_boson(::Boson) = true + is_particle(::Boson) = true + is_anti_particle(::Boson) = false + ``` +""" +abstract type Boson <: BosonLike end +is_particle(::Boson) = true +is_anti_particle(::Boson) = false + +""" +Abstract base type for anti-bosons as distinct from its particle counterpart [`Boson`](@ref). + +!!! note "particle interface" + All subtypes of `AntiBoson` have + ```julia + is_boson(::AntiBoson) = true + is_particle(::AntiBoson) = false + is_anti_particle(::AntiBoson) = true + ``` +""" +abstract type AntiBoson <: BosonLike end +is_particle(::AntiBoson) = false +is_anti_particle(::AntiBoson) = true + +""" +Abstract base type for majorana-bosons, i.e. bosons which are their own anti-particles. + +!!! note "particle interface" + All subtypes of `MajoranaBoson` have + ```julia + is_boson(::MajoranaBoson) = true + is_particle(::MajoranaBoson) = true + is_anti_particle(::MajoranaBoson) = true + ``` +""" +abstract type MajoranaBoson <: BosonLike end +is_particle(::MajoranaBoson) = true +is_anti_particle(::MajoranaBoson) = true + +""" +Concrete type for the *photons* as a particle species. Mostly used for dispatch. + +```jldoctest +julia> using QEDbase + +julia> Photon() +photon +``` + +!!! note "particle interface" + Besides being a subtype of `MajoranaBoson`, `Photon` has + + ```julia + mass(::Photon) = 0.0 + charge(::Photon) = 0.0 + ``` +""" +struct Photon <: MajoranaBoson end +mass(::Photon) = 0.0 +charge(::Photon) = 0.0 +Base.show(io::IO, ::Photon) = print(io, "photon") diff --git a/src/particles/spinors.jl b/src/particles/spinors.jl index f20b60c..d26ebe5 100644 --- a/src/particles/spinors.jl +++ b/src/particles/spinors.jl @@ -118,6 +118,6 @@ end const SpinorVbar = IncomingAntiFermionSpinor -# function getindex(SP::T, idx) where {T<:QEDbase.AbstractParticleSpinor} -# return idx in (1, 2) ? SP(idx) : throw(BoundsError()) -# end +function getindex(SP::T, idx) where {T<:QEDbase.AbstractParticleSpinor} + return idx in (1, 2) ? SP(idx) : throw(BoundsError()) +end diff --git a/test/particles/types.jl b/test/particles/types.jl new file mode 100644 index 0000000..13fec88 --- /dev/null +++ b/test/particles/types.jl @@ -0,0 +1,73 @@ +using QEDbase +using StaticArrays +using Random + +# test function to test scalar broadcasting +test_broadcast(x::AbstractParticle) = x +test_broadcast(x::ParticleDirection) = x +test_broadcast(x::AbstractSpinOrPolarization) = x + +@testset "fermion likes" begin + @testset "antifermion" begin + struct TestAntiFermion <: AntiFermion end + @test is_fermion(TestAntiFermion()) + @test !is_particle(TestAntiFermion()) + @test is_anti_particle(TestAntiFermion()) + @test test_broadcast.(TestAntiFermion()) == TestAntiFermion() + end + + @testset "majorana fermion" begin + struct TestMajoranaFermion <: MajoranaFermion end + @test is_fermion(TestMajoranaFermion()) + @test is_particle(TestMajoranaFermion()) + @test is_anti_particle(TestMajoranaFermion()) + @test test_broadcast.(TestMajoranaFermion()) == TestMajoranaFermion() + end + + @testset "electron" begin + @test is_fermion(Electron()) + @test is_particle(Electron()) + @test !is_anti_particle(Electron()) + @test mass(Electron()) == 1.0 + @test charge(Electron()) == -1.0 + @test test_broadcast.(Electron()) == Electron() + end + + @testset "positron" begin + @test is_fermion(Positron()) + @test !is_particle(Positron()) + @test is_anti_particle(Positron()) + @test mass(Positron()) == 1.0 + @test charge(Positron()) == 1.0 + @test test_broadcast.(Positron()) == Positron() + end +end + +@testset "boson likes" begin + @testset "boson" begin + struct TestBoson <: Boson end + @test !is_fermion(TestBoson()) + @test is_boson(TestBoson()) + @test is_particle(TestBoson()) + @test !is_anti_particle(TestBoson()) + @test test_broadcast.(TestBoson()) == TestBoson() + end + + @testset "antiboson" begin + struct TestAntiBoson <: AntiBoson end + @test !is_fermion(TestAntiBoson()) + @test is_boson(TestAntiBoson()) + @test !is_particle(TestAntiBoson()) + @test is_anti_particle(TestAntiBoson()) + @test test_broadcast.(TestAntiBoson()) == TestAntiBoson() + end + + @testset "majorana boson" begin + struct TestMajoranaBoson <: MajoranaBoson end + @test !is_fermion(TestMajoranaBoson()) + @test is_boson(TestMajoranaBoson()) + @test is_particle(TestMajoranaBoson()) + @test is_anti_particle(TestMajoranaBoson()) + @test test_broadcast.(TestMajoranaBoson()) == TestMajoranaBoson() + end +end diff --git a/test/runtests.jl b/test/runtests.jl index 0c44d6c..045c44b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -21,6 +21,10 @@ begin end # particles + @time @safetestset "particle types" begin + include("particles/types.jl") + end + @time @safetestset "particle spinors" begin include("particles/spinors.jl") end From 1492bd88e95c67203328a04945d9c809805966f6 Mon Sep 17 00:00:00 2001 From: Anton Reinhard Date: Wed, 19 Jun 2024 16:13:32 +0200 Subject: [PATCH 2/3] Fix tests --- src/particles/spinors.jl | 7 ++++--- test/particles/types.jl | 4 ++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/particles/spinors.jl b/src/particles/spinors.jl index d26ebe5..d366807 100644 --- a/src/particles/spinors.jl +++ b/src/particles/spinors.jl @@ -118,6 +118,7 @@ end const SpinorVbar = IncomingAntiFermionSpinor -function getindex(SP::T, idx) where {T<:QEDbase.AbstractParticleSpinor} - return idx in (1, 2) ? SP(idx) : throw(BoundsError()) -end +# TODO: reenable when it's no longer in QEDbase +# function getindex(SP::T, idx) where {T<:QEDbase.AbstractParticleSpinor} +# return idx in (1, 2) ? SP(idx) : throw(BoundsError()) +# end diff --git a/test/particles/types.jl b/test/particles/types.jl index 13fec88..4766170 100644 --- a/test/particles/types.jl +++ b/test/particles/types.jl @@ -2,6 +2,10 @@ using QEDbase using StaticArrays using Random +# TODO this can be deleted when QEDbase is released again +# fix for the broadcast tests +Base.broadcastable(part::QEDbase.AbstractParticleType) = Ref(part) + # test function to test scalar broadcasting test_broadcast(x::AbstractParticle) = x test_broadcast(x::ParticleDirection) = x From 1dd825720376394e4367530d20d210937039ef87 Mon Sep 17 00:00:00 2001 From: Anton Reinhard Date: Wed, 19 Jun 2024 16:17:16 +0200 Subject: [PATCH 3/3] Format --- .gitignore | 5 ++--- src/algebraic_objects/lorentz_vector.jl | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 5a16984..493f309 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ -/Manifest.toml -/docs/Manifest.toml -/docs/build/ +*Manifest.toml +docs/build/ diff --git a/src/algebraic_objects/lorentz_vector.jl b/src/algebraic_objects/lorentz_vector.jl index cff8c75..a0cfcfc 100644 --- a/src/algebraic_objects/lorentz_vector.jl +++ b/src/algebraic_objects/lorentz_vector.jl @@ -98,4 +98,4 @@ end # TODO: this breaks incremental compilation because it's trying to eval permanent changes in a different module #register_LorentzVectorLike(MLorentzVector) @traitimpl QEDbase.IsLorentzVectorLike{MLorentzVector} -@traitimpl QEDbase.IsMutableLorentzVectorLike{MLorentzVector} \ No newline at end of file +@traitimpl QEDbase.IsMutableLorentzVectorLike{MLorentzVector}