Skip to content

Commit 03d6b97

Browse files
authored
Add depth_max keyword to solve_system! (#41)
* Add depth_max keyword to solve_system! * Improve branching code a bit and add a test case
1 parent 16cecf8 commit 03d6b97

File tree

2 files changed

+38
-10
lines changed

2 files changed

+38
-10
lines changed

src/System.jl

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -433,33 +433,47 @@ function retrace_system!(system::AbstractSystem, gauss::GaussianBeamlet{T}) wher
433433
end
434434

435435
"""
436-
solve_system!(system::System, beam::AbstractBeam; r_max=100, retrace=true)
436+
solve_system!(system::System, beam::AbstractBeam; r_max=100, retrace=true, depth_max=typemax(Int))
437437
438438
Manage the tracing of an `AbstractBeam` through an optical `system`. The function retraces the `beam` if possible and then proceeds to trace each leaf of the beam tree through the system.
439439
The condition to stop ray tracing is that the last `beam` intersection is `nothing` or the beam interaction is `nothing`. Then, the system is considered to be solved.
440-
A maximum number of rays per `beam` (`r_max`) can be specified in order to avoid infinite calculations under resonant conditions, i.e. two facing mirrors.
440+
A maximum number of rays per `beam` (`r_max`) can be specified in order to avoid infinite calculations under resonant conditions, i.e. two facing mirrors. Likewise, `depth_max` limits how many branching levels are explored when new sub-beams are generated (for example, by beamsplitters) so that the tree cannot grow without bound.
441441
442442
# Arguments
443443
444444
- `system::System`: The optical system in which the beam will be traced.
445445
- `beam::AbstractBeam`: The beam object to be traced through the system.
446446
- `r_max::Int=100` (optional): Maximum number of tracing iterations for each leaf. Default is 100.
447447
- `retrace::Bool=true` (optional): Flag to indicate if the system should be retraced. Default is true.
448+
- `depth_max::Int=typemax(Int)` (optional): Maximum number of branching levels explored from the root beam. Default allows unlimited depth.
448449
"""
449-
function solve_system!(system::AbstractSystem, beam::B; r_max::Int = 100, retrace::Bool = true) where {B <: AbstractBeam}
450-
# Initialize a queue for BFS with the root beam.
451-
queue = [beam]
450+
function solve_system!(
451+
system::AbstractSystem,
452+
beam::B;
453+
r_max::Int = 100,
454+
retrace::Bool = true,
455+
depth_max::Int = typemax(Int),
456+
) where {B <: AbstractBeam}
457+
queue = Tuple{B, Int}[(beam, 1)]
452458
while !isempty(queue)
453-
current = popfirst!(queue) # Process beams in FIFO order.
454-
# Optionally retrace the current beam.
459+
# Process beams in FIFO order.
460+
current, depth = popfirst!(queue)
461+
# Optionally retrace the current beam.
455462
if retrace
456463
retrace_system!(system, current)
457464
end
458465
# Process the current leaf beam.
459466
solve_leaf!(system, current; r_max=r_max)
460-
# Enqueue all child beams for subsequent processing.
461-
for child in children(current) # 'children' returns an iterable of sub-beams.
462-
push!(queue, child)
467+
# Check if the maximum branching depth has been reached.
468+
if depth <= depth_max
469+
# Enqueue all child beams for subsequent processing.
470+
for child in children(current) # 'children' returns an iterable of sub-beams.
471+
push!(queue, (child, depth + 1))
472+
end
473+
else
474+
# Maximum braching depth is reached. Remove childrens of the current beam because they will not be solved.
475+
_drop_beams!(current)
476+
@debug lazy"Maximum branching depth of $depth_max levels reached."
463477
end
464478
end
465479
return nothing

test/Components/TestBeamsplitters.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,20 @@ const mm = 1e-3
122122
@test BMO.direction(last(r)) [-1, 0, 0]
123123
end
124124
end
125+
126+
@testset "depth_max branch limiting" begin
127+
beamsplitter = CubeBeamsplitter(25e-3, n -> N0)
128+
translate3d!(beamsplitter, [0, 50mm, 0])
129+
system = System([beamsplitter])
130+
131+
beam = Beam([0, 0, 0], [0, 1, 0], 1e-6)
132+
solve_system!(system, beam; depth_max=0)
133+
@test isempty(beam.children)
134+
135+
beam = Beam([0, 0, 0], [0, 1, 0], 1e-6)
136+
solve_system!(system, beam; depth_max=1)
137+
@test length(beam.children) == 2
138+
end
125139
end
126140

127141
end

0 commit comments

Comments
 (0)