Skip to content

Commit

Permalink
Add process interface test (#96)
Browse files Browse the repository at this point in the history
Adds the process test from QEDcore to QEDbase in order to test the
implementations relying on the process interface.
Once #95, #90, and #88 are merged, I can add tests for their
functionalities here as well.
  • Loading branch information
AntonReinhard authored Jul 11, 2024
1 parent 30d398b commit 68f1fc9
Show file tree
Hide file tree
Showing 4 changed files with 265 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/interfaces/phase_space_point.jl
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ function momentum(
if (number_particles(process(psp), dir, species) != 1)
throw(
InvalidInputError(
"this overload only works when exactly one $dir $species exists in the phase space point, but $(number_paarticles(process(psp), dir, species)) exist in this one; to specify an index, use momentum(psp, dir, species, n)",
"this overload only works when exactly one $dir $species exists in the phase space point, but $(number_particles(process(psp), dir, species)) exist in this one; to specify an index, use momentum(psp, dir, species, n)",
),
)
end
Expand Down
77 changes: 77 additions & 0 deletions test/interfaces/phase_space_point.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using Random
using QEDbase
using QEDcore

RNG = MersenneTwister(137137)
ATOL = 0.0
RTOL = sqrt(eps())

include("../test_implementation/TestImplementation.jl")

const TestBoson = TestImplementation.TestParticleBoson
const TestFermion = TestImplementation.TestParticleFermion

@testset "PhaseSpacePoint" begin
N_INCOMING = 3
N_OUTGOING = 3
INCOMING_PARTICLES = (TestBoson(), TestFermion(), TestBoson())
OUTGOING_PARTICLES = (TestFermion(), TestBoson(), TestFermion())

TESTPROC = TestImplementation.TestProcess(INCOMING_PARTICLES, OUTGOING_PARTICLES)
TESTMODEL = TestImplementation.TestModel()
TESTPSDEF = TestImplementation.TestPhasespaceDef()
IN_PS = TestImplementation._rand_momenta(RNG, N_INCOMING)
OUT_PS = TestImplementation._rand_momenta(RNG, N_OUTGOING)

PSP = PhaseSpacePoint(TESTPROC, TESTMODEL, TESTPSDEF, IN_PS, OUT_PS)

@testset "momentum implementations" begin
@test momentum(PSP, Incoming(), TestBoson(), 1) == IN_PS[1]
@test momentum(PSP, Incoming(), TestFermion(), 1) == IN_PS[2]
@test momentum(PSP, Incoming(), TestFermion()) == IN_PS[2]
@test momentum(PSP, Incoming(), TestBoson(), 2) == IN_PS[3]

@test momentum(PSP, Outgoing(), TestFermion(), 1) == OUT_PS[1]
@test momentum(PSP, Outgoing(), TestBoson(), 1) == OUT_PS[2]
@test momentum(PSP, Outgoing(), TestBoson()) == OUT_PS[2]
@test momentum(PSP, Outgoing(), TestFermion(), 2) == OUT_PS[3]

@test momentum(PSP, Incoming(), TestBoson(), Val(1)) == IN_PS[1]
@test momentum(PSP, Incoming(), TestFermion(), Val(1)) == IN_PS[2]
@test momentum(PSP, Incoming(), TestBoson(), Val(2)) == IN_PS[3]

@test momentum(PSP, Outgoing(), TestFermion(), Val(1)) == OUT_PS[1]
@test momentum(PSP, Outgoing(), TestBoson(), Val(1)) == OUT_PS[2]
@test momentum(PSP, Outgoing(), TestFermion(), Val(2)) == OUT_PS[3]
end

@testset "momentum fails" begin
@test_throws BoundsError momentum(PSP, Incoming(), 0)
@test_throws BoundsError momentum(PSP, Outgoing(), 0)
@test_throws BoundsError momentum(PSP, Incoming(), TestBoson(), 0)
@test_throws BoundsError momentum(PSP, Outgoing(), TestFermion(), 0)
@test_throws BoundsError momentum(PSP, Incoming(), 4)
@test_throws BoundsError momentum(PSP, Outgoing(), 4)
@test_throws BoundsError momentum(PSP, Incoming(), TestFermion(), 2)
@test_throws BoundsError momentum(PSP, Incoming(), TestBoson(), 3)
@test_throws BoundsError momentum(PSP, Outgoing(), TestFermion(), 3)
@test_throws BoundsError momentum(PSP, Outgoing(), TestBoson(), 2)

# overload only exists for single particles of that type
@test_throws InvalidInputError momentum(PSP, Incoming(), TestBoson())
@test_throws InvalidInputError momentum(PSP, Outgoing(), TestFermion())

# same for Val() overloads
@test_throws BoundsError momentum(PSP, Incoming(), TestBoson(), Val(0))
@test_throws BoundsError momentum(PSP, Outgoing(), TestFermion(), Val(0))
@test_throws BoundsError momentum(PSP, Incoming(), TestFermion(), Val(2))
@test_throws BoundsError momentum(PSP, Incoming(), TestBoson(), Val(3))
@test_throws BoundsError momentum(PSP, Outgoing(), TestFermion(), Val(3))
@test_throws BoundsError momentum(PSP, Outgoing(), TestBoson(), Val(2))
end

@testset "momenta implementation" begin
@test IN_PS == momenta(PSP, Incoming())
@test OUT_PS == momenta(PSP, Outgoing())
end
end
179 changes: 179 additions & 0 deletions test/interfaces/process.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
using Random
using QEDbase
using QEDcore

RNG = MersenneTwister(137137)
ATOL = 0.0
RTOL = sqrt(eps())

include("../test_implementation/TestImplementation.jl")

@testset "($N_INCOMING,$N_OUTGOING)" for (N_INCOMING, N_OUTGOING) in Iterators.product(
(1, rand(RNG, 2:8)), (1, rand(RNG, 2:8))
)
INCOMING_PARTICLES = Tuple(rand(RNG, TestImplementation.PARTICLE_SET, N_INCOMING))
OUTGOING_PARTICLES = Tuple(rand(RNG, TestImplementation.PARTICLE_SET, N_OUTGOING))

TESTPROC = TestImplementation.TestProcess(INCOMING_PARTICLES, OUTGOING_PARTICLES)
TESTMODEL = TestImplementation.TestModel()
TESTPSDEF = TestImplementation.TestPhasespaceDef()
IN_PS = TestImplementation._rand_momenta(RNG, N_INCOMING)
OUT_PS = TestImplementation._rand_momenta(RNG, N_OUTGOING)
PSP = PhaseSpacePoint(TESTPROC, TESTMODEL, TESTPSDEF, IN_PS, OUT_PS)

@testset "failed interface" begin
TESTPROC_FAIL_ALL = TestImplementation.TestProcess_FAIL_ALL(
INCOMING_PARTICLES, OUTGOING_PARTICLES
)
TESTPROC_FAIL_DIFFCS = TestImplementation.TestProcess_FAIL_DIFFCS(
INCOMING_PARTICLES, OUTGOING_PARTICLES
)
TESTMODEL_FAIL = TestImplementation.TestModel_FAIL()
TESTPSDEF_FAIL = TestImplementation.TestPhasespaceDef_FAIL()

@testset "failed process interface" begin
@test_throws MethodError incoming_particles(TESTPROC_FAIL_ALL)
@test_throws MethodError outgoing_particles(TESTPROC_FAIL_ALL)
end

@testset "$PROC $MODEL" for (PROC, MODEL) in Iterators.product(
(TESTPROC, TESTPROC_FAIL_DIFFCS), (TESTMODEL, TESTMODEL_FAIL)
)
if TestImplementation._any_fail(PROC, MODEL)
psp = PhaseSpacePoint(PROC, MODEL, TESTPSDEF, IN_PS, OUT_PS)
@test_throws MethodError QEDbase._incident_flux(psp)
@test_throws MethodError QEDbase._averaging_norm(psp)
@test_throws MethodError QEDbase._matrix_element(psp)
end

for PS_DEF in (TESTPSDEF, TESTPSDEF_FAIL)
if TestImplementation._any_fail(PROC, MODEL, PS_DEF)
psp = PhaseSpacePoint(PROC, MODEL, PS_DEF, IN_PS, OUT_PS)
@test_throws MethodError QEDbase._phase_space_factor(psp)
end
end
end
end

@testset "broadcast" begin
test_func(proc::AbstractProcessDefinition) = proc
@test test_func.(TESTPROC) == TESTPROC

test_func(model::AbstractModelDefinition) = model
@test test_func.(TESTMODEL) == TESTMODEL
end

@testset "incoming/outgoing particles" begin
@test incoming_particles(TESTPROC) == INCOMING_PARTICLES
@test outgoing_particles(TESTPROC) == OUTGOING_PARTICLES
@test particles(TESTPROC, Incoming()) == INCOMING_PARTICLES
@test particles(TESTPROC, Outgoing()) == OUTGOING_PARTICLES
@test number_incoming_particles(TESTPROC) == N_INCOMING
@test number_outgoing_particles(TESTPROC) == N_OUTGOING
@test number_particles(TESTPROC, Incoming()) == N_INCOMING
@test number_particles(TESTPROC, Outgoing()) == N_OUTGOING

@testset "$dir $species" for (dir, species) in Iterators.product(
(Incoming(), Outgoing()), TestImplementation.PARTICLE_SET
)
groundtruth_particle_count = count(x -> x == species, particles(TESTPROC, dir))
test_ps = ParticleStateful(dir, species, zero(SFourMomentum))

@test number_particles(TESTPROC, dir, species) == groundtruth_particle_count
@test number_particles(TESTPROC, test_ps) == groundtruth_particle_count
end
end

@testset "incident flux" begin
test_incident_flux = QEDbase._incident_flux(
InPhaseSpacePoint(TESTPROC, TESTMODEL, TESTPSDEF, IN_PS)
)
groundtruth = TestImplementation._groundtruth_incident_flux(IN_PS)
@test isapprox(test_incident_flux, groundtruth, atol=ATOL, rtol=RTOL)

test_incident_flux = QEDbase._incident_flux(
PhaseSpacePoint(TESTPROC, TESTMODEL, TESTPSDEF, IN_PS, OUT_PS)
)
@test isapprox(test_incident_flux, groundtruth, atol=ATOL, rtol=RTOL)

@test_throws MethodError QEDbase._incident_flux(
OutPhaseSpacePoint(TESTPROC, TESTMODEL, TESTPSDEF, OUT_PS)
)
end

@testset "averaging norm" begin
test_avg_norm = QEDbase._averaging_norm(TESTPROC)
groundtruth = TestImplementation._groundtruth_averaging_norm(TESTPROC)
@test isapprox(test_avg_norm, groundtruth, atol=ATOL, rtol=RTOL)
end

@testset "matrix element" begin
test_matrix_element = QEDbase._matrix_element(PSP)
groundtruth = TestImplementation._groundtruth_matrix_element(IN_PS, OUT_PS)
@test length(test_matrix_element) == length(groundtruth)
for i in eachindex(test_matrix_element)
@test isapprox(test_matrix_element[i], groundtruth[i], atol=ATOL, rtol=RTOL)
end
end

@testset "is in phasespace" begin
@test QEDbase._is_in_phasespace(PSP)

IN_PS_unphysical = (zero(SFourMomentum), IN_PS[2:end]...)
OUT_PS_unphysical = (OUT_PS[1:(end - 1)]..., ones(SFourMomentum))
PSP_unphysical_in_ps = PhaseSpacePoint(
TESTPROC, TESTMODEL, TESTPSDEF, IN_PS_unphysical, OUT_PS
)
PSP_unphysical_out_ps = PhaseSpacePoint(
TESTPROC, TESTMODEL, TESTPSDEF, IN_PS, OUT_PS_unphysical
)
PSP_unphysical = PhaseSpacePoint(
TESTPROC, TESTMODEL, TESTPSDEF, IN_PS_unphysical, OUT_PS_unphysical
)

@test !QEDbase._is_in_phasespace(PSP_unphysical_in_ps)
@test !QEDbase._is_in_phasespace(PSP_unphysical_out_ps)
@test !QEDbase._is_in_phasespace(PSP_unphysical)
end

@testset "phase space factor" begin
test_phase_space_factor = QEDbase._phase_space_factor(PSP)
groundtruth = TestImplementation._groundtruth_phase_space_factor(IN_PS, OUT_PS)
@test isapprox(test_phase_space_factor, groundtruth, atol=ATOL, rtol=RTOL)
end

@testset "generate momenta" begin
ps_in_coords = Tuple(rand(RNG, 4 * N_INCOMING))
ps_out_coords = Tuple(rand(RNG, 4 * N_OUTGOING))

groundtruth_in_momenta = TestImplementation._groundtruth_generate_momenta(
ps_in_coords
)
groundtruth_out_momenta = TestImplementation._groundtruth_generate_momenta(
ps_out_coords
)

@test groundtruth_in_momenta == QEDbase._generate_incoming_momenta(
TESTPROC, TESTMODEL, TESTPSDEF, ps_in_coords
)
@test groundtruth_out_momenta == QEDbase._generate_outgoing_momenta(
TESTPROC, TESTMODEL, TESTPSDEF, ps_in_coords, ps_out_coords
)
@test (groundtruth_in_momenta, groundtruth_out_momenta) ==
QEDbase._generate_momenta(
TESTPROC, TESTMODEL, TESTPSDEF, ps_in_coords, ps_out_coords
)

groundtruth_psp = PhaseSpacePoint(
TESTPROC, TESTMODEL, TESTPSDEF, groundtruth_in_momenta, groundtruth_out_momenta
)
groundtruth_in_psp = InPhaseSpacePoint(
TESTPROC, TESTMODEL, TESTPSDEF, groundtruth_in_momenta
)

@test groundtruth_psp ==
PhaseSpacePoint(TESTPROC, TESTMODEL, TESTPSDEF, ps_in_coords, ps_out_coords)
@test groundtruth_in_psp ==
InPhaseSpacePoint(TESTPROC, TESTMODEL, TESTPSDEF, ps_in_coords)
end
end
8 changes: 8 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ begin
include("interfaces/model.jl")
end

@time @safetestset "process interface" begin
include("interfaces/process.jl")
end

@time @safetestset "phase space point interface" begin
include("interfaces/phase_space_point.jl")
end

@time @safetestset "Lorentz interface" begin
include("interfaces/lorentz.jl")
end
Expand Down

0 comments on commit 68f1fc9

Please sign in to comment.