Skip to content

Commit

Permalink
Merge pull request #570 from bmad-sim/devel/step28
Browse files Browse the repository at this point in the history
Devel/step28
  • Loading branch information
DavidSagan authored Oct 23, 2023
2 parents e55dc76 + 802be10 commit ae5762e
Show file tree
Hide file tree
Showing 31 changed files with 14,031 additions and 160 deletions.
25 changes: 14 additions & 11 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,21 @@ bmad-doc/cookbook_bmad_tao/doc/cookbook_bmad_tao.pdf
bmad-doc/cookbook_bmad_tao/doc/cookbook_bmad_tao.toc
bmad-doc/tao_examples/csr_beam_tracking/csr_wake.dat

bmad/doc/*aux
bmad/doc/bmad.idx
bmad/doc/bmad.ilg
bmad/doc/bmad.ind
bmad/doc/bmad.lof
bmad/doc/bmad.log
bmad/doc/bmad.lot
bmad/doc/bmad.out
bmad/doc/bmad.pdf
bmad/doc/bmad.rdx
bmad/doc/bmad.rnd
bmad/doc/bmad.toc
bsim/**/doc/*.pdf

**/doc/*.idx
**/doc/*.ilg
**/doc/*.ind
**/doc/*.lof
**/doc/*.log
**/doc/*.lot
**/doc/*.out
**/doc/*.rdx
**/doc/*.rnd
**/doc/*.toc
**/doc/*.aux
**/2www.pl

regression_tests/*/output.now
regression_tests/*/lat.bmad
Expand Down
Binary file modified bmad-doc/other_manuals/sodom2.pdf
Binary file not shown.
Binary file modified bmad-doc/other_manuals/tune_scan.pdf
Binary file not shown.
3 changes: 1 addition & 2 deletions bmad/code/set_tune.f90
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ function set_tune (phi_a_set, phi_b_set, dk1, eles, branch, orb, print_err) resu
logical, optional :: print_err
logical ok, err, rf_on, master_saved

character(20) :: r_name = 'set_tune'
character(*), parameter :: r_name = 'set_tune'
real(rp), dimension(2) :: phi_array

! Init
Expand Down Expand Up @@ -150,5 +150,4 @@ function set_tune (phi_a_set, phi_b_set, dk1, eles, branch, orb, print_err) resu
'SET TUNE: \2f\ ', &
r_array = [phi_a/twopi, phi_b/twopi, phi_a_set/twopi, phi_b_set/twopi ])


end function
189 changes: 189 additions & 0 deletions bmad/code/set_tune_via_group_knobs.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
!+
! Function set_tune_via_group_knobs (phi_set, branch, group_knobs, orb, print_err) result (ok)
!
! Function to Q_tune a lattice branch. The tunes will be set to within 0.001 radian (0.06 deg).
! Note: The tune is computed with reference to the closed orbit.
!
! Input:
! phi_set(2) -- real(rp): Set tunes (radians).
! branch -- branch_struct: Lattice branch to tune.
! group_knobs(2) -- character(*): Names of group knobs to vary.
! orb(0)%vec(6) -- Coord_struct: If RF is off: Energy dE/E at which the tune is computed.
! print_err -- logical, optional: Print error message if there is a problem? Default is True.
!
! Output:
! branch -- branch_struct: Q_tuned lattice branch
! orb(0:) -- coord_struct: New closed orbit.
! ok -- logical: Set True if everything is ok. False otherwise.
!-

function set_tune_via_group_knobs (phi_set, branch, group_knobs, orb, print_err) result (ok)

use bmad_interface, except_dummy => set_tune_via_group_knobs

implicit none

type (branch_struct), target :: branch
type (ele_struct), pointer :: group1, group2
type (ele_struct) :: ave
type (ele_struct), pointer :: ele
type (coord_struct), allocatable :: orb(:)

real(rp) phi_set(2), dphi_a, dphi_b, dQ_max
real(rp) phi_a, phi_b, d_a1, d_a2, d_b1, d_b2, det
real(rp) d1, d2, del0
real(rp) :: phi_array(2)
real(rp), allocatable :: deriv1(:), deriv2(:), kinit(:)

integer i, j, status, n_loc

logical, optional :: print_err
logical ok, err, rf_on, master_saved

character(*) group_knobs(2)
character(*), parameter :: r_name = 'set_tune_via_group_knobs'

! Init

dQ_max = 0.001
del0 = 0.001
ok = .false.
rf_on = rf_is_on(branch)

allocate(kinit(branch%n_ele_track), deriv1(branch%n_ele_track), deriv2(branch%n_ele_track))
deriv1 = 0; deriv2 = 0

group1 => find_group(group_knobs(1), branch, del0, kinit, deriv1, err); if (err) return
group2 => find_group(group_knobs(2), branch, del0, kinit, deriv2, err); if (err) return

! Q tune

do i = 1, 10
call lattice_bookkeeper(branch%lat)

if (rf_on) then
call closed_orbit_calc (branch%lat, orb, 6, 1, branch%ix_branch, err, print_err)
else
call closed_orbit_calc (branch%lat, orb, 4, 1, branch%ix_branch, err, print_err)
endif

if (err) return

call lat_make_mat6 (branch%lat, -1, orb, branch%ix_branch)

call twiss_at_start(branch%lat, status, branch%ix_branch, print_err)
if (status /= ok$) return

call twiss_propagate_all (branch%lat, branch%ix_branch, err)
if (err) return

phi_a = branch%ele(branch%n_ele_track)%a%phi
phi_b = branch%ele(branch%n_ele_track)%b%phi
dphi_a = phi_set(1) - phi_a
dphi_b = phi_set(2) - phi_b
if (abs(dphi_a) < dQ_max .and. abs(dphi_b) < dQ_max) then
ok = .true.
return
endif

d_a1 = 0
d_a2 = 0
d_b1 = 0
d_b2 = 0

do j = 1, branch%n_ele_track
if (deriv1(j) == 0 .and. deriv2(j) == 0) cycle
ele => branch%ele(j)
call twiss_at_element (ele, average = ave)

if (deriv1(j) /= 0) then
d_a1 = d_a1 + deriv1(j) * ave%a%beta * ave%value(l$) / 2
d_b1 = d_b1 - deriv1(j) * ave%b%beta * ave%value(l$) / 2
endif

if (deriv2(j) /= 0) then
d_a2 = d_a2 + deriv2(j) * ave%a%beta * ave%value(l$) / 2
d_b2 = d_b2 - deriv2(j) * ave%b%beta * ave%value(l$) / 2
endif
enddo

det = d_a1 * d_b2 - d_a2 * d_b1
d1 = (d_b2 * dphi_a - d_b1 * dphi_b) / det
d2 = (d_a1 * dphi_b - d_a2 * dphi_a) / det

! Put in the changes

group1%control%var(1)%value = group1%control%var(1)%value + d1
group2%control%var(1)%value = group2%control%var(1)%value + d2

call set_flags_for_changed_attribute (group1)
call set_flags_for_changed_attribute (group2)
enddo

phi_array(1) = phi_a/twopi
phi_array(2) = phi_b/twopi
phi_array(1) = phi_set(1)/twopi
phi_array(2) = phi_set(2)/twopi
call out_io (s_error$, r_name, 'CANNOT GET TUNE RIGHT.', &
'CURRENT TUNE: \2f\ ', &
'SET TUNE: \2f\ ', &
r_array = [phi_a/twopi, phi_b/twopi, phi_set(1)/twopi, phi_set(2)/twopi ])

!--------------------------------------------------------------------------------
contains

function find_group(name, branch, del0, kinit, deriv, err) result (group_ele)

type (branch_struct) branch
type (ele_struct), pointer :: group_ele, ele
type (ele_pointer_struct), allocatable ::eles(:)
character(*) name
real(rp) del0, kinit(:), deriv(:)
integer i, j, n_loc
logical err

!

call lat_ele_locator(name, branch%lat, eles, n_loc, err, ix_dflt_branch = branch%ix_branch)
if (err) return
err = .true.

if (n_loc == 0) then
call out_io(s_error$, r_name, 'Group element not found: ' // ele%name)
return
endif

if (n_loc > 1) then
call out_io(s_error$, r_name, 'Multiple lattice elements match group name: ' // ele%name)
return
endif

group_ele => eles(1)%ele
if (group_ele%key /= group$) then
call out_io(s_error$, r_name, 'Element is not a group type element which is needed for tune variation: ' // ele%name)
return
endif

!

kinit = branch%ele(1:branch%n_ele_track)%value(k1$)

group_ele%control%var(1)%value = group_ele%control%var(1)%value + del0
call control_bookkeeper(branch%lat, group_ele)

do i = 1, branch%n_ele_track
ele => branch%ele(i)
if (ele%key /= quadrupole$) cycle
if (ele%value(tilt$) /= 0) cycle
if (ele%value(k1$) == kinit(i)) cycle
deriv(i) = (ele%value(k1$) - kinit(i)) / del0
enddo

group_ele%control%var(1)%value = group_ele%control%var(1)%value - del0
call control_bookkeeper(branch%lat, group_ele)

err = .false.

end function find_group

end function
6 changes: 3 additions & 3 deletions bmad/doc/charged-tracking.tex
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ \section{Relative Versus Absolute Time Tracking}
upstream end of the element. $t_\text{eff}$ is defined such that a particle entering an element
with $z = 0$ has $t_\text{eff} = 0$.

With \vn{absolute time tracking}, and \vn{bmad_com%absolute_time_ref_shift} set to True (the
With \vn{absolute time tracking}, and \vn{bmad_com[absolute_time_ref_shift]} set to True (the
default), $t_\text{eff}$ is defined by
\begin{equation}
t_\text{eff}(s) = t(s) - t_0(s_\text{ent})
Expand All @@ -58,7 +58,7 @@ \section{Relative Versus Absolute Time Tracking}
reference particle at the entrance end of the element on the first pass. For absolute time tracking,
it is important to keep in mind that $t_0(s_\text{ent})$ is a property of the element independent of
how tracking is done. Thus, if a particle goes through a particular element multiple times, the
value of $t_\text{ent}$ will be the same for each transit. If \vn{bmad_com%absolute_time_ref_shift}
value of $t_\text{ent}$ will be the same for each transit. If \vn{bmad_com[absolute_time_ref_shift]}
set to True, $t_\text{eff}$ is simply
\begin{equation}
t_\text{eff}(s) = t(s)
Expand All @@ -67,7 +67,7 @@ \section{Relative Versus Absolute Time Tracking}
To understand the difference between relative and absolute time tracking, consider a particle
traveling on the reference orbit along side the reference particle in a circular ring with one RF
cavity. This particle always has $z = 0$ and thus, with \vn{relative time tracking}, $t_\text{eff}$
will always be zero (assuming \vn{bmad_com%absolute_time_ref_shift} is set to True) at the entrance
will always be zero (assuming \vn{bmad_com[absolute_time_ref_shift] is set to True) at the entrance
to the cavity. With \vn{absolute time tracking}, the particle, on the first turn, will have
$t_\text{eff}$ equal to zero. However, on subsequent turns (or subsequent passes if using
multipass), the time will increase by the revolution time $t_\text{C}$ on each turn. If the RF
Expand Down
6 changes: 5 additions & 1 deletion bmad/doc/lattice-file.tex
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,8 @@ \section{Particle Species Names}
The curly brackets \{...\} denote optional prefixes and suffixes. \vn{AA} here is the
atomic symbol, \vn{\#nnn} is the number of nucleons, and \vn{ccc} is the charge. Examples:
\begin{example}
parameter[particle] = \#12C+3 ! Triply charged carbon-12
parameter[particle] = \#12C+3 ! Triply charged carbon-12.
parameter[p0c] = 12 * 500e6 ! Reference momentum is total momentum for particle.
parameter[particle] = He-- ! Doubly charged He.
\end{example}
If the number of nucleons is given, the appropriate weight for that isotope is used. If the number
Expand All @@ -714,6 +715,9 @@ \section{Particle Species Names}
mass shifts due to finite electron binding energies. This shift is small typically being well less
than 1\% of the mass of the electron.
Note: When setting the reference momentum \vn{parameter[p0c]}, or reference total energy
\vn{parameter[E_tot]}, the total for the whole particle is used. {\em Not} the value per nucleon.
Another group of particles are the ``known'' molecules. The syntax for these are:
\begin{example}
BBB\{@Mxxxx\}\{ccc\}
Expand Down
8 changes: 4 additions & 4 deletions bmad/modules/attribute_mod.f90
Original file line number Diff line number Diff line change
Expand Up @@ -1405,14 +1405,14 @@ subroutine init_attribute_name_array ()
call init_attribute_name1 (crab_cavity$, cylindrical_map$, 'CYLINDRICAL_MAP')
call init_attribute_name1 (crab_cavity$, gen_grad_map$, 'GEN_GRAD_MAP')
call init_attribute_name1 (crab_cavity$, grid_field$, 'GRID_FIELD')
call init_attribute_name1 (crab_cavity$, gradient$, 'GRADIENT', dependent$)
call init_attribute_name1 (crab_cavity$, gradient$, 'GRADIENT')
call init_attribute_name1 (crab_cavity$, rf_frequency$, 'RF_FREQUENCY')
call init_attribute_name1 (crab_cavity$, rf_wavelength$, 'RF_WAVELENGTH', dependent$)
call init_attribute_name1 (crab_cavity$, rf_clock_harmonic$, 'rf_clock_harminic', private$)
call init_attribute_name1 (crab_cavity$, field_autoscale$, 'FIELD_AUTOSCALE', private$) ! Not yet used
call init_attribute_name1 (crab_cavity$, phi0_autoscale$, 'PHI0_AUTOSCALE', private$) ! Not yet used
call init_attribute_name1 (crab_cavity$, field_autoscale$, 'FIELD_AUTOSCALE', private$) ! Not yet used
call init_attribute_name1 (crab_cavity$, phi0_autoscale$, 'PHI0_AUTOSCALE', private$) ! Not yet used
call init_attribute_name1 (crab_cavity$, autoscale_amplitude$, 'AUTOSCALE_AMPLITUDE', private$) ! Not yet used
call init_attribute_name1 (crab_cavity$, autoscale_phase$, 'AUTOSCALE_PHASE', private$) ! Not yet used
call init_attribute_name1 (crab_cavity$, autoscale_phase$, 'AUTOSCALE_PHASE', private$) ! Not yet used
call init_attribute_name1 (crab_cavity$, field_master$, 'FIELD_MASTER')

call init_attribute_name1 (rfcavity$, longitudinal_mode$, 'LONGITUDINAL_MODE')
Expand Down
11 changes: 11 additions & 0 deletions bmad/modules/bmad_routine_interface.f90
Original file line number Diff line number Diff line change
Expand Up @@ -2163,6 +2163,17 @@ function set_tune (phi_a_set, phi_b_set, dk1, eles, branch, orb, print_err) resu
logical ok
end function

function set_tune_via_group_knobs (phi_set, branch, group_knobs, orb, print_err) result (ok)
import
implicit none
type (branch_struct), target :: branch
type (coord_struct), allocatable :: orb(:)
character(*) group_knobs(2)
real(rp) phi_set(2)
logical, optional :: print_err
logical ok
end function

function significant_difference (value1, value2, abs_tol, rel_tol) result (is_different)
import
implicit none
Expand Down
Loading

0 comments on commit ae5762e

Please sign in to comment.