In [1]:
Copied!
# Useful for debugging
%load_ext autoreload
%autoreload 2
# Useful for debugging
%load_ext autoreload
%autoreload 2
pySuperfish Fish Example¶
This example should run on Linux, macOS, and Windows
In [2]:
Copied!
from superfish import Superfish
from superfish import Superfish
In [3]:
Copied!
# by default, will try to use the private container hhslepicka/poisson-superfish:latest
# see https://github.com/hhslepicka/docker-poisson-superfish-nobin for instructions
# on building and using your own docker container
#Superfish._container_image = "poisson-superfish"
# by default, will try to use the private container hhslepicka/poisson-superfish:latest
# see https://github.com/hhslepicka/docker-poisson-superfish-nobin for instructions
# on building and using your own docker container
#Superfish._container_image = "poisson-superfish"
In [4]:
Copied!
import os
AMFILE = os.path.join('data', 'swifel_7.000_9.170_36.000_5.531_9.819_30.000_2.000_5469.am')
import os
AMFILE = os.path.join('data', 'swifel_7.000_9.170_36.000_5.531_9.819_30.000_2.000_5469.am')
In [5]:
Copied!
# by default, will auto-detect system and use a container on Linux or macOS, or no container on (native) Windows
SF = Superfish(AMFILE, verbose=True)
# On Windows Subsystem for Linux (WSL), if you want to run this notebook on Linux but
# want PySuperfish to use the Windows executables, you can do this instead:
#SF = Superfish(AMFILE, verbose=True, use_container=False)
#Superfish._windows_exe_path = '/mnt/c/LANL/'
# by default, will auto-detect system and use a container on Linux or macOS, or no container on (native) Windows
SF = Superfish(AMFILE, verbose=True)
# On Windows Subsystem for Linux (WSL), if you want to run this notebook on Linux but
# want PySuperfish to use the Windows executables, you can do this instead:
#SF = Superfish(AMFILE, verbose=True, use_container=False)
#Superfish._windows_exe_path = '/mnt/c/LANL/'
Configured to run in: /tmp/tmplb2ssyev
Using container on Linux:
docker run {interactive_flags} --rm -v {local_path}:/data/ {image} {cmds}
In [6]:
Copied!
# Run, should take about a minute
SF.run()
# Run, should take about a minute
SF.run()
Running: docker run --rm -v /tmp/tmplb2ssyev:/data/ poisson-superfish autofish SWIFEL_7.000_9.170_36.000_5.531_9.819_30.000_2.000_5469.AM Done in 55.86 seconds Parsed output: /tmp/tmplb2ssyev/SWIFEL_7.000_9.170_36.000_5.531_9.819_30.000_2.000_5469.SFO
In [7]:
Copied!
# This is automatically done above
SF.load_output()
# This is automatically done above
SF.load_output()
Parsed output: /tmp/tmplb2ssyev/SWIFEL_7.000_9.170_36.000_5.531_9.819_30.000_2.000_5469.SFO
SFO Output¶
In [10]:
Copied!
SF.output.keys()
SF.output.keys()
Out[10]:
dict_keys(['sfo'])
In [11]:
Copied!
SF.output['sfo'].keys()
SF.output['sfo'].keys()
Out[11]:
dict_keys(['wall_segments', 'other', 'header', 'BeamEnergy', 'summary'])
In [12]:
Copied!
# Readback of the basic parameters, with the description
header = SF.output['sfo']['header']
for key in header['variable']:
print(f"{key:10} {header['variable'][key]:16} {header['description'][key]}")
# Readback of the basic parameters, with the description
header = SF.output['sfo']['header']
for key in header['variable']:
print(f"{key:10} {header['variable'][key]:16} {header['description'][key]}")
ALPHAT 0.00393 Temperature coefficient of resistance ASCALE 3767.30313 Scaling factor for H at drive point BETA 0.95 Particle velocity BETA1 0.1 Starting BETA in transit-time table BETA2 0.95 Ending BETA in transit-time table CCLDELK 1.0 Increment for coupling for table in SFO CCLMAXK 6.0 Highest coupling for table in SFO CCLMINK 1.0 Lowest coupling for table in SFO CLENGTH 0.0 Cavity length for normalization in SFO CLIGHT 29979245800.0 Exact speed of light in cm/sec CONV 1.0 Length conversion (number of units per cm) DBETA 0.05 BETA increment in transit-time table DELFR 0.0 Frequency step size for a resonance search DIAGDLL 0 If 1, DLL writes diagnostics to DiagDLL.txt DKSQ 2.0162059e-10 Change in k^2 after an iteration in Fish DPHI 180.0 Phase length of the problem geometry DSLOPE -0.999970577 Slope of D(k^2) function DSTOLER 0.02 Tolerance required on D(k^2) DX1 0.205259127 First X mesh interval (at XMIN) DXMIN 0.01 Minimum X mesh interval (found by Automesh) DYMIN 0.01 Minimum Y mesh interval (found by Automesh) ENORM 30000000.0 Field normalization for NORM=4 option EPS0 8.854187818e-12 Permittivity of free space EPSIK 0.0001 Frequency convergence parameter EPSO 1e-06 Convergence parameter in mesh optimization ERG 23466.8637 Integral (H^2 r dr dz) EZERO 1000000.0 E0 for normalization in SFO when NORM=0 EZEROT 1000000.0 E0*T for normalization in SFO when NORM=1 FMU0 1.256637061e-06 Permeability of free space FREQ 175.715181 RF cavity resonant frequency FREQD 199.6 Design frequency for a cavity (MHz) HPHI 5000.0 Normalization magnetic field for NORM=2 IBETA 0 If >0, SFO writes transit-time vs BETA ICCC 1 1 for real arrays, 2 for complex arrays ICCP 1 If 1, compute material power loss ICORNER1 0 First corner segment for computing average H ICORNER2 0 Last corner segment for computing average H ICYCLE 4 Present iteration number ICYLIN 1 0 for X,Y problems, 1 for Z,R problems IMAX 553 KMAX+2 INFODATA 0 Number of tuning-code parameters IOBSEG -1 First segment of the CCL outer boundary IPIVOT 1 Pivoting in matrix inversion routines IRESID 0 If 1, calculate potential residuals IRMAX 25 Used in optimization of RHOXY IRTYPE 1 Surface resistance option indicator ISLOT 0 If 1, SFO computes coupling-slot power loss ITFILE 0 If 1, SFO writes transit-time plot file ITOT 170324 (KMAX+2)*(LMAX+2) KDRI 121 K coordinate of the drive point KMAX 551 Number of horizontal logical mesh points KMETHOD 1 Wavenumber computation method (1= use beta) KPROB 1 Problem type indicator (Superfish) LAST35 1 Code for last program to update T35 file LCYCLE 129 Iteration number in mesh optimization LDRI 306 L coordinate of the drive point LINT 1 Logical-mesh coordinate for Ez integration LMAX 306 Number of vertical logical mesh points MAXCY 19 Maximum number of cycles (-1: use default) MAXPPR 1587 Maximum points per region METHOD 2 Method used to get frequency in root finder NAIR 81619 Number of air points NBND 218 Number of Dirichlet boundary points NBSLF 1 Left-side boundary condition NBSLO 0 Lower boundary condition NBSRT 1 Right-side boundary condition NBSUP 1 Upper boundary condition NDRI 169340 Drive point index = IRLAX(NPINP) NEGAT 0 Zero-area triangle indicator NFE 0 Number of iron points NHSTEM 1 Number of half stems NINTER 0 Number of interface points NMATR 0 Number of material records in T35 file NORM 4 Normalization method in SFO NPBOUND 1586 Total number of boundary points in the mesh NPINP 81838 Total points in problem NPONTS 78216 Number of unknown relaxation points NREG 12 Number of regions NRMSEG 1 Normalization segment number for NORM=2 NSEG 29 Number of boundary segments NSPL 1 Number of special-potential points NSTEP 0 Number of steps for a resonance search OMEGAM 0.001 Used in optimization of RHOXY PI 3.14159265 The number pi to machine precision PLCELL 360.0 Phase length per cell for multicell problems Q2I 0.0 1/2Q passed from CFish to SFO RESIDR 1e-08 Residual resistance of a superconductor RESIK 1.486569292e-07 Residual = DKSQ/XKSQ RFMU 1.0 Permeability for rf surface resistance RHO 1.7241e-06 Material resistivity (Ohm-m) RHOC 1.7241e-06 Computed resistivity for IRTYPE=3 RHOR 1.7241e-06 Reference resistivity (Ohm-cm) at TEMPR RHOXY 1.6 Over-relaxation factor in mesh optimization RMASS -1.0 Rest mass energy of particle in SFO RSTEM 1.0 Stem radius in cm SLOSS 0.03 Coupling-slot power factor per % coupling TC 9.2 Critical temperature of a superconductor TEMPC 20.0 Normal conductor operating temperature TEMPK 4.2 Operating temperature of a superconductor TEMPR 20.0 Reference temperature for IRTYPE=3 TRIAVG 0.004699172741 Average area of all triangles TRIMAX 0.05325771449 Area of the largest positive-area triangle TRIMIN 3.002529383e-05 Area of the smallest positive-area triangle VOLUME 91630.8421 Cavity volume (cylindrical symmetry only) XDRI 35.0 X coordinate of the drive point XK0 0.03682717867 The wave number k = 2pif/c XKSQ 0.001356241089 Square of the wave number XMAXG 73.0 Upper X bound of the problem geometry XMING 10.2206557 Lower X bound of the problem geometry XNORM1 50.5 Starting X for NORM=4 integration path XNORM2 50.51 Ending X for NORM=4 integration path XYAREA 761.68421 Total cross sectional area YDRI 30.0 Y coordinate of the drive point YMAXG 30.0 Upper Y bound of the problem geometry YMING 0.0 Lower Y bound of the problem geometry YNORM1 0.0 Starting Y for NORM=4 integration path YNORM2 0.0 Ending Y for NORM=4 integration path ZCTR 0.0 Reference Z in transit-time integrals
In [13]:
Copied!
SF.output['sfo']['summary']
SF.output['sfo']['summary']
Out[13]:
{'type': 'summary',
'data': {'Enorm': 30.0,
'integration_Z1': 50.5,
'integration_R1': 0.0,
'integration_Z2': 50.51,
'integration_R2': 0.0,
'Frequency': 175.71518,
'Particle rest mass energy': 0.510999,
'beta': 0.95,
'kinetic_energy': 1.82899,
'Normalization factor for E0': 58982.877,
'Transit-time factor': 0.9949286,
'Stored energy': 22.7093948,
'Superconductor surface resistance': 22.0147,
'Operating temperature': 4.2,
'Power dissipation': 7266.1288,
'Q': 3450580000.0,
'Shunt impedance': 2001666.082,
'Rs*Q': 75.963,
'Z*T*T': 1981414.951,
'r/Q': 132.072,
'Wake loss parameter': 0.03645,
'AvgH': 15002.1,
'MaxH_z': 24.7307,
'MaxH_r': 17.4738,
'MaxH': 31503.2,
'MaxE_z': 49.6677,
'MaxE_r': 4.35367,
'MaxE': 32.9096,
'Ratio of peak fields Bmax/Emax': 1.2029,
'Peak-to-average ratio Emax/E0': 4.1385},
'units': {'Enorm': 'MV/m',
'integration_Z1': 'cm',
'integration_R1': 'cm',
'integration_Z2': 'cm',
'integration_R2': 'cm',
'Frequency': 'MHz',
'Particle rest mass energy': 'MeV',
'beta': '',
'kinetic_energy': 'MeV',
'Normalization factor for E0': '',
'Transit-time factor': '',
'Stored energy': 'Joules',
'Superconductor surface resistance': 'nanoOhm',
'Operating temperature': 'K',
'Power dissipation': 'mW',
'Q': '',
'Shunt impedance': 'MOhm/m',
'Rs*Q': 'Ohm',
'Z*T*T': 'MOhm/m',
'r/Q': 'Ohm',
'Wake loss parameter': 'V/pC',
'AvgH': 'A/m',
'MaxH_z': 'cm',
'MaxH_r': 'cm',
'MaxH': 'A/m',
'MaxE_z': 'cm',
'MaxE_r': 'cm',
'MaxE': 'MV/m',
'Ratio of peak fields Bmax/Emax': 'mT/(MV/m)',
'Peak-to-average ratio Emax/E0': ''}}
In [14]:
Copied!
SF.output['sfo']['summary']['data']
SF.output['sfo']['summary']['data']
Out[14]:
{'Enorm': 30.0,
'integration_Z1': 50.5,
'integration_R1': 0.0,
'integration_Z2': 50.51,
'integration_R2': 0.0,
'Frequency': 175.71518,
'Particle rest mass energy': 0.510999,
'beta': 0.95,
'kinetic_energy': 1.82899,
'Normalization factor for E0': 58982.877,
'Transit-time factor': 0.9949286,
'Stored energy': 22.7093948,
'Superconductor surface resistance': 22.0147,
'Operating temperature': 4.2,
'Power dissipation': 7266.1288,
'Q': 3450580000.0,
'Shunt impedance': 2001666.082,
'Rs*Q': 75.963,
'Z*T*T': 1981414.951,
'r/Q': 132.072,
'Wake loss parameter': 0.03645,
'AvgH': 15002.1,
'MaxH_z': 24.7307,
'MaxH_r': 17.4738,
'MaxH': 31503.2,
'MaxE_z': 49.6677,
'MaxE_r': 4.35367,
'MaxE': 32.9096,
'Ratio of peak fields Bmax/Emax': 1.2029,
'Peak-to-average ratio Emax/E0': 4.1385}
In [15]:
Copied!
# Convenient access and information
SF.param('CONV'), SF.param_info('CONV')
# Convenient access and information
SF.param('CONV'), SF.param_info('CONV')
Out[15]:
(1.0, 'Length conversion (number of units per cm)')
Plot¶
In [16]:
Copied!
# Nicer plotting
import matplotlib.pyplot as plt
%config InlineBackend.figure_format = 'retina'
# Nicer plotting
import matplotlib.pyplot as plt
%config InlineBackend.figure_format = 'retina'
In [17]:
Copied!
SF.plot_wall()
SF.plot_wall()
In [18]:
Copied!
SF.plot_wall(perp_scale=2, figsize=(16,9))
SF.plot_wall(perp_scale=2, figsize=(16,9))
In [19]:
Copied!
SF.plot_wall(perp_scale=2, field='H', figsize=(16,9))
SF.plot_wall(perp_scale=2, field='H', figsize=(16,9))
Interpolate¶
In [20]:
Copied!
?SF.interpolate
?SF.interpolate
Signature: SF.interpolate(zmin=-1000, zmax=1000, nz=100, rmin=0, rmax=0, nr=1) Docstring: Interpolates field over a grid. File: ~/github/PySuperfish/superfish/superfish.py Type: method
In [21]:
Copied!
SF.interactive = False
SF.interactive = False
In [22]:
Copied!
%%time
# Get the data
t7data = SF.interpolate(zmin=50, zmax = 70, rmax = 3, nz=100, nr=20)
t7data.keys()
%%time
# Get the data
t7data = SF.interpolate(zmin=50, zmax = 70, rmax = 3, nz=100, nr=20)
t7data.keys()
Running: docker run --rm -v /tmp/tmplb2ssyev:/data/ poisson-superfish sf7 SWIFEL_7.000_9.170_36.000_5.531_9.819_30.000_2.000_5469.IN7 SWIFEL_7.000_9.170_36.000_5.531_9.819_30.000_2.000_5469.T35 CPU times: user 3.04 ms, sys: 112 µs, total: 3.15 ms Wall time: 9.67 s
Out[22]:
dict_keys(['geometry', 'problem', 'zmin', 'zmax', 'nz', 'freq', 'rmin', 'rmax', 'nr', 'Ez', 'Er', 'E', 'Hphi'])
In [23]:
Copied!
from superfish import plot
import numpy as np
z = np.linspace(t7data['zmin'], t7data['zmax'], t7data['nz'])
Ez = t7data['Ez'][0,:]
plt.title('On-axis field')
plt.xlabel('z (cm)')
plt.ylabel('Ez (MV/m)')
plt.plot(z, Ez, color='black')
from superfish import plot
import numpy as np
z = np.linspace(t7data['zmin'], t7data['zmax'], t7data['nz'])
Ez = t7data['Ez'][0,:]
plt.title('On-axis field')
plt.xlabel('z (cm)')
plt.ylabel('Ez (MV/m)')
plt.plot(z, Ez, color='black')
Out[23]:
[<matplotlib.lines.Line2D at 0x7fbec8b452b0>]
In [24]:
Copied!
# Plot field data
fig, ax = plt.subplots(figsize=(12,7))
ax.set_title(AMFILE)
plot.add_t7data_to_axes(t7data, ax, field='E')
plot.plot_wall(SF.output['sfo']['wall_segments'], ax=ax)
# Plot field data
fig, ax = plt.subplots(figsize=(12,7))
ax.set_title(AMFILE)
plot.add_t7data_to_axes(t7data, ax, field='E')
plot.plot_wall(SF.output['sfo']['wall_segments'], ax=ax)
FieldMesh from interpolation¶
Alternatively, an openPMD-beamphysics FieldMesh object can be returned.
In [25]:
Copied!
FM = SF.fieldmesh(zmin=0.50, zmax=0.7, dz=0.001, rmax=0.02, nr=10)
FM = SF.fieldmesh(zmin=0.50, zmax=0.7, dz=0.001, rmax=0.02, nr=10)
Running: docker run --rm -v /tmp/tmplb2ssyev:/data/ poisson-superfish sf7 SWIFEL_7.000_9.170_36.000_5.531_9.819_30.000_2.000_5469.IN7 SWIFEL_7.000_9.170_36.000_5.531_9.819_30.000_2.000_5469.T35
In [26]:
Copied!
FM.attrs
FM.attrs
Out[26]:
{'eleAnchorPt': 'beginning',
'gridGeometry': 'cylindrical',
'axisLabels': ('r', 'theta', 'z'),
'gridLowerBound': (0, 1, 0),
'gridOriginOffset': (0, 0, 0.5),
'gridSpacing': (0.0022222222222222222, 0, 0.0010000000000000002),
'gridSize': (10, 1, 200),
'harmonic': 1,
'fundamentalFrequency': 175715180.667,
'RFphase': 0,
'fieldScale': 1.0}
In [27]:
Copied!
FM.plot('E')
FM.plot('E')
In [28]:
Copied!
# Btheta is complex (pure imaginary in this case). Access via:
FM.plot('abs_Btheta')
# Btheta is complex (pure imaginary in this case). Access via:
FM.plot('abs_Btheta')
In [29]:
Copied!
# On-axis field
z0 = FM.coord_vec('z')
Ez0 = np.real(FM.Ez[0,0,:])
plt.title('On-axis field')
plt.xlabel('z (cm)')
plt.ylabel('Ez (MV/m)')
plt.plot(z0*100, Ez0/1e6, color='black')
# On-axis field
z0 = FM.coord_vec('z')
Ez0 = np.real(FM.Ez[0,0,:])
plt.title('On-axis field')
plt.xlabel('z (cm)')
plt.ylabel('Ez (MV/m)')
plt.plot(z0*100, Ez0/1e6, color='black')
Out[29]:
[<matplotlib.lines.Line2D at 0x7fbebe8fb710>]
Interactive¶
You can use Superfish's own graphical tools (when running in a container) with the interactive flag (currently, only supported on macOS).
In [ ]:
Copied!
SF.interactive = True
# This will pop up the WSFPLOT.EXE window.
SF.run_cmd('wsfplot')
SF.interactive = False
SF.interactive = True
# This will pop up the WSFPLOT.EXE window.
SF.run_cmd('wsfplot')
SF.interactive = False
In [28]:
Copied!
# Save
#!cp {SF.path}/SWIFEL1.T7 data/SWIFEL.T7
#!cp {SF.path}/OUTSF7.TXT data/SWIFEL_OUTSF7.TXT
# Save
#!cp {SF.path}/SWIFEL1.T7 data/SWIFEL.T7
#!cp {SF.path}/OUTSF7.TXT data/SWIFEL_OUTSF7.TXT