Absorption of particles

Using conductor objects

To absorb particles on conductor objects, a particle scraper must be created. The objects which should scrape particles are passed into the scrapers. In this example, target is a cylinder that will absorb all of the particles that hit it.

target = ZCylinder(.01,.1,zcent=0.8)

scraper = ParticleScraper(target)

If particles will be absorbed on multiple conductors, the list is given to the particle scraper. For example:

scraper = ParticleScraper([c1,c2,target])

Additionally, once the scraper is created, new conductors can be registered.

cnew = ZCylinderOut(.03,.8)


In general, only one scraper should be created.

Note that conductor objects can have an identification number, which is stored in condid. For the particle scraping to work properly, this number must be nonzero, and each conductor registered must have a unique condid. If the condid is not specified when creating the objects, it will by default have a unique condid.

Also note that the conductors used for particle scraping can be the same ones used in the field solution, but do not have to be.

The ParticleScraper class is defined in the python file particlescraper.py.

Visualizing the ParticleScraper

The particle scraper can be visualized using functions pdzx(), pdzy() and pdxy(). If defined as above one could draw the scraper by calling for example


This will plot a grid in the z-x plane showing where particles will be examined for scraping. The grid is used to select particles that are near a conductor surface - only those particles are checked if they are inside the conductor.

Removing particles directly

Particles can be removed directly, for example by user created functions. The user creates a function that modifies the appropriate particle quantity and installs the function so that it is called at the correct place during the time step. Internally, when the particle scraping is done, the gamma inverse of the particle is used as a flag to determine whether a particle has been lost or not. The user's function can use this, setting the gamma inverse of the particles that need to be scraped. Setting it to zero signifies a particle that is to be scraped.

The following function will cause beam species particles above a specified radius to be scraped.

aperture_radius = 1.*cm

def scrapebeam():

rsq = beam.xp**2 + beam.yp**2

beam.gaminv[rsq >= aperture_radius**2] = 0.

This function is then installed so that it will be called during the particle scraping.


The scraping will occur each time step.

If the lost particles are being saved, i.e. top.lsavelostpart=1, the particles scraped by this method will be saved. If this is not desired, gaminv can be set to -1 and the particles will be scraped but not saved.

Lost particle diagnostics

By default, Warp does not keep track of lost particles - they are just deleted. There are ways, however, of saving the lost particles. The simplest is to set the flag telling Warp to save them.

top.lsavelostparticles = true

The lost particles can be accessed similarly to live particles. The following will return the x position of the lost particles for the beam species - this is the x position where the particles were lost.

x = beam.getx(lost=1)

The same argument can be given to the plot commands. This will plot the lost particles in the z-x plane.


A useful diagnostic that is always saved is lostpars, which holds the number of lost particles as a function of z in the beam frame. This is saved for each species. The following will plot the number of lost beam particles.


When using the particle scraper, there is an option, lcollectlpdata, to save lost particle statistics for the conductors.

scraper = ParticleScraper([c1,c2,target],lcollectlpdata=True)

After running the simulation, there are various methods for each of the conductors to post-process the saved data.





There is online documentation that can be obtained by this:


The data saved also includes particles emitted from the conductor and image charges.