In a particle in cell code such as Warp, it is common to need to retrieve data from an input grid to the particle positions (examples: applied field data from a rf cavity or magnetic design code) or to need to deposit particle data on a grid (example: to calculate fluid moments of the particle phase-space distribution). It is common to call retrieval of data from a grid to particle locations as "weighting" and deposition of particle data to a grid as "binning." Fortunately, Warp has numerous efficient tools to aid the user in these common tasks. Routines are efficiently written in fast complied code in dtop.F and linked to the python interpreter where they can be called with broad flexibility for the specific tasks needed by the user. These tools are grouped into several categories covered below: "getting" data from a grid to particle positions, "setting" particle position data on a grid, "depositing" particle quantities on a grid based on particle positions, and special purpose routines. Many of these routines have variants for 1d, 2d, and 3d geometry with some 2d routines being specifically designed for use in r-z cylindrical geometry. Consistent with the usual Warp structure, grids/meshes are assumed to be uniformly spaced and interpolations of data retrievals or depositions are low-order "linear" (linear, area, or volume in 1d, 2d, and 3d) methods, or in some cases, lowest-order nearest grid point methods. Users can examine Fortran code in dtop.F for details of specific routines. Getting Data from a Grid to Particle PositionsRoutines to "get" or "weight" gridded data to the particle coordinates using linear interpolation from the grid nodes to the particle coordinates include: `getgrid1d(...) ` `getgrid2d(...) ` `getgrid3d(...) ` for 1d, 2d, and 3d cases using linear (linear, area, and volume in 1d, 2d, and 3d) interpolation. Arguments of the routines are not shown. For getgrid1d(), they are: `getgrid1d(np:integer,x(np):real,z(np):real,` and arguments for getgrid2d() and getgrid3d() are analogously extended to higher dimensions for uniform 2d and 3d grids and can be found using doc(). For getgrid1d(), arguments correspond to np number of particles x(np) array of particle x-coordinates that grid data will be retrieved from z(np) array of interpolated values grid data to particle positions nx upper grid index of data grid(0:nx) array of gridded data values xmin min x-value of gridded data corresponding to grid(0) xmax max x-value of gridded data corresponding to grid(nx) Note that the x-grid values are not input because the grid is assumed to be uniformly spaced from x=xmin (grid node n=0) to x=xmax (grid node n=nx). Linearly interpolated z-data is passed to the python interpreter via the argument list (linked to a subroutine call complied code). Nearest grid point variants of the linear interpolation getgridxd() routines are also available in 1d, 2d, and 3d versions: `getgridngp1d(...) ` `getgridngp2d(...) ` `getgridngp3d(...)` Arguments are the same as the corresponding linear interpolation routines. The "getgrid" routines are commonly used for tasks such as interpolating applied field data exported from some other code into Warp (see Saving/Retrieving Warp Data in External Files) to the particle positions or in constructing various diagnostic measures. Setting Particle Position Data on a GridRoutines to deposit (bin) particles onto a node centered grid using linear interpolation include: `setgrid1d(...)` `setgrid2d(...)` `setgrid3d(...) ` for 1d, 2d, and 3d cases using linear (linear, area, and volume in
1d, 2d, and 3d) interpolation. Arguments of the routines are not shown.
For setgrid1d(), they are: `setgrid1d(np:integer,x(np):real,nx:integer,grid(0:nx):real,xmin:real,xmax:real) ` and arguments for setgrid2d() and setgrid3d() are analogously
extended to higher dimensions for uniform 2d and 3d grids and can be
found using doc(). For setgrid1d(), arguments correspond to np number of particles x(np) array of particle positions to deposit on grid nx upper grid index of deposition x-grid grid(0:nx) array of deposition grid particle counts xmin min x-value of deposition grid corresponding to grid(0) xmax max x-value of deposition grid corresponding to grid(nx) Note that the x-grid values of the deposition grid are not
input because the grid is assumed to be uniformly spaced from x=xmin [corresponding to count grid(0)] to x=xmax [corresponding to count grid(nx)]. Linearly interpolated counts in grid are passed to the python interpreter via the argument list (linked to a
subroutine call complied code). grid() is not zeroed when the routine is called so statistics can be accumulated over multiple passes. This also means the user must use caution to initialize (zero) the grid before calling, when appropriate. There is also a 1d nearest grid point version of setgrid1d(): `setgrid1dngp(...) ` `setgrid1dw(...)` `setgrid2dw(...)` The argument list for setgrid1dw() is: `setgrid1dw(np:integer,x(np):real,w(np):real,` w(np) array of particle weights which are deposited on the x-grid and returned in grid():nx) instead of counts of x(np). The deposition is based on the locations of x(np) on the x-grid. Of course, quantities other than the particle weights can be deposited. Special versions of setgrid2d() and setgrid2dw() also exist: `setgrid2dcylindrical(...) ` `setgrid2dcylindricalw(...) ` The arguments can be found with doc() and are analogous to those in other setgrid() routines. However, in this case, depositions are modified to be appropriate for r-z cylindrical geometry to account for radial Jacobian factors. Depositing Particle Quantities on a Grid Based on Particle Positions Routines to deposit (bin) data associated with particles onto a node centered grid based on the particle coordinate location on the coordinate grid include: `deposgrid1d(...) ` `deposgrid2d(...)` `deposgrid3d(...) ` for 1d, 2d, and 3d cases using linear (linear, area, and volume in
1d, 2d, and 3d) interpolation. Arguments of the routines are not shown.
For getgrid1d(), they are: `deposgrid1d(itask:integer,np:integer,x(np):real,z(np):real,` and
arguments for deposgrid2d() and deposgrid3d() are analogously extended to
higher dimensions for uniform 2d and 3d grids and can be found using
doc(). For deposgrid1d(), arguments correspond to itask integer control flag 0: grid is set to zero before accumulation and grid divided by gridcount nonzero: grid is not reset np number of particles x(np) array of particle positions z(np) array of particle quantities to deposit based on x(np) locations on x-grid nx upper grid index of deposition x-grid grid(0:nx) array of z deposition values on x-grid gridcount(0:nx) array of x particle deposition counts on x-grid xmin min x-value of deposition x-grid xmax max x-value of deposition x-grid If itask is passed as zero, grid values returned will be average values. itask passed as nonzero allows the routine to be used in multiple passes to accumulate statistics. Note that the x-grid values of the deposition grid are not
input because the grid is assumed to be uniformly spaced from x=xmin
[corresponding to deposition value grid(0)] to x=xmax [corresponding to deposition value
grid(nx)]. Linearly interpolated counts in grid are passed to the python
interpreter via the argument list (linked to a
subroutine call complied code). Note that the routines setgrid1dw() and deposgrid1d() provide similar functionality with the addition of the itask argument in deposgrid1d() making it more flexible. `deposgrid1dngp(...)` `deposgrid2dngp(...)` Use of these are analogous to the corresponding linear weighting versions. Also, versions of deposgrid1d() and deposgrid2d() including individual particle weights in the z deposition are defined: `deposgrid1dw(...) ` `deposgrid2dw(...)` Arguments of deposgrid1dw() are the same as for deposgrid1d() with the addition of w(np) array of particle weights deposgrid1dw() essentially deposits z*w rather than z. Special Purpose RoutinesA common utility need is to deposit data from one grid to another. Warp includes a routine for this purpose based on linear (volume) interpolation: `gridtogrid3d(nxin:integer,nyin:integer,nzin:integer,` ` gridin(0:nxin,0:nyin,0:nzin):real,`
` gridout(0:nxout,0:nyout,0:nzout):real)` Arguments correspond to: nxin input number x-nodes xminin input min x-value of mesh xmaxin input max x-value of mesh gridin(0:nxin,0:nyin,0:nzin) input 3d grid data nxout output number of x-nodes xminout output min x-value of mesh xmaxout output max x-value of mesh gridout(0:nxout,0:nyout,0:nzout) output 3d grid data Here we have suppressed argument definitions in y and z that have obvious generalization from x. Note this routine can be used for 3d and 1d arrays if the corresponding n values are set to zero. |