Parallel Impact-T run¶
This example shows how to set up the Impact-T input files and run script, but to leave the running to the user.
In [1]:
Copied!
from impact import Impact
import os
# Nicer plotting
import matplotlib
%config InlineBackend.figure_format = 'retina'
matplotlib.rcParams["figure.figsize"] = (8, 4)
NUMPROCS = 0 # auto-select
from impact import Impact
import os
# Nicer plotting
import matplotlib
%config InlineBackend.figure_format = 'retina'
matplotlib.rcParams["figure.figsize"] = (8, 4)
NUMPROCS = 0 # auto-select
In [2]:
Copied!
ifile = "templates/lcls_injector/ImpactT.in"
os.path.exists(ifile)
ifile = "templates/lcls_injector/ImpactT.in"
os.path.exists(ifile)
Out[2]:
True
In [3]:
Copied!
# Make Impact object
I = Impact(ifile)
# Change some things
I.header["Np"] = 10000 // 2 # Make smaller problem for speed
I.header["Nx"] = 32 // 2
I.header["Ny"] = 32 // 2
I.header["Nz"] = 32 // 2
I.header["Dt"] = 5e-13
I.stop = 3
# Turn on MPI and set parallel domain
I.numprocs = NUMPROCS
I.path
# Make Impact object
I = Impact(ifile)
# Change some things
I.header["Np"] = 10000 // 2 # Make smaller problem for speed
I.header["Nx"] = 32 // 2
I.header["Ny"] = 32 // 2
I.header["Nz"] = 32 // 2
I.header["Dt"] = 5e-13
I.stop = 3
# Turn on MPI and set parallel domain
I.numprocs = NUMPROCS
I.path
Out[3]:
'/tmp/tmp5ms5h05h'
In [4]:
Copied!
# Write input to workdir
I.write_input()
# This will be the working path
I.path
# Write input to workdir
I.write_input()
# This will be the working path
I.path
Out[4]:
'/tmp/tmp5ms5h05h'
In [5]:
Copied!
!cat {I.path}/ImpactT.in
!cat {I.path}/ImpactT.in
! Impact-T input file !Npcol Nprow 2 1 !Dt Ntstep Nbunch 5e-13 1000000 1 !Dim Np Flagmap Flagerr Flagdiag Flagimg Zimage 6 5000 1 0 2 1 0.02 !Nx Ny Nz Flagbc Xrad Yrad Perdlen 16 16 16 1 0.015 0.015 45.0 !Flagdist Rstartflg Flagsbstp Nemission Temission 16 0 0 400 6.515803466731775e-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 0.7140000000000003 1.0 511005.0 -1.0 2856000000.0 -3.249141278122655e-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.93723122804266 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 3 0.0 3 /!name:stop_1
Run externally¶
Parallel jobs often need to be run on special nodes and/or submitted to a queue, invoking the run script:
In [6]:
Copied!
I.path
I.path
Out[6]:
'/tmp/tmp5ms5h05h'
In [7]:
Copied!
!cat {I.path}/run
!cat {I.path}/run
mpirun -n 2 /home/runner/miniconda3/envs/lume-impact-dev/bin/ImpactTexe-mpi
Here we will do a quick run
In [8]:
Copied!
%%time
!cd {I.path};./run >log.txt
%%time
!cd {I.path};./run >log.txt
CPU times: user 134 ms, sys: 35.9 ms, total: 170 ms Wall time: 15 s
In [9]:
Copied!
# Save into template for the other examples to use
# OUTPATH = os.path.join(os.path.split(ifile)[0], 'output/')
#!cp {I.path}/fort* {OUTPATH}
# Save into template for the other examples to use
# OUTPATH = os.path.join(os.path.split(ifile)[0], 'output/')
#!cp {I.path}/fort* {OUTPATH}
Collect output¶
In [10]:
Copied!
I.verbose = True
# Load output
I.load_output()
I.verbose = True
# Load output
I.load_output()
Loaded fort 18 : Time and energy Loaded fort 24 : RMS X information Loaded fort 25 : RMS Y information Loaded fort 26 : RMS Z information
Loaded fort 27 : Max amplitude information Loaded fort 28 : Load balance and loss diagnostics Loaded fort 29 : Cube root of third moments of the beam distribution Loaded fort 30 : Fourth root of the fourth moments of the beam distribution Loaded fort 32 : Covariance matrix of the beam distribution
Loaded fort 60 : Slice information of the initial distribution Loaded fort 70 : Slice information of the final distribution Loading particles Loaded fort 40 : initial particle distribution at t = 0 Loaded fort 50 : final particle distribution projected to the centroid location of the bunch Loaded write beam particles YAG02 fort.102 Converting z to t according to cathode_kinetic_energy_ref = 1.0 eV Converted initial_particles to ParticleGroup Converted final_particles to ParticleGroup Converted YAG02 to ParticleGroup
In [11]:
Copied!
I.plot(ylim=(0, 0.002))
I.plot(ylim=(0, 0.002))
Alternative: load into new object¶
If this notebook went out of scope, or the run was done previously, we'd need to load the output into a new object.
In [12]:
Copied!
I2 = Impact(f"{I.path}/ImpactT.in", use_temp_dir=False)
I2 = Impact(f"{I.path}/ImpactT.in", use_temp_dir=False)
In [13]:
Copied!
I2.load_output()
I2.load_output()
In [14]:
Copied!
I.plot(ylim=(0, 0.002))
I.plot(ylim=(0, 0.002))
Archiving¶
Archiving is the same as in the simple example
In [15]:
Copied!
afile = os.path.expandvars("output.h5")
I2.archive(afile)
afile = os.path.expandvars("output.h5")
I2.archive(afile)
Out[15]:
'output.h5'
In [16]:
Copied!
# Cleanup
os.remove(afile)
# Cleanup
os.remove(afile)