Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions manual/ele-types.tex
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ \section{Fork}
Element parameter groups associated with this element type are:
\TOPrule
\begin{example}
FloorParams -> Floor floor position and orientation. \sref{s:orientation.g}
FloorParams -> Floor floor position and orientation. \sref{s:orientation.g}
LengthParams -> Length and s-position parameters. \sref{s:length.g}
DescriptionParams -> Element descriptive strings. \sref{s:descrip.g}
TrackingParams -> Default tracking settings. \sref{s:tracking.g}
Expand All @@ -381,12 +381,13 @@ \section{Fork}

The components of this group are:
\begin{example}
to_line::Union{BeamLine,Branch} - Beam line to fork to
to_ele::Union{String,Ele} - Element forked to.
to_line::Union{BeamLine,Nothing} - Beam line to fork to. Default: nothing.
to_ele::Union{String,Ele,Nothing} - Element forked to. Default: nothing.
direction::Int - Longitudinal Direction of injected beam.
\end{example}


If \vn{to_line} is set to a \vn{BeamLine} -> New branch
Otherwise the fork is to an existing lattice element.



Expand Down
64 changes: 39 additions & 25 deletions src/bookkeeper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,7 @@ function ele_paramgroup_bookkeeper!(ele::Ele, group::Type{ForkParams},
changed::ChangedLedger, previous_ele::Ele)
fg = ele.ForkParams
rg = ele.ReferenceParams
clear_changed!(ele, ForkParams)

to_ele = fg.to_ele
to_ele.ix_ele != 1 && return
Expand All @@ -608,8 +609,6 @@ function ele_paramgroup_bookkeeper!(ele::Ele, group::Type{ForkParams},
to_ele.pc_ref = rg.pc_ref

set_branch_min_max_changed!(to_ele.branch, 1)
clear_changed!(ele, ForkParams)

return
end

Expand Down Expand Up @@ -955,35 +954,50 @@ Adds the `Branch` that is forked to to the lattice.
""" fork_bookkeeper

function fork_bookkeeper(fork::Ele)
# No to_line means fork to existing element.
if isnothing(fork.to_line)
if typeof(fork.to_ele) != Ele; error("Since to_line is not specified for fork $(fork.name),\n" *
"to_ele must be an actual element in a lattice."); end
lat = lattice(ele)
if isnothing(lat); error("Since to_line is not specified for fork $(fork.name),\n" *
"to_ele must be in a lattice and not external."); end

# Fork to new branch
else
lat = fork.branch.lat
isnothing(fork.to_ele) && isnothing(fork.to_line) &&
error("Neither to_ele nor to_line set for Fork element $(fork.name)")
isnothing(fork.to_ele) && typeof(fork.to_line) == Lattice &&
error("to_ele not set for fork element $(fork.name)")

lat = fork.branch.lat

# If to_line is a BeamLine then forking to a new branch
if typeof(fork.to_line) == BeamLine
typeof(fork.to_ele) == Ele && !isnothing(lattice(fork.to_ele)) && error(
"Confusion: to_line is a BeamLine and to_ele is associated with a Lattice for fork element $(fork.name).")

to_branch = new_tracking_branch!(lat, fork.to_line)
if typeof(fork.to_ele) == Ele; error(
"Since to_line is specified, to_ele must be something (String, Regex) that can be used with \n" *
"the `find` function to locate the element in the new branch and cannot be an existing element."); end

if fork.to_ele == ""
if isnothing(fork.to_ele)
fork.to_ele = to_branch[1]
else
to_ele = eles_search(lat, fork.to_ele)
if length(to_ele) == 0; error("to_ele ($(fork.to_ele)) not found in new branch for fork $(fork.name)."); end
if length(to_ele) > 1; error("Multiple elements matched to to_ele ($(fork.to_ele)) for fork $(fork.name)."); end
fork.to_ele = to_ele[1]
end
if typeof(fork.to_ele) == Ele
name = fork.to_ele.name
else # String
name = fork.to_ele
end

to_ele = fork.to_ele
if to_ele.ix_ele == 1
to_ele.from_forks = [fork]
to_eles = eles_search(to_branch, name)
if length(to_eles) == 0; error("to_ele $name not found in new branch for fork $(fork.name)."); end
if length(to_eles) > 1; error("Multiple elements matched to to_ele $name) for fork $(fork.name)."); end
fork.to_ele = to_eles[1]
end

# to_line is nothing means fork to existing element.
elseif typeof(fork.to_ele) == String
to_eles = eles_search(lat, fork.to_ele)
if length(to_eles) == 0; error("to_ele $name not found in new branch for fork $(fork.name)."); end
if length(to_eles) > 1; error("Multiple elements matched to to_ele $name) for fork $(fork.name)."); end
fork.to_ele = to_eles[1]
end

#

to_ele = fork.to_ele
if haskey(to_ele.pdict, :from_forks)
push!(to_ele.pdict[:from_forks], fork)
else
to_ele.pdict[:from_forks] = Vector{Ele}([fork])
end

return
Expand Down
13 changes: 8 additions & 5 deletions src/lat_construction.jl
Original file line number Diff line number Diff line change
Expand Up @@ -242,14 +242,17 @@ function new_tracking_branch!(lat::Lattice, bline::BeamLine)
for outer ib in reverse(1:length(lat.branch))
if lat.branch[ib].type == TrackingBranch; break; end
end
ib += 1

insert!(lat.branch, ib+1, Branch(name = bline.pdict[:name], lat = lat,
insert!(lat.branch, ib, Branch(name = bline.pdict[:name], lat = lat,
pdict = Dict{Symbol,Any}(:geometry => bline.pdict[:geometry])))
branch = lat.branch[ib+1]
for ix in ib:length(lat.branch)
lat.branch[ix].pdict[:ix_branch] = ix
end

branch.pdict[:ix_branch] = length(lat.branch)
branch = lat.branch[ib]
branch.pdict[:type] = TrackingBranch
if branch.name == ""; branch.name = "B" * string(length(lat.branch)); end
if branch.name == ""; branch.name = "B" * string(ib); end
info = LatticeConstructionInfo([], bline.pdict[:orientation], 0)

if haskey(bline.pdict, :species_ref); branch.ele[1].species_ref = bline.pdict[:species_ref]; end
Expand All @@ -262,7 +265,7 @@ function new_tracking_branch!(lat::Lattice, bline::BeamLine)
add_beamline_ele_to_branch!(branch, BeamLineItem(bline.pdict[:end_ele]))
else
@ele end_ele = Marker()
end_ele.pdict[:name] = "end$(length(lat.branch))"
end_ele.pdict[:name] = "end$(ib)"
add_beamline_ele_to_branch!(branch, BeamLineItem(end_ele))
end

Expand Down
10 changes: 6 additions & 4 deletions src/query.jl
Original file line number Diff line number Diff line change
Expand Up @@ -96,17 +96,19 @@ function ele_geometry(ele::Ele)
end

#---------------------------------------------------------------------------------------------------
# is_null(ele), is_null(branch)
# is_null(ele), is_null(branch), is_null(species

"""
is_null(ele::Ele)
is_null(branch::Branch
is_null(species::Species)

Test if argument is either of the `NULL_ELE` or `NULL_BRANCH` constants.
Test if argument is either of the `NULL_ELE`, `NULL_BRANCH`, or null species. constants.
""" is_null

is_null(ele::Ele) = return (ele.name == "NULL_ELE")
is_null(branch::Branch) = return (branch.name == "NULL_BRANCH")
is_null(ele::Ele) = (ele.name == "NULL_ELE")
is_null(branch::Branch) = (branch.name == "NULL_BRANCH")
is_null(species::Species) = (species == Species())

#---------------------------------------------------------------------------------------------------
# s_inbounds
Expand Down
10 changes: 5 additions & 5 deletions src/struct.jl
Original file line number Diff line number Diff line change
Expand Up @@ -732,17 +732,17 @@ end
Fork element parameters.

## Fields
• `to_line::Union{BeamLine,Nothing}` - Beam line to fork to. \\
• `to_ele::Union{String,Ele}` - On input: Element ID or element itself. \\
• `direction::Int` - Longitudinal Direction of injected beam. \\
• `propagate_reference::Bool` - Propagate reference species and energy? \\
• `to_line::Union{BeamLine,Nothing}` - Beam line to fork to. \\
• `to_ele::Union{String,Ele,Nothing}` - On input: Element ID or element itself. \\
• `direction::Int` - Longitudinal Direction of injected beam. \\
• `propagate_reference::Bool` - Propagate reference species and energy? \\


""" ForkParams

@kwdef mutable struct ForkParams <: EleParams
to_line::Union{BeamLine,Nothing} = nothing
to_ele::Union{String,Ele} = ""
to_ele::Union{String,Ele,Nothing} = nothing
direction::Int = +1
propagate_reference::Bool = true
end
Expand Down
28 changes: 14 additions & 14 deletions src/utilities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,8 @@

"""
lat_sanity_check(lat::Lattice)
Internal: lat_sanity_check(lat::Lattice, base_ele::Ele, pointed_ele::Ele, err_string::String)

Does some self consistency checks on a lattice and throws an error if there is a problem.

The internal version of `lat_sanity_check` is called by the public version and is not usable otherwise.
""" lat_sanity_check

function lat_sanity_check(lat::Lattice)
Expand Down Expand Up @@ -40,43 +37,43 @@ function lat_sanity_check(lat::Lattice)
end

if haskey(pdict, :girder)
lat_sanity_check(lat, ele, pdict[:girder], "girder")
check_pointed(lat, ele, pdict[:girder], "girder")
end

if haskey(pdict, :multipass_lord)
lat_sanity_check(lat, ele, pdict[:multipass_lord], "multipass lord")
check_pointed(lat, ele, pdict[:multipass_lord], "multipass lord")
end

if haskey(pdict, :ForkParams)
lat_sanity_check(lat, ele, pdict[:ForkParams].to_ele, "a forked-to element")
check_pointed(lat, ele, pdict[:ForkParams].to_ele, "a forked-to element")
if ele.L != 0; error("A Fork element may not have a non-zero length: $(ele_name(ele))"); end
end

if haskey(pdict, :OriginEleParams)
lat_sanity_check(lat, ele, pdict[:OriginEleParams].origin_ele, "the element's origin element")
check_pointed(lat, ele, pdict[:OriginEleParams].origin_ele, "the element's origin element")
end

if haskey(pdict, :super_lords)
for lord in pdict[:super_lords]
lat_sanity_check(lat, ele, lord, "super lord")
check_pointed(lat, ele, lord, "super lord")
end
end

if haskey(pdict, :slaves)
for slave in pdict[:slaves]
lat_sanity_check(lat, ele, slave, "slave")
check_pointed(lat, ele, slave, "slave")
end
end

if haskey(pdict, :from_forks)
for fork in pdict[:from_forks]
lat_sanity_check(lat, ele, fork, "a fork that is forking to this element")
check_pointed(lat, ele, fork, "a fork that is forking to this element")
end
end

if haskey(pdict, :GirderParams)
for slave in pdict[:GirderParams].supported
lat_sanity_check(lat, ele, slave, "supported element")
check_pointed(lat, ele, slave, "supported element")
end
end

Expand All @@ -85,12 +82,15 @@ function lat_sanity_check(lat::Lattice)
end

#-------------------
# Internal lat_sanity_check method
# Internal check_pointed method

function lat_sanity_check(lat::Lattice, base_ele::Ele, pointed_ele::Ele, err_string::String)
"""
Internal: check_pointed(lat::Lattice, base_ele::Ele, pointed_ele::Ele, err_string::String)
"""
function check_pointed(lat::Lattice, base_ele::Ele, pointed_ele::Ele, err_string::String)
pele = lat.branch[pointed_ele.branch.ix_branch].ele[pointed_ele.ix_ele]
if !(pointed_ele === pele)
error("Element $(ele_name(ele)) has a $err_string pointer to $(ele_name(pele)) but this\n" *
error("Element $(ele_name(base_ele)) has a $err_string pointer to $(ele_name(pele)) but this\n" *
" pointed to element is in a different lattice!!!")
end
end
Expand Down
18 changes: 15 additions & 3 deletions test/fork_test.jl
Original file line number Diff line number Diff line change
@@ -1,30 +1,42 @@
using AcceleratorLattice, Test

@ele begin1 = BeginningEle(species_ref = Species("electron"), pc_ref = 1e6)
@ele begin2 = BeginningEle()

@ele begin2 = BeginningEle(species_ref = Species("proton"), pc_ref = 1e7)
@ele begin3 = BeginningEle(species_ref = Species("photon"), E_tot_ref = 1e3)
@ele mk1 = Marker()
@ele bend1 = Bend(g = 1, angle = pi/2, Kn2L = 0.1, Bs3 = 0.2, En4 = 0.3, Es5L = 0.4)
@ele dft = Drift(L = 2)
bend2 = copy(bend1)
bend2.name = "bend2"
bend2.tilt_ref = pi/2

@ele fork1 = Fork()
@ele fork2 = Fork(propagate_reference = false)
@ele fork3 = Fork(to_ele = "mk1")

line1 = BeamLine([begin1, bend1, fork1])
line1 = BeamLine([begin1, bend1, fork1, mk1])
line2 = BeamLine([begin2, bend2])
line3 = BeamLine([begin3, dft, fork3])

fork1.to_line = line2
fork2.to_line = line3

lat = Lattice([line1])

superimpose!(fork2, lat["bend2"], offset = 0.2)

b1 = lat.branch[1]
b2 = lat.branch[2]



@testset "bend_bookkeeping" begin


end

# test fork superimpose
# test fork with multipass
# test fork to existing branch.
# make sure finite L throws error.
# check that forked to branch inherits reference energy from fork.
Expand Down
Loading