Mesh refinement

The mesh used in Warp can be refined when using a multigrid field solver.

Setting up the mesh refinement is (hopefully) straightforward. You first need to register a base field solver compatible with mesh refinement so that Warp knows to call it each time step.

solver = MRBlock3D()

registersolver(solver)

When using 2D axi-symmetric (r-z) or transverse planar (x-y), use MRBlock2D for the solver. Typically, the variables w3d.nx, ny, nz, and w3d.xmmin etc of the main mesh are set before registering the solver and solver will use those values. Mesh refinement "patches" can be added. For example,

child1 = solver.addchild(mins=[xmin1,ymin1,zmin1],

maxs=[xmax1,ymax1,zmax1],refinement=[2,2,2])

where the mins and maxs define the extent of the refined "child" patch in the lab frame (in units of meters) doubling the base resolution in each direction. A next level of child patches can be added to child1 the same way.

child2 = child1.addchild(mins=[xmin2,ymin2,zmin2],

maxs=[xmax2,ymax2,zmax2],refinement=[2,2,2])

The refinement=[a,b,c] means that within the box defined by mins and maxs the mesh gets refined by the factors a,b,c along the x,y,z directions. So if the mins and maxs include [4,5,120] grid points in each dimension in the base grid, a refinement of [2,2,2] will end up with approximately [8,10,240] grid points for that area. Note that this is not exact, since there might be some guard mesh points added to reduce errors at the patch boundary. So the real patch grids could be larger.

One can later access the calculated field on a child patch by using the getselfe method.

child1.getselfe()

This will return an array of the dimension [3,Nx,Ny,Nz] with the 3 standing for the Ex,Ey,Ez components.

The patch structure generated can be visualized. The following will plot a diagram of the grid, showing boxes for each refinement patch at the plane iy.

solver.drawboxzx(iy)