In this example we calculate the on-axis multi-particle spectrum 30 [m] downstream from the center of the EPU.
# This has nothing to do with OSCARS, but it puts the matplotlib plots inline in the notebook %matplotlib inline # Import the OSCARS SR module import oscars.sr # Import basic plot utilities (matplotlib). You don't need these to run OSCARS, but it's used here for basic plots from oscars.plots_mpl import *
OSCARS v2.1.8 - Open Source Code for Advanced Radiation Simulation Brookhaven National Laboratory, Upton NY, USA http://oscars.bnl.gov firstname.lastname@example.org
# Create a new OSCARS object. Default to 8 threads and always use the GPU if available osr = oscars.sr.sr(nthreads=8, gpu=1)
Here we create an EPU by adding two ideal undulators, one with a vertical field and one with a horizontal field, out of phase.
For the undulator, bfield represents maximum magnetic field [$B_x, B_y, B_z$]. The period is also in vector form which allows you to orient the axis of the undulator in any arbitrary direction. The number of periods is given by nperiods. This is the number of FULL periods. A terminating field of 1 period length is added to each side in addition to nperiods.
Typically clear_magnetic_fields() is called before adding a field in notebooks only to save time when making changes and rerunning sections of the code so it is not strictly necessary.
# Phase difference between fields in [rad] phase = osr.pi()/2. # Clear any existing fields (just good habit in notebook style) and add an undulator field osr.clear_bfields() osr.add_bfield_undulator(bfield=[0, 0.7, 0], period=[0, 0, 0.049], nperiods=21, phase=-phase/2.) osr.add_bfield_undulator(bfield=[0.7, 0, 0], period=[0, 0, 0.049], nperiods=21, phase=+phase/2.) # Just to check the field that we added seems visually correct plot_bfield(osr)
Here we add a particle beam making use of some of the defaults, namely:
* type='electron' * t0=0 * d0=[0, 0, 1]
One must specify ctstartstop. This is the start and stop time of the calculation. In this example we will start the calculation at t=0 and go to t=2 (given in units of ct) since the beam is relativistic. In this example you can specify the start time as less than 0 which is useful if you want to propogate the particle backwars in time. This is useful for instance if you have a bending magnet before the undulator that you wish to include.
clear_particle_beams() is called, again for convenience, but it is not necessary.
# Setup beam similar to NSLSII osr.clear_particle_beams() osr.set_particle_beam( energy_GeV=3, x0=[0, 0, -1], current=0.500, sigma_energy_GeV=0.001*3, beta=[1.5, 0.8], emittance=[0.9e-9, 0.008e-9] ) # Set the start and stop times for the calculation osr.set_ctstartstop(0, 2)
Now we calculate the trajectory and plot it. It is enough to call calculate_trajectory(). If you are doing other calculations (flux, spectra, power density) it is not necesary to call this since it is called internally.
# Run the particle trajectory calculation for the ideal particle # First must load the ideal particle initial conditions osr.set_new_particle(particle='ideal') trajectory = osr.calculate_trajectory() # Plot the trajectory position and velocity plot_trajectory_position(trajectory) plot_trajectory_velocity(trajectory)
Calculate the spectrum in a given range with the given number of points equally spaced (not a requirement).
# Calculate spectrum zoom for ideal particle. In reality you may want to run the multi-particle # spectrum calculation, then pick from there what energy we want to see the spectrum at osr.set_new_particle(particle='ideal') spectrum_ideal = osr.calculate_spectrum(obs=[0, 0, 30], energy_range_eV=[130, 180], npoints=200) plot_spectrum(spectrum_ideal)
# Calculate the multi-particle spectrum. We use 10 particles here, but in general you # should use a lot more osr.set_new_particle(particle='ideal') spectrum_multi = osr.calculate_spectrum( obs=[0, 0, 30], energy_range_eV=[130, 180], npoints=200, nparticles=100 ) plot_spectrum(spectrum_multi)
# Combine the ideal and multi-particle spectra in one plot plot_spectra([spectrum_ideal, spectrum_multi], ['ideal', 'multi'])
It may be of interested to calculate polarization components for such a device. Below is shown the circular-right and circular left components for the multi-particle simulation.
# Calculate spectrum, circular right and left, short versions are: 'cr', 'cl' spectrum_cr = osr.calculate_spectrum( obs=[0, 0, 30], energy_range_eV=[140, 350], polarization='circular-right', nparticles=100 ) spectrum_cl = osr.calculate_spectrum( obs=[0, 0, 30], energy_range_eV=[140, 350], polarization='cl', nparticles=100 ) # Plot both spectra on the same plot plot_spectra([spectrum_cr, spectrum_cl], ['circular-right', 'circular-left'])