Functional example for LUME-Impact¶
In [1]:
Copied!
from impact import Impact, run_impact_with_distgen, evaluate_impact_with_distgen
import h5py
import os
# Nicer plotting
import matplotlib
%config InlineBackend.figure_format = 'retina'
matplotlib.rcParams["figure.figsize"] = (8, 4)
from impact import Impact, run_impact_with_distgen, evaluate_impact_with_distgen
import h5py
import os
# Nicer plotting
import matplotlib
%config InlineBackend.figure_format = 'retina'
matplotlib.rcParams["figure.figsize"] = (8, 4)
In [2]:
Copied!
gfile = "templates/lcls_injector/distgen.yaml"
ifile = "templates/lcls_injector/ImpactT.yaml"
gfile = "templates/lcls_injector/distgen.yaml"
ifile = "templates/lcls_injector/ImpactT.yaml"
Functional run_impact_with_distgen¶
This is a functional way to apply some settings to and run distgen and impact together.
Any key with a prefix distgen:
will send its suffix to distgen's Generator.
Otherwise, any key that can be set with Impact's attr syntax can be used.
In [3]:
Copied!
# Make some settings
SETTINGS0 = {
"distgen:n_particle": 100,
"total_charge": 0, # effectively turns spacecharge off
"stop": 0.02,
"GUN_phase:autophase_deg": 0,
}
# This returns an Impact object that has run
I = run_impact_with_distgen(
settings=SETTINGS0,
distgen_input_file=gfile,
impact_config=ifile,
)
I.plot("mean_kinetic_energy")
I
# Make some settings
SETTINGS0 = {
"distgen:n_particle": 100,
"total_charge": 0, # effectively turns spacecharge off
"stop": 0.02,
"GUN_phase:autophase_deg": 0,
}
# This returns an Impact object that has run
I = run_impact_with_distgen(
settings=SETTINGS0,
distgen_input_file=gfile,
impact_config=ifile,
)
I.plot("mean_kinetic_energy")
I
Out[3]:
<Impact with 100 particles, stopping at 0.02 m, at 0x7f570b697bf0>
In [4]:
Copied!
h5file = I.archive()
h5file = I.archive()
In [5]:
Copied!
with h5py.File(h5file, "r") as h5:
print(list(h5))
with h5py.File(h5file, "r") as h5:
print(list(h5))
['control_groups', 'initial_particles', 'input', 'output']
In [6]:
Copied!
I.from_archive(h5file)
I.output.keys()
I.from_archive(h5file)
I.output.keys()
Out[6]:
dict_keys(['autophase_info', 'run_info', 'stats', 'slice_info', 'particles'])
In [7]:
Copied!
I["total_charge"] = 1
I.write_input()
!cat {I.path}/ImpactT.in
I["total_charge"] = 1
I.write_input()
!cat {I.path}/ImpactT.in
! Impact-T input file !Npcol Nprow 1 1 !Dt Ntstep Nbunch 5e-13 1000000 1 !Dim Np Flagmap Flagerr Flagdiag Flagimg Zimage 6 100 1 0 2 1 0.02 !Nx Ny Nz Flagbc Xrad Yrad Perdlen 32 32 32 1 0.015 0.015 45.0 !Flagdist Rstartflg Flagsbstp Nemission Temission 16 0 0 400 5.326350576132463e-12 !sigx(m) sigpx muxpx xscale pxscale xmu1(m) xmu2 0.0006 0.0 0.0 1.0 1.0 0.0 0.0 !sigy(m) sigpy muxpy yscale pyscale ymu1(m) ymu2 0.0006 0.0 0.0 1.0 1.0 0.0 0.0 !sigz(m) sigpz muxpz zscale pzscale zmu1(m) zmu2 1.27e-06 0.0 0.0 1.0 1.0 0.0 0.0 !Bcurr Bkenergy Bmass Bcharge Bfreq Tini 2855999999.9999995 1.0 511005.0 -1.0 2856000000.0 -2.738554468039765e-12 !=================== LATTICE =================== 0 0 0 -4 0.0 0.0 0.25 4e-12 /!name:change_timestep_1 0 0 0 -5 0.0 0.0 -1000.0 /!name:SC_2D_to_3D !__________________ 1.5 cell gun __________________ ! Single particle phased and scaled for 6 MeV energy 0.15 0 0 105 0.0 47537665.059089914 2856000000.0 303.90095993748866 201 0.15 0.0 0.0 0.0 0.0 0.0 0.0 /!name:GUN !__________________Solenoid and correctors__________________ 0.49308 0 0 105 0.0 0.0 0.0 0.0 102 0.15 0.0 0.0 0.0 0.0 0.0 0.2457 /!name:SOL1 ! Corrector quads: skew and regular. ! Overlap SOL1. Effective length, radius estimated from measurements. ! Max field should be 0.00714 T/m 0.36 0 0 1 0.01601 0.0 0.21 0.0254 0.0 0.0 0.0 0.0 0.7853981633974483 /!name:SQ01 0.36 0 0 1 0.01601 0.0 0.21 0.0254 0.0 0.0 0.0 0.0 0.0 /!name:CQ01 !________________________________________________________________________ !!! Broken: 0 1 101 -2 0.0 0.0 0.61362 /!name:YAG01 0 1 102 -2 0.0 0.0 1.38841 /!name:YAG02 !__________________ L0A begin __________________ 0 -1 0 -6 1 1 1.485 4.527856 0.0116 0.0292 0.035 /!name:wakefield_L0A ! Phased to get to 64 MeV 0.052464 0 0 105 1.485 26013439.060000002 2856000000.0 264.5 4 0.15 0.0 0.0 0.0 0.0 0.0 0.0 /!name:L0A_entrance 2.937928 0 0 105 1.537464 30048347.1 2856000000.0 294.5 5 0.15 0.0 0.0 0.0 0.0 0.0 0.0 /!name:L0A_body_1 2.937928 0 0 105 1.537464 30048347.1 2856000000.0 354.5 6 0.15 0.0 0.0 0.0 0.0 0.0 0.0 /!name:L0A_body_2 0.052464 0 0 105 4.475392 26013439.060000002 2856000000.0 264.5 7 0.15 0.0 0.0 0.0 0.0 0.0 0.0 /!name:L0A_exit !__________________ L0A exit __________________ ! Space charge switches !!!0 0 0 -8 0 1 4.527856 / name:SC_ON !!!0 0 0 -8 0 -1 4.527856 / name:SC_OFF !!!0 0 0 -5 0.0 0.0 4.527856 /!name:SC_2D_to_3D 0 1 103 -2 0.0 0.0 4.614538605 /!name:YAG03 0.204 0 0 1 4.752933605 1.8524000101358 0.108 0.016 0.0 0.0 0.0 0.0 0.0 /!name:QA01 0.204 0 0 1 5.081309605 -1.8524000101358 0.108 0.016 0.0 0.0 0.0 0.0 0.0 /!name:QA02 !__________________ L0B begin __________________ 0 -1 0 -6 1 1 5.328756 8.371612 0.0116 0.0292 0.035 /!name:wakefield_L0B ! Phased to get to 135 MeV 0.052464 0 0 105 5.328756 31395529.900000002 2856000000.0 42.27 4 0.15 0.0 0.0 0.0 0.0 0.0 0.0 /!name:L0B_entrance 2.937928 0 0 105 5.38122 36265246.5 2856000000.0 72.27 5 0.15 0.0 0.0 0.0 0.0 0.0 0.0 /!name:L0B_body_1 2.937928 0 0 105 5.38122 36265246.5 2856000000.0 132.27 6 0.15 0.0 0.0 0.0 0.0 0.0 0.0 /!name:L0B_body_2 0.052464 0 0 105 8.319148 31395529.900000002 2856000000.0 42.27 7 0.15 0.0 0.0 0.0 0.0 0.0 0.0 /!name:L0B_exit !__________________ L0B exit __________________ 0.204 0 0 1 8.392048605 0.18720000156206 0.108 0.016 0.0 0.0 0.0 0.0 0.0 /!name:QE01 0.204 0 0 1 8.793561605 0.16609999999321 0.108 0.016 0.0 0.0 0.0 0.0 0.0 /!name:QE02 !!! Unmodeled: Laser Heater from 9.076892 m to 10.690580 m 0.204 0 0 1 11.469244190867 -2.6409000012747 0.108 0.016 0.0 0.0 0.0 0.0 0.0 /!name:QE03 0.204 0 0 1 11.875644190867 2.9799999853198 0.108 0.016 0.0 0.0 0.0 0.0 0.0 /!name:QE04 !!! 0 1 104 -2 0.0 0.0 12.175332190867 /!name:WS01 0 1 105 -2 0.0 0.0 12.327300190867 /!name:OTR1 !!! 0 1 106 -2 0.0 0.0 14.089061190867 /!name:WS02 0 1 107 -2 0.0 0.0 14.241029190867 /!name:OTR2 !!! 0 1 108 -2 0.0 0.0 16.002790190867 /!name:WS03 !!! 0 1 109 -2 0.0 0.0 16.154758190867 /!name:OTR3 0 0 0 -8 0.0 -1 16.5 /!name:SC_OFF 0 0 0 -99 0.02 0.0 0.02 /!name:stop_1
Functional evaluate_impact_with_distgen¶
Similar to above, but reuruns a dict of common outputs, and an optinal archive file.
This is useful in optimizations and creating datasets.
In [8]:
Copied!
# This returns an Impact object that has run
O1 = evaluate_impact_with_distgen(
SETTINGS0, distgen_input_file=gfile, impact_config=ifile, archive_path="."
)
# This is the default output
O1
# This returns an Impact object that has run
O1 = evaluate_impact_with_distgen(
SETTINGS0, distgen_input_file=gfile, impact_config=ifile, archive_path="."
)
# This is the default output
O1
Out[8]:
{'error': False, 'end_t': np.float64(8.2587796e-11), 'end_mean_z': np.float64(0.019394996), 'end_mean_gamma': np.float64(4.7245665), 'end_mean_beta': np.float64(0.97734344), 'end_max_r': np.float64(0.00048188862), 'end_sigma_gamma': np.float64(0.030050215), 'end_mean_x': np.float64(-7.3036541e-08), 'end_sigma_x': np.float64(0.00022254175), 'end_norm_emit_x': np.float64(2.2733475e-07), 'end_mean_y': np.float64(-1.0694885e-08), 'end_sigma_y': np.float64(0.00022232416), 'end_norm_emit_y': np.float64(2.2707187e-07), 'end_sigma_z': np.float64(0.00028894631), 'end_norm_emit_z': np.float64(2.5412704e-07), 'end_max_amplitude_x': np.float64(0.00047003989), 'end_max_amplitude_y': np.float64(0.00045379458), 'end_max_amplitude_z': np.float64(0.0007008975), 'end_loadbalance_min_n_particle': np.float64(100.0), 'end_loadbalance_max_n_particle': np.float64(100.0), 'end_n_particle': np.float64(100.0), 'end_moment3_x': np.float64(3.4437469e-05), 'end_moment3_y': np.float64(nan), 'end_moment3_z': np.float64(nan), 'end_moment4_x': np.float64(0.00027210158), 'end_moment4_y': np.float64(0.00027072853), 'end_moment4_z': np.float64(0.00035338746), 'end_cov_x__x': np.float64(4.9524829e-08), 'end_cov_x__y': np.float64(-5.2436574e-10), 'end_cov_x__z': np.float64(2.4559681e-09), 'end_cov_y__y': np.float64(4.9428032e-08), 'end_cov_y__z': np.float64(6.1728512e-10), 'end_cov_z__z': np.float64(8.3489973e-08), 'end_mean_kinetic_energy': np.float64(1903272.0999999999), 'end_cov_x__px': np.float64(0.35831143663211046), 'end_cov_y__py': np.float64(0.35526303151596944), 'end_cov_z__pz': np.float64(4.538073496472284), 'end_cov_x__py': np.float64(0.007374815540238299), 'end_cov_x__pz': np.float64(0.13350571143263198), 'end_cov_px__px': np.float64(2864867.0943182963), 'end_cov_y__px': np.float64(-0.018418079256553897), 'end_cov_px__py': np.float64(-58888.61455449906), 'end_cov_z__px': np.float64(0.020540342210730648), 'end_cov_px__pz': np.float64(1127808.5859090092), 'end_cov_y__pz': np.float64(0.033206237613864695), 'end_cov_py__py': np.float64(2825837.7599643157), 'end_cov_z__py': np.float64(0.012698218130717349), 'end_cov_py__pz': np.float64(683963.8799525708), 'end_cov_pz__pz': np.float64(246867661.8349353), 'run_time': 0.11290717124938965, 'end_n_particle_loss': 0, 'end_total_charge': np.float64(0.9999999999999999), 'end_higher_order_energy_spread': np.float64(61.72667652526508), 'end_norm_emit_xy': np.float64(2.2720327198014227e-07), 'end_norm_emit_4d': np.float64(5.1942671033125496e-14), 'fingerprint': '9ced85b60c455a41037b25558fc44ca9', 'archive': '/home/runner/work/lume-impact/lume-impact/docs/examples/9ced85b60c455a41037b25558fc44ca9.h5'}
In [9]:
Copied!
I2 = Impact.from_archive(O1["archive"])
I2 = Impact.from_archive(O1["archive"])
In [10]:
Copied!
I2.fingerprint() == I.fingerprint()
I2.fingerprint() == I.fingerprint()
Out[10]:
False
A custom merit function can be provided to give different output. Note that the fingerprint is always returned.
In [11]:
Copied!
# Custom merit function
def my_merit(impact_object):
"""
Custom merit function.
Returns the maximum sigma_x seen
"""
d = {"max_sigma_x": I.stat("sigma_x").max()}
return d
evaluate_impact_with_distgen(
SETTINGS0, distgen_input_file=gfile, impact_config=ifile, merit_f=my_merit
)
# Custom merit function
def my_merit(impact_object):
"""
Custom merit function.
Returns the maximum sigma_x seen
"""
d = {"max_sigma_x": I.stat("sigma_x").max()}
return d
evaluate_impact_with_distgen(
SETTINGS0, distgen_input_file=gfile, impact_config=ifile, merit_f=my_merit
)
Out[11]:
{'max_sigma_x': np.float64(0.00025965193), 'fingerprint': '9ced85b60c455a41037b25558fc44ca9'}
In [12]:
Copied!
# Cleanup
os.remove(O1["archive"])
os.remove(h5file)
# Cleanup
os.remove(O1["archive"])
os.remove(h5file)