Python interface
The Python interface provides low and high level access to much of the data in WarpX. With the low level access, a user has direct access to the underlying memory contained in the MultiFabs and in the particle arrays. The high level provides a more user friendly interface.
High level interface
There are two python modules that provide convenient access to the fields and the particles.
Fields
The fields
module provides wrapper around most of the MultiFabs that are defined in the WarpX class.
For a list of all of the available wrappers, see the file Python/pywarpx/fields.py
.
For each MultiFab, there is a function that will return a wrapper around the data.
For instance, the function ExWrapper
returns a wrapper around the x
component of the MultiFab vector Efield_aux
.
from pywarpx import fields
Ex = fields.ExWrapper()
By default, this wraps the MultiFab for level 0. The level
argument can be specified for other levels.
By default, the wrapper only includes the valid cells. To include the ghost cells, set the argument include_ghosts=True
.
The wrapper provides access to the data via global indexing.
Using standard array indexing (with exceptions) with square brackets, the data can be accessed using indices that are relative to the full domain (across the MultiFab and across processors).
With multiple processors, the result is broadcast to all processors.
This example will return the Bz
field at all points along x
at the specified y
and z
indices.
from pywarpx import fields
Bz = fields.BzWrapper()
Bz_along_x = Bz[:,5,6]
The same global indexing can be done to set values. This example will set the values over a range in y
and z
at the
specified x
. The data will be scattered appropriately to the underlying FABs.
from pywarpx import fields
Jy = fields.JyFPWrapper()
Jy[5,6:20,8:30] = 7.
The code does error checking to ensure that the specified indices are within the bounds of the global domain.
Note that negative indices are handled differently than with numpy arrays because of the possibility of having ghost cells.
With ghost cells, the lower ghost cells are accessed using negative indices (since 0
is the index of the lower bound of the
valid cells). Without ghost cells, a negative index will always raise an out of bounds error since there are no ghost cells.
Under the covers, the wrapper object has a list of numpy arrays that have pointers to the underlying data, one array for each FAB. When data is being fetched, it loops over that list to gather the data. The result is then gathered among all processors. Note that the result is not writeable, in the sense that changing it won’t change the underlying data since it is a copy. When the data is set, using the global indexing, a similar process is done where the processors loop over their FABs and set the data at the appropriate indices.
The wrappers are always up to date since whenever an access is done (either a get or a set), the list of numpy arrays for the FABs is regenerated. In this case, efficiency is sacrificed for consistency.
If it is needed, the list of numpy arrays associated with the FABs can be obtained using the wrapper method _getfields
.
Additionally, there are the methods _getlovects
and _gethivects
that get the list of the bounds of each of the arrays.
Particles
This is still in development.