diff --git a/bmad-doc/other_manuals/long_term_tracking.pdf b/bmad-doc/other_manuals/long_term_tracking.pdf index a2692e76d3..ce4963f8d3 100644 Binary files a/bmad-doc/other_manuals/long_term_tracking.pdf and b/bmad-doc/other_manuals/long_term_tracking.pdf differ diff --git a/bmad/code/lat_ele_locator.f90 b/bmad/code/lat_ele_locator.f90 index 7ef6ef43ed..9777e1fe75 100644 --- a/bmad/code/lat_ele_locator.f90 +++ b/bmad/code/lat_ele_locator.f90 @@ -18,8 +18,10 @@ ! If a name and no branch is given, all branches are searched. ! If an index and no branch is given, branch 0 is assumed. ! ##N -- N = integer. N^th instance of ele_id in the branch. -! +/-offset -- Element offset. For example, "Q1+1" is the element after "Q1" and -! "Q1-2" is the second element before "Q1". +! +/-offset -- Element offset. For example, "Q1+1" is the element after "Q1" and "Q1-2" is the second element +! before "Q1". Modulo arithmatic is used so the offset wraps around the ends of the lattice. +! EG: "BEGINNING-1" gives the END element and "END+1" gives the BEGINNING element. +! ! Note: An old syntax that is still supported is: ! {key::}{branch>>}ele_id{##N} ! diff --git a/bsim/bbu/README.TXT b/bsim/bbu/README.TXT index acd9037e70..3ee7c874f7 100644 --- a/bsim/bbu/README.TXT +++ b/bsim/bbu/README.TXT @@ -64,7 +64,7 @@ Note: the output files will be stored in the working directory at which python3 ------------------------------------------------------- Command: python $DIST_BASE_DIR/bsim/bbu/test_run.py PHASE_X PHASE_Y ------------------------------------------------------- - Obtain (Ith v.s. tr/tb) for a lattice with two free phases (with coupled or decoupled optics) + Obtain (Ith versus tr/tb) for a lattice with two free phases (with coupled or decoupled optics) Phase advances are changed via a Taylor element in the lattice, named talylorW. The correct Twiss parameters must be extracted from the lattice and set in phase_scan.py. Output file: thresh_v_phase_PHASE.txt (produced at where it's called) diff --git a/bsim/long_term_tracking/doc/long_term_tracking.tex b/bsim/long_term_tracking/doc/long_term_tracking.tex index 7f81330d5e..e182a8ee3c 100644 --- a/bsim/long_term_tracking/doc/long_term_tracking.tex +++ b/bsim/long_term_tracking/doc/long_term_tracking.tex @@ -85,7 +85,7 @@ \title{Long Term Tracking Program} \author{} -\date{David Sagan \\ August 13, 2024} +\date{David Sagan \\ September 6, 2024} \begin{document} \pdfbookmark[1]{Contents}{contents} @@ -465,6 +465,14 @@ unnormalized strength \vn{B1_gradient} will remain fixed and normalized \vn{k1} will vary inversely with the reference momentum. +\ltt program parameters that affect ramping in the simulation are: +\begin{code} +ltt%ramping_start_time -- Default 0. +ltt%ramping_on -- Default False. +ltt%ramp_update_each_particle -- Default False. +ltt%ramp_particle_energy_without_rf -- Default False. +\end{code} + There are two modes that can be selected to determine how ramper elements are applied. If using \vn{"BEAM"} mode, and if\vn{ltt%ramp_update_each_particle} is set to True, rampers are applied to a given lattice element as each particle of the beam passes through the element using the time the @@ -487,21 +495,30 @@ If \vn{ltt%ramping_on} is set to True, ramping will be done if \vn{ltt%simulation_mode} is set to "\vn{BEAM}" or "\vn{SINGLE}". Ramping will be ignored in the other modes. -\ltt program parameters that affect ramping in the simulation are: -\begin{code} -ltt%ramping_on -ltt%ramping_start_time -\end{code} - When ramping, the \vn{ltt%simulation_mode} (\sref{s:track.methods}) must be set to "\vn{BMAD}". The program will detect if there is a conflict and issue an error message and stop. +Normally, when the reference energy \vn{E_tot} or the reference momentum \vn{p0c} is varied by a +ramper element, the phase space $p_z$ of the particles are adjusted in tandem to keep the particle +momentum $(1 + pz) * p0c$ invariant. This also keeps the particle energy invariant. This mirrors +what is actually happening in a machine: It is the energy kick in the RF cavities that makes particles +change energy, not the change in field strengths that result from changing the reference energy. +The RF kick will result in synchrotron oscillations. For some simulations, it is useful to see what +would happen if the synchrotron oscillations were magically ``turned off''. +This unphysical simulation can be done by turning off the RF in the lattice and by setting +\begin{code} +ltt%ramp_particle_energy_without_rf = True +\end{code} +When this is set, the $p_z$ of the particles are {\em not} adjusted when the reference energy is +adjusted. And since the RF is off, $p_z$ will be an invariant and there are no synchrotron +oscillations. + The \vn{ltt%ix_turn_start} parameter can be used to start tracking at any turn. This can be useful if a simulation is accidentally interrupted. In this case the beam positions can be saved by setting \begin{code} - ltt%beam_output_file - ltt%beam_output_every_n_turns - ltt%output_only_last_turns +ltt%beam_output_file +ltt%beam_output_every_n_turns +ltt%output_only_last_turns \end{code} With ramping, the concept of the closed orbit (possibly needed to initialize particle positions) is @@ -696,6 +713,7 @@ ltt%lat_file = "lat.bmad" ! Bmad lattice file ltt%ramping_on = F ltt%ramp_update_each_particle = F + ltt%ramp_particle_energy_without_rf = F ltt%ramping_start_time = 0 ltt%extraction_method = "" ltt%simulation_mode = "BEAM" @@ -876,6 +894,10 @@ \subsection{Simulation Parameters} the \ltt program will additionally impose a 0.9~meters aperture independent of the setting of \vn{ltt%ptc_aperture}. % +\item[ltt\%ramp_particle_energy_without_rf] \Newline +Simulate the unphysical situation where particle energy moves in tandem with the reference energy? +See \sref{s:ramp} for more details. +% \item[ltt\%ramp_update_each_particle] \Newline Default is False which means only apply rampers to a given lattice element once per beam passage (\sref{s:ramp}). This parameter is only used for \vn{"BEAM"} mode. diff --git a/bsim/modules/lt_tracking_mod.f90 b/bsim/modules/lt_tracking_mod.f90 index ee8caae0df..85e7f73a9d 100644 --- a/bsim/modules/lt_tracking_mod.f90 +++ b/bsim/modules/lt_tracking_mod.f90 @@ -83,6 +83,7 @@ module lt_tracking_mod logical :: only_live_particles_out = .true. logical :: ramping_on = .false. logical :: ramp_update_each_particle = .false. + logical :: ramp_particle_energy_without_rf = .false. logical :: rfcavity_on = .true. logical :: add_closed_orbit_to_init_position = .true. logical :: symplectic_map_tracking = .false. @@ -906,6 +907,7 @@ subroutine ltt_write_preheader(iu, lttp, ltt_com, print_this) call ltt_write_line('# ltt%ramping_on = ' // logic_str(lttp%ramping_on), lttp, iu, print_this) call ltt_write_line('# ltt%output_combined_bunches = ' // logic_str(lttp%output_combined_bunches), lttp, iu, print_this) call ltt_write_line('# ltt%ramp_update_each_particle = ' // logic_str(lttp%ramp_update_each_particle), lttp, iu, print_this) +call ltt_write_line('# ltt%ramp_particle_energy_without_rf = ' // logic_str(lttp%ramp_particle_energy_without_rf), lttp, iu, print_this) call ltt_write_line('# ltt%ramping_start_time = ' // real_str(lttp%ramping_start_time, 6), lttp, iu, print_this) call ltt_write_line('# ltt%set_beambeam_z_crossing = ' // logic_str(lttp%set_beambeam_z_crossing), lttp, iu, print_this) call ltt_write_line('# ltt%random_seed = ' // int_str(lttp%random_seed), lttp, iu, print_this) @@ -2318,6 +2320,7 @@ subroutine ltt_write_params_header(lttp, ltt_com, iu, n_particle, n_bunch) write (iu, '(a, i8)') '# n_turns = ', lttp%n_turns write (iu, '(a, l1)') '# ramping_on = ', lttp%ramping_on write (iu, '(a, l1)') '# ramp_update_each_particle = ', lttp%ramp_update_each_particle +write (iu, '(a, l1)') '# ramp_particle_energy_without_rf = ', lttp%ramp_particle_energy_without_rf write (iu, '(2a)') '# ramping_start_time = ', real_str(lttp%ramping_start_time, 6) write (iu, '(a, i8)') '# particle_output_every_n_turns = ', lttp%particle_output_every_n_turns write (iu, '(a, i8)') '# averages_output_every_n_turns = ', lttp%averages_output_every_n_turns @@ -3438,7 +3441,10 @@ subroutine ltt_track1_bunch_hook (bunch, ele, err, centroid, direction, finished r = orb%p0c / ele%value(p0c_start$) orb%vec(2) = r * orb%vec(2) orb%vec(4) = r * orb%vec(4) - orb%vec(6) = r * orb%vec(6) + (orb%p0c - ele%value(p0c_start$)) / ele%value(p0c_start$) + ! Normally need to adjust pz (vec(6)) so that the particle energy (1 + orb%vec(6)) * orb%p0c is not changed. + if (.not. ltt_params_global%ramp_particle_energy_without_rf) then + orb%vec(6) = r * orb%vec(6) + (orb%p0c - ele%value(p0c_start$)) / ele%value(p0c_start$) + endif orb%p0c = ele%value(p0c_start$) enddo @@ -3537,7 +3543,10 @@ subroutine ltt_track1_preprocess (start_orb, ele, param, err_flag, finished, rad r = start_orb%p0c / ele%value(p0c_start$) start_orb%vec(2) = r * start_orb%vec(2) start_orb%vec(4) = r * start_orb%vec(4) -start_orb%vec(6) = r * start_orb%vec(6) + (start_orb%p0c - ele%value(p0c_start$)) / ele%value(p0c_start$) +! Normally need to adjust pz (vec(6)) so that the particle energy (1 + orb%vec(6)) * orb%p0c is not changed. +if (.not. ltt_params_global%ramp_particle_energy_without_rf) then + start_orb%vec(6) = r * start_orb%vec(6) + (start_orb%p0c - ele%value(p0c_start$)) / ele%value(p0c_start$) +endif start_orb%p0c = ele%value(p0c_start$) end subroutine ltt_track1_preprocess diff --git a/tao/version/tao_version_mod.f90 b/tao/version/tao_version_mod.f90 index 691b7a749e..b7a6569cc9 100644 --- a/tao/version/tao_version_mod.f90 +++ b/tao/version/tao_version_mod.f90 @@ -6,5 +6,5 @@ !- module tao_version_mod -character(*), parameter :: tao_version_date = "2024/08/28 21:24:21" +character(*), parameter :: tao_version_date = "2024/09/04 22:30:30" end module