F.A.Q.

F.A.Q.

How-to’s #

How to set up absorbing boundary conditions?

Compile the code with the -absorb flag, set the corresponding boundary_* to 0 (non-periodic), and set absorb_* to 1 or 2. If you need a spherical absorption, set one of the absorb_* to 2. Also specify the abs_thick in the input which determines the region across which the absorption takes place.

How to set up reflecting boundary conditions?

There is no encoded reflecting boundary condition in our code as is. However, one can use the userfile to mimic the reflecting wall (see user_reflect.F90). The key is to take advantage of the userCurrentDeposit() (already done in the mentioned userfile) to properly reflect the particles from the wall with corresponding charge conservation.

How to add a particle injector?

Use your userfile for that. Examples of particle (and field) injectors can be found in user_rec.F90 and user_reflect.F90.

How do I post-process the simulation data?

There are several ways. The most straightforward is to simply use h5py module in Python. The output files are very basic hdf5 files, so you should have no trouble opening them and extracting any data necessary (description of the file content is provided in this section. For more advanced post-processing it is recommended to use the graph-et module. For usage examples, please see the following section.

How do I track particles between timesteps?

Each particle has an associated pair of numbers which uniquely identify it between timesteps: ind and proc. The combination of these two numbers is totally unique for every single particle. These variables are being written with the particle output and can be accessed in the same was as any other quantity. The graph-et module uses these pairs of attributes to construct a unique ID for each particle automatically. When using vanilla h5py, you can construct this ID on your own by using, e.g., the Cantor pairing function: id = (ind + proc) * (ind + proc + 1) / 2 + ind (make sure to convert these arrays into int64 as the numbers can be very large).

Common problems #

My simulation produces unphysical results. Is it possible the code has errors in its core?

No.

When trying to restart, the code starts from the zeroth timestep instead of continuing

Carefully read the following section. Especially, pay attention to the warning about the do_restart flag in the input file.

The code just crashes with a segfault

This can be caused by a multitude of reasons. Unfortunately, with max optimizations it is hard to track down what exactly causes the issue (it could be a range error, a nan in one of the variables, or attempt to pass a variable with incorrect type to a subroutine). To know for sure, try to reproduce the issue with the debug flag turned on (-D DEBUG=ON for CMake, and --debug=1 or --debug=2 for GNU Make). Particularly, pay attention to the traceback of the issue which should point to where in the code the error originates, as well as the reason for the error (e.g., “invalid floating point operation” likely means you’re either dividing by zero, or taking a sqrt from a negative number). If none of this works, open an issue on github and attach all of the information you’ve gathered.