TESLA 9-cell Cavity¶
In [1]:
Copied!
from impact import Impact
from pmd_beamphysics.units import mec2
import numpy as np
import os
import matplotlib.pyplot as plt
%config InlineBackend.figure_format='retina'
from impact import Impact
from pmd_beamphysics.units import mec2
import numpy as np
import os
import matplotlib.pyplot as plt
%config InlineBackend.figure_format='retina'
In [2]:
Copied!
ifile1 = "../templates/tesla_9cell_cavity/ImpactT-1d.in"
ifile2 = "../templates/tesla_9cell_cavity/ImpactT-2d.in"
os.path.exists(ifile1), os.path.exists(ifile2)
ifile1 = "../templates/tesla_9cell_cavity/ImpactT-1d.in"
ifile2 = "../templates/tesla_9cell_cavity/ImpactT-2d.in"
os.path.exists(ifile1), os.path.exists(ifile2)
Out[2]:
(True, True)
In [3]:
Copied!
# calculate gamma*beta
Etot = 10e6 # eV
gamma = Etot / mec2
GB = np.sqrt(gamma**2 - 1)
GB
GB, np.sqrt(Etot**2 - mec2**2)
# calculate gamma*beta
Etot = 10e6 # eV
gamma = Etot / mec2
GB = np.sqrt(gamma**2 - 1)
GB
GB, np.sqrt(Etot**2 - mec2**2)
Out[3]:
(np.float64(19.543945187279075), np.float64(9986935.46955716))
In [4]:
Copied!
%%time
I1 = Impact(ifile1)
I1.run()
I1.plot(y2="mean_kinetic_energy")
%%time
I1 = Impact(ifile1)
I1.run()
I1.plot(y2="mean_kinetic_energy")
CPU times: user 267 ms, sys: 55 ms, total: 322 ms Wall time: 29.4 s
In [5]:
Copied!
%%time
I2 = Impact(ifile2)
I2.run()
I2.plot(y2="mean_kinetic_energy")
%%time
I2 = Impact(ifile2)
I2.run()
I2.plot(y2="mean_kinetic_energy")
CPU times: user 584 ms, sys: 73.3 ms, total: 658 ms Wall time: 6.97 s
In [6]:
Copied!
I1.particles["final_particles"].plot("z", "pz", bins=100)
I1.particles["final_particles"].plot("z", "pz", bins=100)
In [7]:
Copied!
I2.particles["final_particles"].plot("z", "pz", bins=100)
I2.particles["final_particles"].plot("z", "pz", bins=100)
In [8]:
Copied!
# ky = 'mean_kinetic_energy'
def compare(ky="sigma_x", kx="mean_z"):
fig, ax = plt.subplots(figsize=(12, 6))
ax.plot(I1.stat(kx), I1.stat(ky), label="Impact-T 1D")
ax.plot(I2.stat(kx), I2.stat(ky), label="Impact-T 2D", linestyle="--")
ax.legend()
# ax.set_xlim(0,2)
ax.set_xlabel(kx)
ax.set_ylabel(ky)
compare()
# ky = 'mean_kinetic_energy'
def compare(ky="sigma_x", kx="mean_z"):
fig, ax = plt.subplots(figsize=(12, 6))
ax.plot(I1.stat(kx), I1.stat(ky), label="Impact-T 1D")
ax.plot(I2.stat(kx), I2.stat(ky), label="Impact-T 2D", linestyle="--")
ax.legend()
# ax.set_xlim(0,2)
ax.set_xlabel(kx)
ax.set_ylabel(ky)
compare()
Use Impact's built-in Gaussian particle generator¶
In [9]:
Copied!
I = Impact(ifile1)
I.header["Dt"] = 1e-12
I.total_charge = 0 # Turn SC off
print(I)
I.run()
I.particles["final_particles"]["sigma_x"] / 1e-6
I = Impact(ifile1)
I.header["Dt"] = 1e-12
I.total_charge = 0 # Turn SC off
print(I)
I.run()
I.particles["final_particles"]["sigma_x"] / 1e-6
================ Impact-T Summary ================ 10000 particles 1 bunch of electrons total charge: 0.0 pC Distribution type: gauss3 Free space start Processor domain: 1 x 1 = 1 CPUs Space charge grid: 32 x 32 x 32 Maximum time steps: 1000000 Reference Frequency: 1300000000.0 Hz Initial reference time: 0.0 s Simulation starting from the beginning ================================================= Impact-T configured in /tmp/tmpa0vj1xby
Out[9]:
np.float64(3.7319608096714334)
In [10]:
Copied!
I.particles["final_particles"].plot("delta_z", "delta_pz")
I.particles["final_particles"].plot("delta_z", "delta_pz")
In [11]:
Copied!
I.lattice
I.lattice
Out[11]:
[{'description': 'name:cavity9', 'original': '1.347 0 0 105 0 32e6 1.3e9 229.8241496412331 9 0 0.0 0.0 0.0 0.0 0.0 0.0 /!name:cavity9', 'L': 1.347, 'type': 'solrf', 'zedge': 0.0, 'rf_field_scale': 32000000.0, 'rf_frequency': 1300000000.0, 'theta0_deg': 229.8241496412331, 'filename': 'rfdata9', 'radius': 0.0, 'x_offset': 0.0, 'y_offset': 0.0, 'x_rotation': 0.0, 'y_rotation': 0.0, 'z_rotation': 0.0, 'solenoid_field_scale': 0.0, 's': 1.347, 'name': 'cavity9'}, {'description': 'name:stop_1', 'original': '0 0 0 -99 0 0.0 1.5 /!name:stop_1', 'type': 'stop', 's': 1.5, 'name': 'stop_1'}, {'type': 'comment', 'description': '', 'name': 'comment_1'}]
Autophase¶
In [12]:
Copied!
from impact.autophase import autophase
from pmd_beamphysics import single_particle
P0 = single_particle(pz=10e6, z=1e-15)
autophase(
I2,
ele_name="cavity9",
initial_particles=P0,
metric="mean_kinetic_energy",
verbose=True,
)
from impact.autophase import autophase
from pmd_beamphysics import single_particle
P0 = single_particle(pz=10e6, z=1e-15)
autophase(
I2,
ele_name="cavity9",
initial_particles=P0,
metric="mean_kinetic_energy",
verbose=True,
)
Copied initial Impact object. Phasing cavity9 by changing theta0_deg Bounds: 0.0, 1.347 m Default brent2 algorithm
Phase: 180, 16.998227975214004 MeV
Phase: 180, 16.998227975214004 MeV
/home/runner/miniconda3/envs/lume-impact-dev/lib/python3.12/site-packages/impact/parsers.py:2208: UserWarning: Empty file: /tmp/tmpvu01offo/fort.50 warnings.warn(f"Empty file: {filePath}")
Phase: 42.49224000000004, 0.0 M
Phase: 42.49223094384001, 0.0 M
Phase: 42.49223999999998, 0.0 M
Phase: 222.49223547192, 25.442029397369534 MeV
Phase: 291.2461137423474, 21.238389337448673 MeV
Phase: 243.7817825076153, 26.67725309641637 MeV
Phase: 244.6923794470155, 26.678029806579133 MeV
Phase: 244.40270047418736, 26.678252484702742 MeV
Phase: 244.40037613191828, 26.678252498701642 MeV
Phase: 244.4006205323044, 26.67825249854837 MeV
Phase: 244.40013173153216, 26.67825249854837 MeV Set Phase: 244.40037613191828
Out[12]:
np.float64(244.40037613191828)
In [13]:
Copied!
I.run()
I.run()
In [14]:
Copied!
(
I.particles["final_particles"]["mean_energy"] / 1e6,
I.particles["final_particles"]["sigma_x"] / 1e-6,
)
(
I.particles["final_particles"]["mean_energy"] / 1e6,
I.particles["final_particles"]["sigma_x"] / 1e-6,
)
Out[14]:
(np.float64(27.411527157614398), np.float64(3.7319608096714334))
In [15]:
Copied!
# Compare these.
key1 = "mean_z"
key2 = "sigma_x"
units1 = str(I.units(key1))
units2 = str(I.units(key2))
plt.xlabel(key1 + f" ({units1})")
plt.ylabel(key2 + f" ({units2})")
plt.plot(I.stat(key1), I.stat(key2))
plt.scatter(
[I.particles[name][key1] for name in I.particles],
[I.particles[name][key2] for name in I.particles],
color="red",
)
# Compare these.
key1 = "mean_z"
key2 = "sigma_x"
units1 = str(I.units(key1))
units2 = str(I.units(key2))
plt.xlabel(key1 + f" ({units1})")
plt.ylabel(key2 + f" ({units2})")
plt.plot(I.stat(key1), I.stat(key2))
plt.scatter(
[I.particles[name][key1] for name in I.particles],
[I.particles[name][key2] for name in I.particles],
color="red",
)
Out[15]:
<matplotlib.collections.PathCollection at 0x7f3178ae0080>
In [16]:
Copied!
I.output["stats"].keys()
I.output["stats"].keys()
Out[16]:
dict_keys(['t', 'mean_z', 'mean_gamma', 'mean_beta', 'max_r', 'sigma_gamma', 'mean_x', 'sigma_x', 'norm_emit_x', 'mean_y', 'sigma_y', 'norm_emit_y', 'sigma_z', 'norm_emit_z', 'max_amplitude_x', 'max_amplitude_y', 'max_amplitude_z', 'loadbalance_min_n_particle', 'loadbalance_max_n_particle', 'n_particle', 'moment3_x', 'moment3_y', 'moment3_z', 'moment4_x', 'moment4_y', 'moment4_z', 'cov_x__x', 'cov_x__y', 'cov_x__z', 'cov_y__y', 'cov_y__z', 'cov_z__z', 'mean_kinetic_energy', 'cov_x__px', 'cov_y__py', 'cov_z__pz', 'cov_x__py', 'cov_x__pz', 'cov_px__px', 'cov_y__px', 'cov_px__py', 'cov_z__px', 'cov_px__pz', 'cov_y__pz', 'cov_py__py', 'cov_z__py', 'cov_py__pz', 'cov_pz__pz'])
In [17]:
Copied!
PI = I.particles["initial_particles"]
PF = I.particles["final_particles"]
PI = I.particles["initial_particles"]
PF = I.particles["final_particles"]
In [18]:
Copied!
PI["mean_pz"]
PI["mean_pz"]
Out[18]:
np.float64(9986935.46956785)
In [19]:
Copied!
PF.plot("delta_z", "delta_pz")
PF.plot("delta_z", "delta_pz")
Make particles in distgen¶
In [20]:
Copied!
from distgen import Generator
YAML = """
n_particle: 10000
random_type: hammersley
species: electron
start:
tstart:
units: sec
value: 0
type: time
total_charge:
units: nC
value: 1
r_dist:
sigma_xy:
units: mm
value: .01
type: radial_gaussian
z_dist:
avg_z:
units: mm
value: 0
sigma_z:
units: mm
value: 0.1
type: gaussian
transforms:
setPz:
type: set_avg pz
avg_pz:
value: 99.99869439159244
units: MeV/c
"""
G = Generator(YAML)
G.run()
P = G.particles
from distgen import Generator
YAML = """
n_particle: 10000
random_type: hammersley
species: electron
start:
tstart:
units: sec
value: 0
type: time
total_charge:
units: nC
value: 1
r_dist:
sigma_xy:
units: mm
value: .01
type: radial_gaussian
z_dist:
avg_z:
units: mm
value: 0
sigma_z:
units: mm
value: 0.1
type: gaussian
transforms:
setPz:
type: set_avg pz
avg_pz:
value: 99.99869439159244
units: MeV/c
"""
G = Generator(YAML)
G.run()
P = G.particles
In [21]:
Copied!
I2 = I.copy()
I2.initial_particles = P
I2.configure()
I2.total_charge = 0 # or: P['charge']
I2.run()
PF2 = I2.particles["final_particles"]
I2 = I.copy()
I2.initial_particles = P
I2.configure()
I2.total_charge = 0 # or: P['charge']
I2.run()
PF2 = I2.particles["final_particles"]
In [22]:
Copied!
PF2.plot("x", "px")
PF2.plot("delta_z", "delta_pz")
PF2.plot("x", "px")
PF2.plot("delta_z", "delta_pz")
Compare¶
In [23]:
Copied!
# for k in ['x', 'px', 'z', 'pz']:
# plt.hist(PF[k], density=True, bins=100, label='Impact-T generator', alpha=0.5)
# plt.hist(PF2[k], density=True, bins=100, label='Distgen generator', alpha=0.5)
# plt.xlabel(k)
# plt.legend()
# plt.show()
# for k in ['x', 'px', 'z', 'pz']:
# plt.hist(PF[k], density=True, bins=100, label='Impact-T generator', alpha=0.5)
# plt.hist(PF2[k], density=True, bins=100, label='Distgen generator', alpha=0.5)
# plt.xlabel(k)
# plt.legend()
# plt.show()
In [ ]:
Copied!