Dipole (bend) Example¶
In [1]:
Copied!
from pmd_beamphysics import single_particle
from pmd_beamphysics.units import mec2
import impact.z as IZ
from pmd_beamphysics import single_particle
from pmd_beamphysics.units import mec2
import impact.z as IZ
In [2]:
Copied!
reference_particle_mass = mec2
energy = 10e6
gamma = energy / mec2
sigma_x0 = 0.001
norm_emit_x = 1e-12
norm_emit_y = 1e-12
beta_x = sigma_x0**2 * gamma / norm_emit_x
beta_y = beta_x
n_particle = 1
reference_particle_mass = mec2
energy = 10e6
gamma = energy / mec2
sigma_x0 = 0.001
norm_emit_x = 1e-12
norm_emit_y = 1e-12
beta_x = sigma_x0**2 * gamma / norm_emit_x
beta_y = beta_x
n_particle = 1
In [3]:
Copied!
initial_particles = single_particle(pz=energy)
initial_particles = single_particle(pz=energy)
In [4]:
Copied!
input = IZ.ImpactZInput(
    # line 1
    ncpu_y=1,
    ncpu_z=1,
    # line 2
    seed=6,
    n_particle=n_particle,
    integrator_type="linear_map",
    err=1,
    diagnostic_type="extended",
    # line 3
    nx=32,
    ny=32,
    nz=32,
    boundary_type="trans_open_longi_open",
    radius_x=0.15,  # particles die after this point
    radius_y=0.15,
    z_period_size=0.0,  # TODO we think this is unused based on fortran code reading
    # line 4
    distribution="read",  # "gauss",
    restart=0,
    subcycle=0,  # TODO what is this?
    nbunch=1,
    # line 8
    twiss_alpha_x=0.0,
    twiss_beta_x=beta_x,
    twiss_norm_emit_x=norm_emit_x,
    twiss_mismatch_x=1.0,
    twiss_mismatch_px=1.0,
    twiss_offset_x=0.0,
    twiss_offset_px=0.0,
    # line 9
    twiss_alpha_y=0.0,
    twiss_beta_y=beta_y,
    twiss_norm_emit_y=norm_emit_y,
    twiss_mismatch_y=1.0,
    twiss_mismatch_py=1.0,
    twiss_offset_y=0.0,
    twiss_offset_py=0.0,
    # line 10
    twiss_alpha_z=1e-9,
    twiss_beta_z=5e9,
    twiss_norm_emit_z=1e-9,
    twiss_mismatch_z=1.0,
    twiss_mismatch_e_z=1.0,
    twiss_offset_phase_z=0.0,
    twiss_offset_energy_z=0.0,
    # line 11
    # average_current=1.0,  # space charge on
    average_current=0.0,  # space charge off
    reference_kinetic_energy=energy - mec2,  # eV -> 10MeV total energy
    reference_particle_mass=reference_particle_mass,
    reference_particle_charge=-1.0,
    reference_frequency=1e9,  # arbitrarily set to 1GHz here
    initial_phase_ref=0.0,
    lattice=[
        IZ.WriteFull(file_id=1999, name="initial_particles"),
        # IZ.Drift(length=1e-9, steps=10, map_steps=10),  # <- to get initial particles, set this and set average_current to 0.0
        # IZ.Drift(length=1.0, radius=1.0, steps=10, map_steps=10, name="drift1"),
        IZ.Dipole(
            length=1.0,  # [m]
            steps=10,  # Number of space-charge kicks through the beamline element. Each "step" consists of a half-step, a space-charge kick, and another half-step.
            map_steps=10,  # Each half-step involves computing a map for that half-element which is computed by numerical integration.
            angle=1e-12,
            k1=0.0,
            input_switch=0.0,  # input switch 150., if >200, include 1D CSR
            hgap=0.0,
            e1=0.0,
            e2=0.0,
            entrance_curvature=0.0,
            exit_curvature=0.0,
            fint=0.0,
            misalignment_error_x=0.0,
            misalignment_error_y=0.0,
            rotation_error_x=0.0,
            rotation_error_y=0.0,
            rotation_error_z=0.0,
            name="dipole1",
        ),
        IZ.WriteFull(file_id=2000, name="final_particles"),
    ],
)
input = IZ.ImpactZInput(
    # line 1
    ncpu_y=1,
    ncpu_z=1,
    # line 2
    seed=6,
    n_particle=n_particle,
    integrator_type="linear_map",
    err=1,
    diagnostic_type="extended",
    # line 3
    nx=32,
    ny=32,
    nz=32,
    boundary_type="trans_open_longi_open",
    radius_x=0.15,  # particles die after this point
    radius_y=0.15,
    z_period_size=0.0,  # TODO we think this is unused based on fortran code reading
    # line 4
    distribution="read",  # "gauss",
    restart=0,
    subcycle=0,  # TODO what is this?
    nbunch=1,
    # line 8
    twiss_alpha_x=0.0,
    twiss_beta_x=beta_x,
    twiss_norm_emit_x=norm_emit_x,
    twiss_mismatch_x=1.0,
    twiss_mismatch_px=1.0,
    twiss_offset_x=0.0,
    twiss_offset_px=0.0,
    # line 9
    twiss_alpha_y=0.0,
    twiss_beta_y=beta_y,
    twiss_norm_emit_y=norm_emit_y,
    twiss_mismatch_y=1.0,
    twiss_mismatch_py=1.0,
    twiss_offset_y=0.0,
    twiss_offset_py=0.0,
    # line 10
    twiss_alpha_z=1e-9,
    twiss_beta_z=5e9,
    twiss_norm_emit_z=1e-9,
    twiss_mismatch_z=1.0,
    twiss_mismatch_e_z=1.0,
    twiss_offset_phase_z=0.0,
    twiss_offset_energy_z=0.0,
    # line 11
    # average_current=1.0,  # space charge on
    average_current=0.0,  # space charge off
    reference_kinetic_energy=energy - mec2,  # eV -> 10MeV total energy
    reference_particle_mass=reference_particle_mass,
    reference_particle_charge=-1.0,
    reference_frequency=1e9,  # arbitrarily set to 1GHz here
    initial_phase_ref=0.0,
    lattice=[
        IZ.WriteFull(file_id=1999, name="initial_particles"),
        # IZ.Drift(length=1e-9, steps=10, map_steps=10),  # <- to get initial particles, set this and set average_current to 0.0
        # IZ.Drift(length=1.0, radius=1.0, steps=10, map_steps=10, name="drift1"),
        IZ.Dipole(
            length=1.0,  # [m]
            steps=10,  # Number of space-charge kicks through the beamline element. Each "step" consists of a half-step, a space-charge kick, and another half-step.
            map_steps=10,  # Each half-step involves computing a map for that half-element which is computed by numerical integration.
            angle=1e-12,
            k1=0.0,
            input_switch=0.0,  # input switch 150., if >200, include 1D CSR
            hgap=0.0,
            e1=0.0,
            e2=0.0,
            entrance_curvature=0.0,
            exit_curvature=0.0,
            fint=0.0,
            misalignment_error_x=0.0,
            misalignment_error_y=0.0,
            rotation_error_x=0.0,
            rotation_error_y=0.0,
            rotation_error_z=0.0,
            name="dipole1",
        ),
        IZ.WriteFull(file_id=2000, name="final_particles"),
    ],
)
In [5]:
Copied!
input.space_charge_off()
input.space_charge_off()
In [6]:
Copied!
initial_particles.weight
initial_particles.weight
Out[6]:
array([1.])
In [7]:
Copied!
I = IZ.ImpactZ(input, initial_particles=initial_particles)
output = I.run(verbose=True)
I = IZ.ImpactZ(input, initial_particles=initial_particles)
output = I.run(verbose=True)
Configured to run in: /var/folders/vy/s8_hc3m10fddm6n_43cf_m8r0000gn/T/tmpb2ejfp0j Running Impact-Z in /var/folders/vy/s8_hc3m10fddm6n_43cf_m8r0000gn/T/tmpb2ejfp0j /Users/klauer/Repos/IMPACT-Z/build-single/ImpactZexe
0%| | 0/3 [00:00<?, ?it/s]
 Read input data from file - ImpactZ.in:
 !-----------------------------------------------------------
 ! IMPACT-Z: Integrated Map and PArticle Tracking Code: Version 2.5
 ! Copyright of The Regents of the University of California
 !-----------------------------------------------------------
 check random:            0  0.320923269    
 pass generating initial distribution...
 pass setting up lattice...
 enter elment (type code):            1          -2
 zedge:    0.0000000000000000     
 enter elment (type code):            2           4
 zedge:    0.0000000000000000     
 j, nstep, z           1           1  0.10000000000000001     
 j, nstep, z           2           2  0.20000000000000001     
 j, nstep, z           3           3  0.29999999999999999     
 j, nstep, z           4           4  0.39999999999999997     
 j, nstep, z           5           5  0.49999999999999994     
 j, nstep, z           6           6  0.59999999999999998     
 j, nstep, z           7           7  0.70000000000000007     
 j, nstep, z           8           8  0.80000000000000016     
 j, nstep, z           9           9  0.90000000000000024     
 j, nstep, z          10          10   1.0000000000000002     
 enter elment (type code):            3          -2
 zedge:    1.0000000000000002     
         kvdist    0.00000 seconds
         gaussn    0.00000 seconds
         normdv    0.00000 seconds
        correct    0.00000 seconds
          integ    0.00000 seconds
           map1    0.00000 seconds
           map2    0.00000 seconds
         spch2d    0.00000 seconds
      boundgeom    0.00000 seconds
         greenf    0.00000 seconds
         rhofas    0.00000 seconds
         ntrslo    0.00000 seconds
       fft2dhpf    0.00000 seconds
    mfft_local1    0.00000 seconds
           diag    0.00000 seconds
         ufield    0.00000 seconds
          force    0.00000 seconds
         charge    0.00000 seconds
        ubeamln    0.00000 seconds
          ptsmv    0.00000 seconds
           init    0.00000 seconds
         transp    0.00000 seconds
        enlarge    0.00000 seconds
         shrink    0.00000 seconds
       guardsum    0.00000 seconds
       boundint    0.00000 seconds
      guardexch    0.00000 seconds
 time:    0.0000000000000000     
Success - execution took 0.07s.
In [8]:
Copied!
I.plot()
I.plot()
In [9]:
Copied!
I.output
I.output
Out[9]:
ImpactZOutput(
    run=RunInfo(error_reason='', run_script='/Users/klauer/Repos/IMPACT-Z/build-single/ImpactZexe', run_time=0.07087191700702533),
    stats=OutputStats(
        beta_ref=array([0.99869355, 0.99869355, 0.99869355, 0.99869355, 0.99869355,
       0.99869355, 0.99869355, 0.99869355, 0.99869355, 0.99869355,
       0.99869355]),
        charge_state_n_particle=array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]),
        gamma_ref=array([19.56951184, 19.56951184, 19.56951184, 19.56951184, 19.56951184,
       19.56951184, 19.56951184, 19.56951184, 19.56951184, 19.56951184,
       19.56951184]),
        kinetic_energy_ref=array([9489001.05, 9489001.05, 9489001.05, 9489001.05, 9489001.05,
       9489001.05, 9489001.05, 9489001.05, 9489001.05, 9489001.05,
       9489001.05]),
        loadbalance_max_n_particle=array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]),
        loadbalance_min_n_particle=array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]),
        max_amplitude_energy_dev=array([], dtype=float64),
        max_amplitude_gammabeta_x=array([], dtype=float64),
        max_amplitude_gammabeta_y=array([], dtype=float64),
        max_amplitude_phase=array([], dtype=float64),
        max_amplitude_x=array([], dtype=float64),
        max_amplitude_y=array([], dtype=float64),
        max_r=array([0.00000000e+00, 3.26185435e-18, 1.95882390e-17, 4.89791541e-17,
       9.14345994e-17, 1.46954575e-16, 2.15539081e-16, 2.97188118e-16,
       3.91901684e-16, 4.99679781e-16, 6.20522409e-16]),
        mean_phase_deg=array([ 0.        , -0.00041073, -0.00082145, -0.00123218, -0.0016429 ,
       -0.00205363, -0.00246435, -0.00287508, -0.00328581, -0.00369653,
       -0.00410726]),
        mean_px_over_p0=array([0.00000000e+00, 1.30816209e-16, 2.61632417e-16, 3.92448626e-16,
       5.23264835e-16, 6.54081043e-16, 7.84897252e-16, 9.15713460e-16,
       1.04652967e-15, 1.17734588e-15, 1.30816209e-15]),
        mean_py_over_p0=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]),
        mean_x=array([0.00000000e+00, 3.26185435e-18, 1.95882390e-17, 4.89791541e-17,
       9.14345994e-17, 1.46954575e-16, 2.15539081e-16, 2.97188118e-16,
       3.91901684e-16, 4.99679781e-16, 6.20522409e-16]),
        mean_y=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]),
        moment3_energy=array([], dtype=float64),
        moment3_phase=array([], dtype=float64),
        moment3_px_over_p0=array([], dtype=float64),
        moment3_py_over_p0=array([], dtype=float64),
        moment3_x=array([], dtype=float64),
        moment3_y=array([], dtype=float64),
        moment4_energy=array([], dtype=float64),
        moment4_phase=array([], dtype=float64),
        moment4_px_over_p0=array([], dtype=float64),
        moment4_py_over_p0=array([], dtype=float64),
        moment4_x=array([], dtype=float64),
        moment4_y=array([], dtype=float64),
        n_particle=array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]),
        norm_emit_x=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]),
        norm_emit_y=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]),
        norm_emit_z=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]),
        phase_ref=array([ 0.        , 20.98586727, 20.98586727, 20.98586727, 20.98586727,
       20.98586727, 20.98586727, 20.98586727, 20.98586727, 20.98586727,
       20.98586727]),
        sigma_energy=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]),
        sigma_phase_deg=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]),
        sigma_px_over_p0=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]),
        sigma_py_over_p0=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]),
        sigma_x=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]),
        sigma_y=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]),
        twiss_alpha_x=array([nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan]),
        twiss_alpha_y=array([nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan]),
        twiss_alpha_z=array([nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan]),
        z=array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ]),
        max_abs_x=array([0.00000000e+00, 3.26185435e-18, 1.95882390e-17, 4.89791541e-17,
       9.14345994e-17, 1.46954575e-16, 2.15539081e-16, 2.97188118e-16,
       3.91901684e-16, 4.99679781e-16, 6.20522409e-16]),
        max_abs_px_over_p0=array([], dtype=float64),
        max_abs_y=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]),
        max_abs_py_over_p0=array([], dtype=float64),
        max_phase=array([0.        , 0.00041073, 0.00082145, 0.00123218, 0.0016429 ,
       0.00205363, 0.00246435, 0.00287508, 0.00328581, 0.00369653,
       0.00410726]),
        max_energy_dev=array([], dtype=float64),
        mean_r=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]),
        sigma_r=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]),
        mean_r_90percent=array([2.38567257e-12, 2.38567257e-12, 2.38567257e-12, 2.38567257e-12,
       2.38567257e-12, 2.38567257e-12, 2.38567257e-12, 2.38567257e-12,
       2.38567257e-12, 2.38567257e-12, 2.38567257e-12]),
        mean_r_95percent=array([2.38567257e-12, 2.38567257e-12, 2.38567257e-12, 2.38567257e-12,
       2.38567257e-12, 2.38567257e-12, 2.38567257e-12, 2.38567257e-12,
       2.38567257e-12, 2.38567257e-12, 2.38567257e-12]),
        mean_r_99percent=array([2.38567257e-12, 2.38567257e-12, 2.38567257e-12, 2.38567257e-12,
       2.38567257e-12, 2.38567257e-12, 2.38567257e-12, 2.38567257e-12,
       2.38567257e-12, 2.38567257e-12, 2.38567257e-12]),
        max_r_rel=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]),
        max_abs_gammabeta_x=array([0.00000000e+00, 2.55666481e-15, 5.11332962e-15, 7.66999443e-15,
       1.02266592e-14, 1.27833241e-14, 1.53399889e-14, 1.78966537e-14,
       2.04533185e-14, 2.30099833e-14, 2.55666481e-14]),
        max_abs_gammabeta_y=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]),
        max_gamma_rel=array([0.02553329, 0.02553329, 0.02553329, 0.02553329, 0.02553329,
       0.02553329, 0.02553329, 0.02553329, 0.02553329, 0.02553329,
       0.02553329]),
        norm_emit_x_90percent=array([nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan]),
        norm_emit_x_95percent=array([nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan]),
        norm_emit_x_99percent=array([nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan]),
        norm_emit_y_90percent=array([nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan]),
        norm_emit_y_95percent=array([nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan]),
        norm_emit_y_99percent=array([nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan]),
        norm_emit_z_90percent=array([nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan]),
        norm_emit_z_95percent=array([nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan]),
        norm_emit_z_99percent=array([nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan]),
        energy_ref=array([10000000., 10000000., 10000000., 10000000., 10000000., 10000000.,
       10000000., 10000000., 10000000., 10000000., 10000000.]),
        mean_energy=array([10013047.48450246, 10013047.48450246, 10013047.48450246,
       10013047.48450246, 10013047.48450246, 10013047.48450246,
       10013047.48450246, 10013047.48450246, 10013047.48450246,
       10013047.48450246, 10013047.48450246]),
        mean_gamma=array([19.59504513, 19.59504513, 19.59504513, 19.59504513, 19.59504513,
       19.59504513, 19.59504513, 19.59504513, 19.59504513, 19.59504513,
       19.59504513]),
        mean_px=array([0.00000000e+00, 1.30645303e-09, 2.61290607e-09, 3.91935910e-09,
       5.22581214e-09, 6.53226517e-09, 7.83871820e-09, 9.14517124e-09,
       1.04516243e-08, 1.17580773e-08, 1.30645303e-08]),
        mean_py=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]),
        mean_t=array([0.00000000e+00, 3.34000337e-09, 3.34000223e-09, 3.34000109e-09,
       3.33999995e-09, 3.33999881e-09, 3.33999767e-09, 3.33999652e-09,
       3.33999538e-09, 3.33999424e-09, 3.33999310e-09]),
        mean_t_rel=array([ 0.00000000e+00, -1.14090471e-15, -2.28180941e-15, -3.42271412e-15,
       -4.56361882e-15, -5.70452353e-15, -6.84542823e-15, -7.98633294e-15,
       -9.12723764e-15, -1.02681423e-14, -1.14090471e-14]),
        p0c=array([9986935.46955716, 9986935.46955716, 9986935.46955716,
       9986935.46955716, 9986935.46955716, 9986935.46955716,
       9986935.46955716, 9986935.46955716, 9986935.46955716,
       9986935.46955716, 9986935.46955716]),
        sigma_px=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]),
        sigma_py=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]),
        sigma_t=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]),
        t_ref=array([0.00000000e+00, 3.34000451e-09, 3.34000451e-09, 3.34000451e-09,
       3.34000451e-09, 3.34000451e-09, 3.34000451e-09, 3.34000451e-09,
       3.34000451e-09, 3.34000451e-09, 3.34000451e-09]),
        twiss_beta_x=array([], dtype=float64),
        twiss_beta_y=array([], dtype=float64),
        extra={}
    ),
    reference_frequency=1000000000.0,
    reference_species='electron'
)
In [10]:
Copied!
list(I.output.particles_raw)
list(I.output.particles_raw)
Out[10]:
['initial_particles', 'final_particles']
In [11]:
Copied!
Pin = I.output.particles["initial_particles"]
# Our initial particles must be the same as what Impact-Z wrote:
assert initial_particles == Pin
Pin = I.output.particles["initial_particles"]
# Our initial particles must be the same as what Impact-Z wrote:
assert initial_particles == Pin
In [12]:
Copied!
P_raw = I.output.particles_raw["final_particles"]
P = I.output.particles["final_particles"]
P_raw = I.output.particles_raw["final_particles"]
P = I.output.particles["final_particles"]
In [13]:
Copied!
I.plot("mean_x")
I.plot("mean_x")