diff --git a/bmad/code/pointer_to_next_ele.f90 b/bmad/code/pointer_to_next_ele.f90 index 9db19a48f..6b4139eae 100644 --- a/bmad/code/pointer_to_next_ele.f90 +++ b/bmad/code/pointer_to_next_ele.f90 @@ -1,12 +1,12 @@ !+ -! Function pointer_to_next_ele (this_ele, offset, skip_beginning, follow_fork) result (next_ele) +! Function pointer_to_next_ele (this_ele, offset, skip_beginning, follow_fork, ix_multipass) result (next_ele) ! ! Function to return a pointer to the next (if offset = 1) tracking element relative to this_ele. ! -! If the this_ele is a super_lord element, the appropriate element in the tracking +! If the this_ele is a super_lord or girder_lord, the appropriate element in the tracking ! part of the lattice is returned. ! -! If this_ele is a lord element but not a super_lord then this is an error since +! If this_ele is a lord element but not a super_lord nor a girder_lord then this is an error since ! it is not clear what to do in this case. ! ! This routine will always wrap around between branch end and branch beginning @@ -26,12 +26,15 @@ ! when wrapping around. Default is False. ! follow_fork -- logical, optional: If True then fork at any fork element. ! Default is False. -! +! ix_multipass -- integer, optional: Default = 1. Used to select the multipass branch if +! this_ele is a multipass_lord. +! +! Output: ! next_ele -- ele_struct, pointer: Element after this_ele (if offset = 1). ! Nullified if there is an error. EG bad this_ele. !- -function pointer_to_next_ele (this_ele, offset, skip_beginning, follow_fork) result (next_ele) +function pointer_to_next_ele (this_ele, offset, skip_beginning, follow_fork, ix_multipass) result (next_ele) use bmad_routine_interface, dummy => pointer_to_next_ele @@ -42,7 +45,7 @@ function pointer_to_next_ele (this_ele, offset, skip_beginning, follow_fork) res type (ele_struct), pointer :: an_ele type (branch_struct), pointer :: branch -integer, optional :: offset +integer, optional :: offset, ix_multipass integer i, ix_ele, n_off logical, optional :: skip_beginning, follow_fork @@ -65,16 +68,26 @@ function pointer_to_next_ele (this_ele, offset, skip_beginning, follow_fork) res ! Initially point to the first or last slave element so that this routine ! will return a pointer to an element that is not a slave of this_ele. -if (this_ele%ix_ele > this_ele%branch%n_ele_track) then ! Is a lord - if (this_ele%lord_status /= super_lord$) return ! Error - if (n_off > 0) then - an_ele => pointer_to_slave(this_ele, this_ele%n_slave) - else - an_ele => pointer_to_slave(this_ele, 1) - endif -else - an_ele => this_ele -endif +an_ele => this_ele + +do + if (an_ele%ix_ele <= an_ele%branch%n_ele_track) exit ! Is not a lord + + select case (an_ele%lord_status) + case (multipass_lord$) + an_ele => pointer_to_slave(an_ele, integer_option(1, ix_multipass)) + + case (super_lord$, girder_lord$) + if (n_off > 0) then + an_ele => pointer_to_slave(an_ele, an_ele%n_slave) + else + an_ele => pointer_to_slave(an_ele, 1) + endif + + case default + return ! Error + end select +enddo ! Apply offset. ! If follow_fork = True then must check all elements in between for a possible fork element. diff --git a/bmad/modules/bmad_routine_interface.f90 b/bmad/modules/bmad_routine_interface.f90 index bef0793c2..d09d25a2e 100644 --- a/bmad/modules/bmad_routine_interface.f90 +++ b/bmad/modules/bmad_routine_interface.f90 @@ -2189,12 +2189,12 @@ function pointer_to_multipass_lord (ele, ix_pass, super_lord) result (multi_lord type (ele_struct), pointer, optional :: super_lord end function -function pointer_to_next_ele (this_ele, offset, skip_beginning, follow_fork) result (next_ele) +function pointer_to_next_ele (this_ele, offset, skip_beginning, follow_fork, ix_multipass) result (next_ele) import implicit none type (ele_struct), target :: this_ele type (ele_struct), pointer :: next_ele - integer, optional :: offset + integer, optional :: offset, ix_multipass logical, optional :: skip_beginning, follow_fork end function diff --git a/bmad/parsing/bmad_parser_mod.f90 b/bmad/parsing/bmad_parser_mod.f90 index 394105e98..dde0e7a5e 100644 --- a/bmad/parsing/bmad_parser_mod.f90 +++ b/bmad/parsing/bmad_parser_mod.f90 @@ -1622,11 +1622,13 @@ subroutine parser_read_sr_wake (ele, delim, delim_found, err_flag) srz%smoothing_sigma = c_light * srz%smoothing_sigma endif - if (srz%smoothing_sigma /= 0) then - ns = max(1, nint(3*srz%smoothing_sigma / srz%dz)) + f = srz%smoothing_sigma / srz%dz + ns = nint(3.0_rp * f) + + if (ns /= 0) then allocate (gauss(-ns:ns)) do i = -ns, ns - gauss(i) = exp(-0.5 * i * (srz%dz / srz%smoothing_sigma)**2) + gauss(i) = exp(-0.5_rp * i / f**2) enddo srz%fw = 0 diff --git a/regression_tests/multipass_test/multipass_test.f90 b/regression_tests/multipass_test/multipass_test.f90 index 9924f71f2..ea2f289d9 100644 --- a/regression_tests/multipass_test/multipass_test.f90 +++ b/regression_tests/multipass_test/multipass_test.f90 @@ -6,7 +6,7 @@ program multipass_test implicit none type (lat_struct), target :: lat, lat2 -type (ele_struct), pointer :: ele, ele2, lord +type (ele_struct), pointer :: ele, ele0, ele2, lord, ele3, ele4 type (ele_pointer_struct), allocatable :: eles(:) type (rf_stair_step_struct), pointer :: step @@ -16,6 +16,26 @@ program multipass_test open (1, file = 'output.now') +! Girder and multipass + +call bmad_parser ('multipass_with_girder.bmad', lat) +do ie = 1, lat%n_ele_track + ele => lat%ele(ie) + ele0 => pointer_to_next_ele(ele, -1) + ele2 => pointer_to_next_ele(ele, 1) + write (1, '(3a)') quote(ele%name), ' STR ', quote(trim(ele0%name) // ' + ' // trim(ele2%name)) +enddo + +do ie = lat%n_ele_track+1, lat%n_ele_max + ele => lat%ele(ie) + ele0 => pointer_to_next_ele(ele, -1) + ele2 => pointer_to_next_ele(ele, 1) + ele3 => pointer_to_next_ele(ele, -1, ix_multipass = 2) + ele4 => pointer_to_next_ele(ele, 1, ix_multipass = 2) + write (1, '(3a)') quote(ele%name), ' STR ', quote(trim(ele0%name) // ' + ' // trim(ele2%name) // & + ' + ' // trim(ele3%name) // ' + ' // trim(ele4%name)) +enddo + ! Space_charge_method test call bmad_parser ('multipass_and_superimpose.bmad', lat) @@ -33,7 +53,6 @@ program multipass_test call lat_ele_locator('CAVITY1', lat, eles, n_loc) lord => eles(1)%ele - do is = 0, 2 if (is == 0) then ele => lord @@ -52,8 +71,6 @@ program multipass_test ele => eles(1)%ele write (1, '(a, 2es22.14)') '"END-energy" REL 1E-8', ele%value(p0c$), ele%value(E_tot$) - - ! Forking with a branch element call bmad_parser ('branch_fork.bmad', lat) @@ -83,7 +100,7 @@ program multipass_test write (1, '(3a)') '"MS-12" STR "', trim(lat%ele(12)%name), '"' write (1, '(3a)') '"MS-13" STR "', trim(lat%ele(13)%name), '"' -! fiducial and flexible patch +! Fiducial and flexible patch call bmad_parser ('patch.bmad', lat) call write_bmad_lattice_file ('lat_out2.bmad', lat) diff --git a/regression_tests/multipass_test/multipass_with_girder.bmad b/regression_tests/multipass_test/multipass_with_girder.bmad new file mode 100644 index 000000000..b08479fda --- /dev/null +++ b/regression_tests/multipass_test/multipass_with_girder.bmad @@ -0,0 +1,19 @@ +no_digested + +beginning[beta_a] = 1 +beginning[beta_b] = 1 +beginning[e_tot] = 100e6 +parameter[geometry] = open + +f = 0 +p1: sbend, L = 1, angle = pi/2 * f, ref_tilt = pi/2 +p2: sbend, L = 2, angle = pi/2 * f +g1: girder = {p1, p2}, x_offset = 0.001 + +lat: line[multipass] = (p1, p2) +lat2: line = (lat, lat) +use, lat2 + +m1: marker, superimpose, ref = p1 + + diff --git a/regression_tests/multipass_test/output.correct b/regression_tests/multipass_test/output.correct index 897d242c2..33809519e 100644 --- a/regression_tests/multipass_test/output.correct +++ b/regression_tests/multipass_test/output.correct @@ -1,3 +1,18 @@ +"P1\1#1" STR "BEGINNING + M1\1" +"M1\1" STR "P1\1#1 + P1\1#2" +"P1\1#2" STR "M1\1 + P2\1" +"P2\1" STR "P1\1#2 + P1\2#1" +"P1\2#1" STR "P2\1 + M1\2" +"M1\2" STR "P1\2#1 + P1\2#2" +"P1\2#2" STR "M1\2 + P2\2" +"P2\2" STR "P1\2#2 + END" +"END" STR "P2\2 + BEGINNING" +"P1\1" STR "BEGINNING + P2\1 + BEGINNING + P2\1" +"P1\2" STR "P2\1 + P2\2 + P2\1 + P2\2" +"M1" STR "P1\1#1 + P1\1#2 + P1\2#1 + P1\2#2" +"P2" STR "P1\1#2 + P1\2#1 + P1\2#2 + END" +"P1" STR "BEGINNING + P2\1 + P2\1 + P2\2" +"G1" STR "BEGINNING + P1\2#1 + P2\1 + END" "scm-1DRI01\1#1" STR "Slice" "Slice" "ref_time-1" ABS 1E-16 5.82081208740982E-09 "scm-2DRI01\1\Q01\1" STR "FFT_3D" "FFT_3D" diff --git a/regression_tests/tao_color_test/output.correct b/regression_tests/tao_color_test/output.correct index 8f7f914e4..03f982861 100644 --- a/regression_tests/tao_color_test/output.correct +++ b/regression_tests/tao_color_test/output.correct @@ -1,22 +1,22 @@ -"css4_name" STR teal -"css4_name_mixed_case" STR teal -"css4_name_upper" STR teal -"css4_name_salmon" STR salmon -"css4_name_gold" STR gold -"original_name" STR red -"original_name_blue" STR blue -"original_name_upper" STR red -"hex_6digit" STR #FF5733 -"hex_6digit_lower" STR #FF5733 -"hex_6digit_mixed" STR #FF5733 -"hex_3digit" STR #F53 -"hex_3digit_lower" STR #ABC -"rgb_format" STR RGB(0,128,255) -"rgb_format_spaces" STR RGB(255,0,128) -"rgb_lower_prefix" STR RGB(10,20,30) -"rgb_mixed_prefix" STR RGB(1,2,3) -"rgb_four_values" STR True -"invalid_color_rejected" STR True -"label_color_css4" STR teal -"label_color_upper" STR gold -"label_color_hex" STR #FF0000 +"css4_name" STR "teal" +"css4_name_mixed_case" STR "teal" +"css4_name_upper" STR "teal" +"css4_name_salmon" STR "salmon" +"css4_name_gold" STR "gold" +"original_name" STR "red" +"original_name_blue" STR "blue" +"original_name_upper" STR "red" +"hex_6digit" STR "#FF5733" +"hex_6digit_lower" STR "#FF5733" +"hex_6digit_mixed" STR "#FF5733" +"hex_3digit" STR "#F53" +"hex_3digit_lower" STR "#ABC" +"rgb_format" STR "RGB(0,128,255)" +"rgb_format_spaces" STR "RGB(255,0,128)" +"rgb_lower_prefix" STR "RGB(10,20,30)" +"rgb_mixed_prefix" STR "RGB(1,2,3)" +"rgb_four_values" STR "True" +"invalid_color_rejected" STR "True" +"label_color_css4" STR "teal" +"label_color_upper" STR "gold" +"label_color_hex" STR "#FF0000" diff --git a/regression_tests/tao_color_test/run.py b/regression_tests/tao_color_test/run.py index e5fb312cb..e3f740ef5 100644 --- a/regression_tests/tao_color_test/run.py +++ b/regression_tests/tao_color_test/run.py @@ -67,11 +67,11 @@ if expected is None: # Expect rejection (error message) - results.append(f'"{label}" STR {has_error}') + results.append(f'"{label}" STR "{has_error}"') elif has_error: - results.append(f'"{label}" STR ERROR') + results.append(f'"{label}" STR "ERROR"') else: - results.append(f'"{label}" STR {actual}') + results.append(f'"{label}" STR "{actual}"') # Test that an invalid color produces an error (doesn't crash) cmd = f"set curve {curve} line%color = not_a_color;quit" @@ -79,7 +79,7 @@ proc = subprocess.run(exe, shell=True, capture_output=True, text=True) # Should get an error message but not crash (exit 0) has_error_msg = "ERROR" in proc.stdout -results.append(f'"invalid_color_rejected" STR {has_error_msg}') +results.append(f'"invalid_color_rejected" STR "{has_error_msg}"') # Test label_color via python plot_graph command label_color_tests = [ @@ -109,9 +109,9 @@ has_error = "[ERROR" in proc.stdout or proc.returncode != 0 if has_error: - results.append(f'"{label}" STR ERROR') + results.append(f'"{label}" STR "ERROR"') else: - results.append(f'"{label}" STR {actual}') + results.append(f'"{label}" STR "{actual}"') # Write output.now with open("output.now", "w") as f: diff --git a/tao/version/tao_version_mod.f90 b/tao/version/tao_version_mod.f90 index 3f92c3c71..e16b37218 100644 --- a/tao/version/tao_version_mod.f90 +++ b/tao/version/tao_version_mod.f90 @@ -5,5 +5,5 @@ !- module tao_version_mod -character(*), parameter :: tao_version_date = "2026/06/06 15:26:06" +character(*), parameter :: tao_version_date = "2026/06/10 21:41:51" end module