Errors in get_wf_bulk_modulus


I tried to run the bulk_modulus workflow and ran into big problems. I am not completely sure if I just use this wrong, but I think these are real bugs in the workflow.

First, this is the script I use to get a structure from the MP, create the deformations, and run the workflow:

Created on Thu Jun  4 15:54:46 2020

@author: mwo

import numpy as np
from pymatgen import MPRester, Structure
from fireworks import LaunchPad, Firework, Workflow
from fireworks.core.rocket_launcher import rapidfire
from atomate.vasp.config import VASP_CMD, DB_FILE
from atomate.vasp.workflows.base.bulk_modulus import get_wf_bulk_modulus

def GetLowEnergyStructure(chem_formula, MP_ID=None, PrintInfo=False):
    A function that searches the MaterialsProject Database
    for structures that match the given chemical formula
    and selcts the one with the lowest formation energy
    per atom. If several 
    chem_formula (str): Required input of a chemical formula
                        e.g.: NaCl, Fe2O3, SiO, FeCW
    MP_ID (str):        Optional Input of Materials Project ID
                        of the exact desired structure
                        e.g. 'mp-990448'
    PrintInfo (bool):   Optional variable defaults to "False".
                        if set to "True", will print some
                        information about how many structures
                        have been found and the ID of the selcted
    Returns: pymatgen Structure object and associated MP_ID

    # load structure from MaterialsProjct Website
    with MPRester() as mpr:
        if MP_ID:
            struct = mpr.get_structure_by_material_id(MP_ID)
            return struct, MP_ID
            id_list = mpr.query(criteria={'pretty_formula': chem_formula,
                                        'e_above_hull': 0.0},
            if id_list == []:
                raise NameError('{} has not been found in the MaterialsProject'
                MP_ID = id_list[0]['material_id']
                struct = mpr.get_structure_by_material_id(MP_ID)
                return struct, MP_ID

struct , mp_id = GetLowEnergyStructure('Al')

deforms = []
for i in np.arange(0.9, 1.1, 0.05):

uis = {'ISMEAR': 1}

wf = get_wf_bulk_modulus(struct, deforms, vasp_input_set=None,
                         db_file=DB_FILE, user_kpoints_settings=None,
                         eos='birch_murnaghan', tag=None,#'test_BM',

lpad = LaunchPad.auto_load()


This results in a the follwing errors for each deformation firework:

Traceback (most recent call last):
  File "/home/mwo/FireWorks/atomate_env/lib/python3.7/site-packages/fireworks/core/", line 262, in run
    m_action = t.run_task(my_spec)
  File "/home/mwo/FireWorks/atomate_env/lib/python3.7/site-packages/atomate/vasp/firetasks/", line 70, in run_task
    "calc_loc") else {}
KeyError: 'calc_locs'

This is fixable by setting copy_vasp_outputs=False in the call to get_wf_deformations in line 58 of This defaults to True otherwise and results in the errors above.

However, while this fixes the deformation FWs and they run through without problems, the following FW for the fit to the equation of state still fails:

2020-06-04 17:16:27,031 INFO Task started: {{atomate.vasp.firetasks.parse_outputs.FitEOSToDb}}.
Traceback (most recent call last):
  File "/home/mwo/FireWorks/atomate_env/lib/python3.7/site-packages/fireworks/core/", line 262, in run
    m_action = t.run_task(my_spec)
  File "/home/mwo/FireWorks/atomate_env/lib/python3.7/site-packages/atomate/vasp/firetasks/", line 648, in run_task
TypeError: 'NoneType' object is not subscriptable
2020-06-04 17:16:27,986 INFO Rocket finished

Looking in the code of atomate.vasp.firetasks.parse_outputs.FitEOSToDb, it becomes clear that at line 646: d = mmdb.collection.find_one({"task_label": "{} structure optimization".format(tag)}) is the problem. There is simply no calculation with this task label in the database, since there is no structure optimization run in the workflow. Since I take the structure directly from the MP database, I also do not need one here (at this point I am interested in the change of the bulk modulus and the equilibrium volume with the energy cutoff).

Replacing the line with d = mmdb.collection.find_one({"task_label": {"$regex": "{} bulk_modulus*".format(tag)}}) removes the error and leads to apparently correct fitting of the eos. However, the structure that is put in the summary_dict, IS NOT the input structure, but one of the deformed structures.

All in all, I think that the first fix is OK, while the second one more a hack than a fix. I am not sure how to retrieve the correct input structure without changing much more code, since I do not think it is in the database. Do I just call the workflow incorrectly? Is it mandatory to run an OptimizeFW first?

Should I create an issue on github, or make a pull request with my changes?