As you may have noticed I've been using the ASE package to do some phonon calculations in my free time. One nice feature is the ASE Phonons class, which is very useful programming interface for doing phonon calculations for different calculators and atomic structures. However, one of the limitations is that the Phonons object has no way to write the state of the object, in other words, if you want to recalculate the band structure from the dynamical matrix (in real-space), you would need to write function that saves it. Then in order to use it and plot the band structure, say along another q-point path than you original had done, you would need to reconstruct the Phonons object and all other details. This is cumbersome, so why not make some python pickles, specifically the dill variety.
The Python pickle package is a way implement binary protocols for writing/reading Python object structure (i.e., serializing). The process focuses on the object hierarchy to convert/uncovert it to a byte stream, this is pickling. So why do we have dill pickling, because some class methods and attributes are not easily pickled and thus we can do so with the dill package. What does this mean for the user? We can write the state of our Phonon object/calculation to a pickle/dill file and then use it latter to re-plot the band structure.
Our First 🥒 Batch
To begin we create an aluminum unit cell and then instantiate the Phonons. I'm using the built in EMT calculator for simplicity.
from ase.build import bulk, molecule
from ase.calculators.emt import EMT
from ase.phonons import Phonons
atoms = bulk('Al', 'fcc', a=4.05)
N = 7
ph = Phonons(atoms, EMT(), supercell=(N, N, N), delta=0.05)
ph.run()
ph.read(acoustic=True)
ph.clean()
The band structure is obtained using the get_bandstructure^[a] method which requires the q-point path. An example output is
BandStructure(path=BandPath(path='GXWKGLUWLK,UX', cell=[3x3], special_points={GKLUWX}, kpts=[50x3]), energies=[1x50x3 values], reference=0.0)
Now comes our functions to perform the dill pickling:
import dill as pickle
def pickling_phonons(phonons_obj,filename="phonons.pkl"):
with open(filename, 'wb') as f:
pickle.dump(phonons_obj, f)
return None
def unpickle_phonons(filename="phonons.pkl"):
with open(filename, 'rb') as f:
dill_pickle_phonons = pickle.load(f)
return dill_pickle_phonons
and we can easily perform pickling:
pickling_phonons(ph)
and then unpickle with
ph_pkl = unpickle_phonons()
which nicely gives:
BandStructure(path=BandPath(path='GXWKGLUWLK,UX', cell=[3x3], special_points={GKLUWX}, kpts=[50x3]), energies=[1x50x3 values], reference=0.0)
if we call the get_band_structure method with the same q-point path. So that it, a very straightforward way to save your ASE.Phonons object for later use. This will be particularly helpful for large supercells or calculators that are costly to evaluate again. I've coded this into the my fork of the ASE main branch and have this example included as a test, however, I'm not sure this would make it into the next release as it probably isn't robust enough against edge cases.
Note
One limitation is that pickling, even with dill, will not work for the ASE calculator objects that are tied to external shared lib objects. For example if you use the LAMMPSlib interface you will most likely get a failure since this links the LAMMPS shared C++ library objects and data types (I think this is how it works?).
Let me know if you have any suggestion on better approaches or a more comprehensive way to store the state of ASE.Phonons, but in general I do enjoy making 🥒.
Footnotes
-
The method call and q-point path would be: ph.get_band_structure(atoms.cell.bandpath())), but the point is with the pickled Phonons object you could unpickle it and the provide a different q-point path. ↩
References
[1] Larsen, A. H.; et al., The Atomic Simulation Environment—a Python Library for Working with Atoms. J. Phys.: Condens. Matter 2017, 29 (27), 273002. https://doi.org/10.1088/1361-648X/aa680e.
No comments:
Post a Comment
Please refrain from using ad hominem attacks, profanity, slander, or any similar sentiment in your comments. Let's keep the discussion respectful and constructive.