-
Notifications
You must be signed in to change notification settings - Fork 11
Description
Describe the desired feature
Rather than using the henkelman group's bader program which requires either docker or local install, it might be useful to switch to pybader.
Additional context
Currently, the bader workflows we have rely on the Henkelman groups fortran implementation. This means users need to use either docker or a local install. The pybader package uses essentially the same implementation as the Henkelman group, but exclusively using python packages (numpy, numba, tqdm, and pandas). This also means that results can be easily read from the resulting python object rather than needing to read results from output files.
I've already implemented pybader in the Grid class I made for BadELF:
simmate/src/simmate/apps/badelf/core/grid.py
Lines 388 to 419 in f330103
| def to_pybader(self): | |
| """ | |
| Returns a Bader object from pybader. | |
| """ | |
| atoms = self.structure.cart_coords | |
| lattice = self.matrix | |
| density = {"charge": self.total} | |
| file_info = {"voxel_offset": np.array([0, 0, 0])} | |
| bader = Bader(density, lattice, atoms, file_info) | |
| return bader | |
| def run_pybader(self, threads: int = 1): | |
| """ | |
| Convenience class for running zero-flux voxel assignment using pybader. | |
| Returns a pybader Bader class object with the assigned voxels | |
| Args: | |
| cores (int): | |
| The number of threads to use when running the Bader algorithm | |
| """ | |
| logging.info("Running Bader") | |
| bader = self.to_pybader() | |
| bader.load_config("speed") | |
| bader.threads = threads | |
| bader.spin_flag = True # loading speed config resets all config vars | |
| bader.volumes_init() | |
| bader.bader_calc() | |
| bader.bader_to_atom_distance() | |
| bader.refine_volumes(bader.atoms_volumes) | |
| bader.threads = 1 | |
| bader.min_surface_distance() | |
| return bader |
The Grid class would also make it very easy to create a python only implementation of the combine_chgars workflow so that we can remove the extra workflow.
The main issues I foresee are that pybader is not longer actively maintained and does not by default use a reference file like the henkelman group's implementation. I think the first of these is likely to be ok unless one of the four required packages changes drastically. The second is relatively easy to manage because the voxel assignments are stored in a pybader object (bader.atom_volumes). This would make it easy to run the algorithm on one Grid object and then sum the voxels in another Grid object.
@jacksund let me know if you have any issues with this. Otherwise I can work on it when I have some free time.
To-do items
As I see it, to implement this we would need to:
- Move the Grid class to a more accessible location (toolkit.base_data_types?)
- Add convenience functions to the Grid class for summing files and running bader
- Adjust existing workflows to use the Grid class
- Remove code related to reading the ACF.dat