The current method of matching a specific phase advance implicitly assumes a matched twiss0. This is easy not use correctly and leading to deceptively wrong results for unmatched cases.
Proposed is a specialized objective for unified phase advance /Floquet exponent.
Example with current tools:
mu_x : complex = np.pi/2 # real, positive: phase advance, rotation
mu_x : complex = 2j # imaginary: Floquet exponent, exp. growth/decay
problem = MatchProblem(lattice, twiss0, periodic=False) # allow unstable in one plane
# ...
def phase_advance_x_cost_function(state: MatchState) -> float:
R = state.r_matrix(
state.lat.sequence[0], # only whole lattice is intuitive
state.lat.sequence[-1], # phase advance NOT additive in matrices!!
)
actual_mu_x = np.arccos((R[0, 0] + R[1, 1]) / 2 + 0j)
diff = actual_mu_x - mu_x
re = np.real(diff)
im = np.imag(diff)
# cost: approx abs(diff)**2 for small diff, and 2*pi-periodic + flat only near 0 in re
# return np.sqrt(2 * (1 - np.cos(re))), im # idea rejected: flat near 0 but also +/- pi, which can cause issues with convergence
return 2 * np.tan(re / 2), im # improved version
problem.objective_function(
phase_advance_x_cost_function,
mode="residual",
name="phase_advance_x_func",
weight=1e6,
)
Needs: check that mu is either positive or purely imaginary
Affects: tutorial for phase advance
The current method of matching a specific phase advance implicitly assumes a matched twiss0. This is easy not use correctly and leading to deceptively wrong results for unmatched cases.
Proposed is a specialized objective for unified phase advance /Floquet exponent.
Example with current tools:
Needs: check that mu is either positive or purely imaginary
Affects: tutorial for phase advance