Skip to content

Move from Henkelman Bader to PyBader #711

@SWeav02

Description

@SWeav02

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:

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    baderrelates to simmate.apps.bader

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions