磁铁 ramping

Quadrupole、Sextupole、Octupole 和 Multipole 支持以物理时间为 自变量、分段线性插值的归一化磁场强度程序,正、斜分量可以独立变化。 SBend、Kicker 和 Solenoid 暂不支持此接口。

强度约定

程序使用与静态元件相同的归一化系数:\(K_n\) 的单位是 \(\mathrm{m}^{-(n+1)}\),\(K_nL\) 的单位是 \(\mathrm{m}^{-n}\)。 其中 \(n=1,2,3\) 分别对应四极、六极和八极。对于长度为 \(L\) 的磁铁, K 列乘以 \(L\) 得到积分强度;KL 列已经是整个元件的积分强度。 零长度元件必须使用积分强度列。

表中数值是 绝对强度,不是倍率。程序中指定的分量覆盖对应的当前名义值, 未指定的分量保留当前名义值。已启用的场误差独立保存为绝对加性系数, 跟踪时只相加一次,不写入名义强度,也不随主场程序同比缩放。

与静态跟踪一致,强度相对于当前 bunch 的参考动量 \(P_0\) 归一化。 程序不输入实际磁场,也不根据变化的磁刚度换算固定实际磁场。 例如,正四极薄透镜满足 \(\Delta p_x=-K_1L(t)x\);由于 \(p_x=P_x/P_0\),冲量不再额外乘以 \(1/(1+\delta)\)。

当前强度状态

运行时元件只维护一套当前名义强度。四极铁对应 k1l/k1sl 及其派生的 单位长度强度 k1/k1s;六极和八极使用相应的二阶、三阶属性。 Multipole 使用 knl/ksl 数组,以及派生的 kn/ks 数组。 对于厚元件,单位长度强度等于积分强度除以整个元件长度。

跟踪对每个非空 bunch 在元件入口更新一次程序指定的通道。执行后,这些属性保留 最后执行的非空 bunch 的入口名义值。空 bunch 不采样程序,也不改变当前强度。 元件不保存原始强度备份,运行时移除程序也不会恢复初始强度。程序未列出的通道保留当前值, 包括元件构造后已改变的值。运行时更新不会改写输入字典、配置对象或源 TFS 文件。

这四种运行时元件类均提供 update_strengths(reference_time, offset=0.0)。 它在指定物理参考时间加独立局部时间偏移处取样,更新当前名义强度及派生参数, 并使受影响的系数缓存失效。该调用不跟踪粒子,也不推进 bunch.t0; 元件没有活动程序时,调用保持当前强度不变。例如,已有运行时四极铁对象时:

element.update_strengths(reference_time=0.05, offset=0.0)
print(element.k1l, element.k1sl)

该方法属于跟踪元件,不属于 QuadrupoleItem 输入配置模型。 程序表仍是规定的输入数据,不是元件初始强度的备份。 自动跟踪使用 bunch 入口 t0 和零偏移调用此更新。

配置接口

Python 字段

JSON 键

类型

默认值

说明

is_ramping

Is ramping

bool

False

启用指定的强度程序。

ramping_file

Ramping file

str

""

含 TIME 和强度列的 TFS 文件。

相对路径以输入 JSON 所在目录为基准。构造元件时若关闭 ramping,则使用配置中提供的强度。 旧的分量文件字段(例如 K1L ramping file、K1SL ramping file)仍可使用, 新输入建议使用统一的 Ramping file。统一文件不能与任何旧分量文件字段同时使用。 同一分量不能通过多个旧文件重复定义,也不能同时提供对应的 K 和 KL 列。 旧 TIME_S 列在确实表示物理秒时也可使用。

{
  "Command": "Quadrupole",
  "S (m)": 10.0,
  "Length (m)": 0.5,
  "K1L": 0.2,
  "K1SL": 0.01,
  "Num slices": 8,
  "Is ramping": true,
  "Ramping file": "quadrupole_ramp.tfs"
}

TFS 格式

自变量列为以物理秒计的 TIME。时间必须有限且严格递增,所有强度值必须有限。 相邻行之间作线性插值;首行之前保持首值,末行之后保持末值。 单行文件表示常数程序。只有 TURN 列的文件不是物理时间程序。 手写文件可以省略下面的头信息,但提供时会检查其内容。写入器还记录强度列单位, 例如 K1L_UNIT="m^-1"。

@ TIME_UNIT %s "s"
@ STRENGTH_CONVENTION %s "normalized"
* TIME K1L K1SL
$ %le %le %le
0.00 0.20  0.01
0.05 0.25  0.00
0.10 0.22 -0.01
支持的强度列

元件

单位长度强度列

积分强度列

Quadrupole

K1、K1S

K1L、K1SL

Sextupole

K2、K2S

K2L、K2SL

Octupole

K3、K3S

K3L、K3SL

Multipole

K0、K0S、K1、K1S、……

K0L、K0SL、K1L、K1SL、……

对于 Multipole,列名中的阶数对应名义 KiL/KiSL 输入数组以及运行时 knl/ksl 数组的下标。程序可以增加这些数组中没有的高阶分量。 零阶分量仍然是普通多极冲量, 不引入弯转参考几何,也不代表 SBend 支持 ramping。

入口采样与整个元件冻结

此接口采用每次 bunch 通过时使用一组强度的准静态磁铁模型。对每个非空 bunch, 厚磁铁和薄冲量都只在该 bunch 参考粒子的元件入口时刻采样一次:

\[t_{\mathrm{sample}}=t_{0,\mathrm{entry}}.\]

得到的名义系数在本 bunch 的整个元件跟踪过程中保持不变。主体切片、内部空间电荷 节点和 Yoshida 子步均使用同一组入口强度,不重新采样程序。不同 bunch 使用各自 实际的入口 bunch.t0。同一 bunch 的全部粒子共用这些强度:粒子 z 不用于 校正取样时刻,harmonic_id/z_center 分组元数据也不平移取样时间。

Num slices 只控制磁铁映射的空间积分和内部空间电荷调度。增大切片数可改善这些 积分,但不改变 ramp 采样时刻,也不能解析穿越单个元件期间的强度变化。 所选积分器的阶数针对这组冻结系数下的映射。此模型要求规定的强度在穿越元件期间 变化足够缓慢,可以用一个入口值代表该次通过。元件内部或 bunch 内部的快速变场 不在此近似范围内。

这是一次有意的 ramping 模型调整:跟踪现在对整个元件冻结一组入口值。 若程序在元件飞行时间内变化明显,计算结果可能因此改变。 配置 schema、TFS 格式和 GUI 操作流程保持不变。

ramp 不改变参考能量,不执行参考动量变换,也不增加新的时钟。 厚磁铁在跟踪后仍按已有飞行时间 \(L/(\beta_0c)\) 推进 t0,连续粒子 z 按原有磁铁传输映射演化。模型不包含快速变场产生的感应电场。

求值与诊断

程序表只读取一次并保存独立快照。仅当一个分量的全部存储值精确相等时, 才将其识别为常量;单行列也是常量。微小的非零变化会保留。 常量分量跳过区间搜索;其他分量在 bunch 入口插值,并采用前述端点保持规则。 具有相同时间网格的分量共用区间查找,旧文件中的不同网格仍独立插值。 单次查询使用二分搜索,无需复制整个较长的时间表。

CPU/GPU 跟踪使用当前名义强度和已有磁铁映射。程序工具负责绑定、采样规定数据, 更新名义强度及派生参数,并协调系数缓存失效,不提供另一套粒子映射。 场误差始终独立保存且只施加一次。GPU 系数缓存由当前强度派生, 强度改变时相应刷新。

内部空间电荷节点保留原有顺序和积分权重,其回调在同一 bunch 通过期间读取到 相同的入口冻结名义强度。跟踪后,运行时元件保留这些入口值,直到显式更新, 或下一个非空 bunch 到达元件入口。

元件日志给出程序为常量还是动态、指定的分量、文件时间范围、端点行为、 入口采样方式及有效主体切片数。切片数只描述空间传输。 时间范围是表格节点范围,不是跟踪开关窗口;范围外仍然保持对应端点值。

创建文件

使用 工具 → 数据转换 → 磁铁 ramping… 导入 CSV/TXT/TFS,或按时间断点生成。 选择时间列和单位,将源数据列映射到磁铁强度列名,检查预览后导出 TFS。 随后在元件编辑器中启用 ramping 并选取该文件。 GUI 操作和 Python 文件生成接口见 GUI 工具 与 输入文件生成(命令行模式)。