class VaspToComputedEntryDroneTest(unittest.TestCase): def setUp(self): self.test_dir = os.path.join(os.path.dirname(__file__), "..", "..", "..", "..", 'test_files') self.drone = VaspToComputedEntryDrone(data=["efermi"]) self.structure_drone = VaspToComputedEntryDrone(True) def test_get_valid_paths(self): for path in os.walk(self.test_dir): if path[0] == self.test_dir: self.assertTrue(len(self.drone.get_valid_paths(path)) > 0) def test_assimilate(self): entry = self.drone.assimilate(self.test_dir) for p in ["hubbards", "is_hubbard", "potcar_symbols", "run_type"]: self.assertIn(p, entry.parameters) self.assertAlmostEqual(entry.data["efermi"], 1.8301027) self.assertEqual(entry.composition.reduced_formula, "LiFe4(PO4)4") self.assertAlmostEqual(entry.energy, -269.38319884) entry = self.structure_drone.assimilate(self.test_dir) self.assertEqual(entry.composition.reduced_formula, "LiFe4(PO4)4") self.assertAlmostEqual(entry.energy, -269.38319884) self.assertIsInstance(entry, ComputedStructureEntry) self.assertIsNotNone(entry.structure) compat = MITCompatibility() self.assertIsNone(compat.process_entry(entry)) def test_to_from_dict(self): d = self.structure_drone.to_dict drone = VaspToComputedEntryDrone.from_dict(d) self.assertEqual(type(drone), VaspToComputedEntryDrone)
class VaspToComputedEntryDroneTest(unittest.TestCase): def setUp(self): self.test_dir = os.path.join(os.path.dirname(__file__), "..", "..", "..", "..", 'test_files') self.drone = VaspToComputedEntryDrone(data=["efermi"]) self.structure_drone = VaspToComputedEntryDrone(True) def test_get_valid_paths(self): for path in os.walk(self.test_dir): if path[0] == self.test_dir: self.assertTrue(len(self.drone.get_valid_paths(path)) > 0) def test_assimilate(self): entry = self.drone.assimilate(self.test_dir) for p in ["hubbards", "is_hubbard", "potcar_symbols", "run_type"]: self.assertIn(p, entry.parameters) self.assertAlmostEqual(entry.data["efermi"], 1.8301027) self.assertEqual(entry.composition.reduced_formula, "LiFe4(PO4)4") self.assertAlmostEqual(entry.energy, -269.38319884) entry = self.structure_drone.assimilate(self.test_dir) self.assertEqual(entry.composition.reduced_formula, "LiFe4(PO4)4") self.assertAlmostEqual(entry.energy, -269.38319884) self.assertIsInstance(entry, ComputedStructureEntry) self.assertIsNotNone(entry.structure) self.assertEqual(len(entry.parameters["history"]), 2) compat = MITCompatibility() self.assertIsNone(compat.process_entry(entry)) def test_to_from_dict(self): d = self.structure_drone.to_dict drone = VaspToComputedEntryDrone.from_dict(d) self.assertEqual(type(drone), VaspToComputedEntryDrone)
class VaspToComputedEntryDroneTest(unittest.TestCase): def setUp(self): self.test_dir = os.path.join(os.path.dirname(__file__), "..", "..", "..", "..", 'test_files') self.drone = VaspToComputedEntryDrone(data=["efermi"]) self.structure_drone = VaspToComputedEntryDrone(True) def test_get_valid_paths(self): for path in os.walk(self.test_dir): if path[0] == self.test_dir: self.assertTrue(len(self.drone.get_valid_paths(path)) > 0) def test_assimilate(self): entry = self.drone.assimilate(self.test_dir) for p in ["hubbards", "is_hubbard", "potcar_spec", "run_type"]: self.assertIn(p, entry.parameters) self.assertAlmostEqual(entry.data["efermi"], -6.62148548) self.assertEqual(entry.composition.reduced_formula, "Xe") self.assertAlmostEqual(entry.energy, 0.5559329) entry = self.structure_drone.assimilate(self.test_dir) self.assertEqual(entry.composition.reduced_formula, "Xe") self.assertAlmostEqual(entry.energy, 0.5559329) self.assertIsInstance(entry, ComputedStructureEntry) self.assertIsNotNone(entry.structure) self.assertEqual(len(entry.parameters["history"]), 2) def test_to_from_dict(self): d = self.structure_drone.as_dict() drone = VaspToComputedEntryDrone.from_dict(d) self.assertEqual(type(drone), VaspToComputedEntryDrone)
class VaspToComputedEntryDroneTest(unittest.TestCase): def setUp(self): self.test_dir = os.path.join(os.path.dirname(__file__), "..", "..", "..", "..", 'test_files') self.drone = VaspToComputedEntryDrone(data=["efermi"]) self.structure_drone = VaspToComputedEntryDrone(True) def test_get_valid_paths(self): for path in os.walk(self.test_dir): if path[0] == self.test_dir: self.assertTrue(len(self.drone.get_valid_paths(path)) > 0) def test_assimilate(self): with warnings.catch_warnings(): warnings.simplefilter("ignore") entry = self.drone.assimilate(self.test_dir) for p in ["hubbards", "is_hubbard", "potcar_spec", "run_type"]: self.assertIn(p, entry.parameters) self.assertAlmostEqual(entry.data["efermi"], -6.62148548) self.assertEqual(entry.composition.reduced_formula, "Xe") self.assertAlmostEqual(entry.energy, 0.5559329) entry = self.structure_drone.assimilate(self.test_dir) self.assertEqual(entry.composition.reduced_formula, "Xe") self.assertAlmostEqual(entry.energy, 0.5559329) self.assertIsInstance(entry, ComputedStructureEntry) self.assertIsNotNone(entry.structure) # self.assertEqual(len(entry.parameters["history"]), 2) def test_to_from_dict(self): d = self.structure_drone.as_dict() drone = VaspToComputedEntryDrone.from_dict(d) self.assertEqual(type(drone), VaspToComputedEntryDrone)
class VaspToComputedEntryDroneTest(unittest.TestCase): def setUp(self): self.drone = VaspToComputedEntryDrone(data=["efermi"]) self.structure_drone = VaspToComputedEntryDrone(True) def test_get_valid_paths(self): for path in os.walk(PymatgenTest.TEST_FILES_DIR): if path[0] == PymatgenTest.TEST_FILES_DIR: self.assertTrue(len(self.drone.get_valid_paths(path)) > 0) def test_assimilate(self): with warnings.catch_warnings(): warnings.simplefilter("ignore") entry = self.drone.assimilate(PymatgenTest.TEST_FILES_DIR) for p in ["hubbards", "is_hubbard", "potcar_spec", "run_type"]: self.assertIn(p, entry.parameters) self.assertAlmostEqual(entry.data["efermi"], -6.62148548) self.assertEqual(entry.composition.reduced_formula, "Xe") self.assertAlmostEqual(entry.energy, 0.5559329) entry = self.structure_drone.assimilate(PymatgenTest.TEST_FILES_DIR) self.assertEqual(entry.composition.reduced_formula, "Xe") self.assertAlmostEqual(entry.energy, 0.5559329) self.assertIsInstance(entry, ComputedStructureEntry) self.assertIsNotNone(entry.structure) # self.assertEqual(len(entry.parameters["history"]), 2) def tearDown(self): warnings.simplefilter("default") def test_to_from_dict(self): d = self.structure_drone.as_dict() drone = VaspToComputedEntryDrone.from_dict(d) self.assertEqual(type(drone), VaspToComputedEntryDrone)
def __init__(self, inc_structure=False, inc_incar_n_kpoints=False, parameters=None, data=None): VaspToComputedEntryDrone.__init__(self, inc_structure=inc_structure, parameters=parameters, data=data) self._inc_structure = inc_structure self._inc_incar_n_kpoints = inc_incar_n_kpoints self._parameters = parameters self._data = data
def __init__(self, inc_structure=False, inc_incar_n_kpoints=False, parameters=None, data=None): VaspToComputedEntryDrone.__init__(self, inc_structure=inc_structure, parameters=parameters, data=data) self._inc_structure = inc_structure self._inc_incar_n_kpoints = inc_incar_n_kpoints self._parameters = parameters self._data = data
def create_entry(cdir): """create_entry Creates a ComputedStructure entry from a local calculation. :param cdir: Directory containing VASP calculation. :return: A ComputedStructureEntry object. """ drone = VaspToComputedEntryDrone(inc_structure=True) e = drone.assimilate(cdir) if e is None: print("Missing local calculation for", cdir) sys.exit(0) else: e.entry_id = cdir.rsplit("/", 3)[-2] return e
def test_get_data(self): with warnings.catch_warnings(): warnings.simplefilter("ignore") drone = VaspToComputedEntryDrone() self.queen = BorgQueen(drone, test_dir, 1) data = self.queen.get_data() self.assertEqual(len(data), 7)
def test_load_data(self): with warnings.catch_warnings(): warnings.simplefilter("ignore") drone = VaspToComputedEntryDrone() queen = BorgQueen(drone) queen.load_data(os.path.join(test_dir, "assimilated.json")) self.assertEqual(len(queen.get_data()), 1)
def get_energies(rootdir, reanalyze, verbose, pretty, detailed, sort): if verbose: FORMAT = "%(relativeCreated)d msecs : %(message)s" logging.basicConfig(level=logging.INFO, format=FORMAT) if not detailed: drone = SimpleVaspToComputedEntryDrone(inc_structure=True) else: drone = VaspToComputedEntryDrone( inc_structure=True, data=["filename", "initial_structure"]) ncpus = multiprocessing.cpu_count() logging.info("Detected {} cpus".format(ncpus)) queen = BorgQueen(drone, number_of_drones=ncpus) if os.path.exists(save_file) and not reanalyze: msg = "Using previously assimilated data from {}.".format(save_file) \ + " Use -f to force re-analysis." queen.load_data(save_file) else: if ncpus > 1: queen.parallel_assimilate(rootdir) else: queen.serial_assimilate(rootdir) msg = "Analysis results saved to {} for faster ".format(save_file) + \ "subsequent loading." queen.save_data(save_file) entries = queen.get_data() if sort == "energy_per_atom": entries = sorted(entries, key=lambda x: x.energy_per_atom) elif sort == "filename": entries = sorted(entries, key=lambda x: x.data["filename"]) all_data = [] for e in entries: if not detailed: delta_vol = "{:.2f}".format(e.data["delta_volume"] * 100) else: delta_vol = e.structure.volume / \ e.data["initial_structure"].volume - 1 delta_vol = "{:.2f}".format(delta_vol * 100) all_data.append( (e.data["filename"].replace("./", ""), re.sub("\s+", "", e.composition.formula), "{:.5f}".format(e.energy), "{:.5f}".format(e.energy_per_atom), delta_vol)) if len(all_data) > 0: headers = ("Directory", "Formula", "Energy", "E/Atom", "% vol chg") if pretty: from prettytable import PrettyTable t = PrettyTable(headers) t.set_field_align("Directory", "l") map(t.add_row, all_data) print t else: print str_aligned(all_data, headers) print msg else: print "No valid vasp run found."
def get_energies(rootdir, reanalyze, verbose, detailed, sort, fmt): """ Doc string. """ if verbose: logformat = "%(relativeCreated)d msecs : %(message)s" logging.basicConfig(level=logging.INFO, format=logformat) if not detailed: drone = SimpleVaspToComputedEntryDrone(inc_structure=True) else: drone = VaspToComputedEntryDrone( inc_structure=True, data=["filename", "initial_structure"]) ncpus = multiprocessing.cpu_count() logging.info("Detected {} cpus".format(ncpus)) queen = BorgQueen(drone, number_of_drones=ncpus) if os.path.exists(SAVE_FILE) and not reanalyze: msg = "Using previously assimilated data from {}.".format(SAVE_FILE) \ + " Use -r to force re-analysis." queen.load_data(SAVE_FILE) else: if ncpus > 1: queen.parallel_assimilate(rootdir) else: queen.serial_assimilate(rootdir) msg = "Analysis results saved to {} for faster ".format(SAVE_FILE) + \ "subsequent loading." queen.save_data(SAVE_FILE) entries = queen.get_data() if sort == "energy_per_atom": entries = sorted(entries, key=lambda x: x.energy_per_atom) elif sort == "filename": entries = sorted(entries, key=lambda x: x.data["filename"]) all_data = [] for e in entries: if not detailed: delta_vol = "{:.2f}".format(e.data["delta_volume"] * 100) else: delta_vol = e.structure.volume / \ e.data["initial_structure"].volume - 1 delta_vol = "{:.2f}".format(delta_vol * 100) all_data.append( (e.data["filename"].replace("./", ""), re.sub(r"\s+", "", e.composition.formula), "{:.5f}".format(e.energy), "{:.5f}".format(e.energy_per_atom), delta_vol)) if len(all_data) > 0: headers = ("Directory", "Formula", "Energy", "E/Atom", "% vol chg") print(tabulate(all_data, headers=headers, tablefmt=fmt)) print("") print(msg) else: print("No valid vasp run found.") os.unlink(SAVE_FILE)
def _extract_MP_data(self, MP_data_filename): drone = VaspToComputedEntryDrone() queen = BorgQueen(drone, "dummy", 1) queen.load_data(MP_data_filename) computed_entries = queen.get_data() del drone del queen return computed_entries
def getEhull(new=''): drone = VaspToComputedEntryDrone() queen = BorgQueen(drone, './', 4) entriesorig = queen.get_data() queen.load_data( os.path.join(os.path.dirname(__file__), '../ML/data/missingels.json')) entriesextra = queen.get_data() if new != '': compat = MaterialsProjectCompatibility(check_potcar=False) entriesorig = compat.process_entries(entriesorig) for entry in entriesorig: name = entry.name line = re.findall('[A-Z][^A-Z]*', name.replace('(', '').replace(')', '')) searchset = set(re.sub('\d', ' ', ' '.join(line)).split()) entries = filter( lambda e: set( re.sub('\d', ' ', str(e.composition).replace(' ', '')).split()) == searchset, entriesorig) entriesextra = filter( lambda e: set( re.sub('\d', ' ', str(e.composition).replace(' ', '')).split()) & searchset, entriesextra) a = MPRester("s2vUo6mzETOHLdbu") all_entries = a.get_entries_in_chemsys( set(searchset)) + list(entries) + list(entriesextra) pd = PhaseDiagram(all_entries) #,None for e in pd.stable_entries: if e.entry_id == None: reaction = pd.get_equilibrium_reaction_energy(e) return str(reaction) + ' None' for e in pd.unstable_entries: decomp, e_above_hull = pd.get_decomp_and_e_above_hull(e) pretty_decomp = [("{}:{}".format(k.composition.reduced_formula, k.entry_id), round(v, 2)) for k, v in decomp.items()] if e.entry_id == None: return str(e_above_hull) + ' ' + str(pretty_decomp)
def calculate_phase_stability(args): #This initializes the REST adaptor. a = MPRester(args.api_key) drone = VaspToComputedEntryDrone() entry = drone.assimilate(args.directory) compat = MaterialsProjectCompatibility() entry = compat.process_entry(entry) if not entry: print "Calculation parameters are not consistent with Materials " + \ "Project parameters." sys.exit() syms = [el.symbol for el in entry.composition.elements] #This gets all entries belonging to the relevant system. entries = a.get_entries_in_chemsys(syms) entries.append(entry) #Process entries with Materials Project compatibility. entries = compat.process_entries(entries) print [e.composition.reduced_formula for e in entries]
def main(): """ Main function. """ # Read the calculation results into a ComputedEntry. entl = VaspToComputedEntryDrone().assimilate(sys.argv[1]) # Check if our local calculation is compatible with MP. if MaterialsProjectCompatibility().process_entry(entl) is None: print("Calculation not compatible with MP.") sys.exit(0) # Get other entries sharing a chemical system with the results. chemsys = [ele for ele in entl.composition.as_dict()] with MPRester() as mpr: chemsys_entries = mpr.get_entries_in_chemsys(chemsys) # Append our local calculation to the list of entries. chemsys_entries.append(entl) # Process the entries. p_e = MaterialsProjectCompatibility().process_entries(chemsys_entries) # Build a phase diagram and an analyzer for it. p_d = PhaseDiagram(p_e) pda = PDAnalyzer(p_d) # Scan stable entries for our calculation. for ent in p_d.stable_entries: if ent.entry_id is None: print(str(ent.composition.reduced_formula) + " 0.0") sys.exit(0) # Scan unstable entries for our calculation and print decomposition. for ent in p_d.unstable_entries: if ent.entry_id is None: dco, ehull = pda.get_decomp_and_e_above_hull(ent) pretty_dc = [("{}:{}".format(k.composition.reduced_formula, k.entry_id), round(v, 2)) for k, v in dco.items()] print( str(ent.composition.reduced_formula) + " %.3f" % ehull + " " + str(pretty_dc))
def setUp(self): self.test_dir = os.path.join(os.path.dirname(__file__), "..", "..", "..", "..", 'test_files') self.drone = VaspToComputedEntryDrone(data=["efermi"]) self.structure_drone = VaspToComputedEntryDrone(True)
def test_get_data(self): drone = VaspToComputedEntryDrone() self.queen = BorgQueen(drone, test_dir, 1) data = self.queen.get_data() self.assertEqual(len(data), 12)
def setUp(self): self.drone = VaspToComputedEntryDrone(data=["efermi"]) self.structure_drone = VaspToComputedEntryDrone(True)
def test_to_from_dict(self): d = self.structure_drone.as_dict() drone = VaspToComputedEntryDrone.from_dict(d) self.assertEqual(type(drone), VaspToComputedEntryDrone)
def get_phase_diagram_data(self): """ Returns grand potential phase diagram data to external plot Assumes openelement specific element equals None :return: Data to external plot """ open_elements_specific = None open_element_all = Element(self.open_element) mpr = MPRester(settings.apiKey) drone = VaspToComputedEntryDrone() queen = BorgQueen(drone, rootpath=".") entries = queen.get_data() # Get data to make phase diagram mp_entries = mpr.get_entries_in_chemsys(self.system, compatible_only=True) entries.extend(mp_entries) compat = MaterialsProjectCompatibility() entries = compat.process_entries(entries) #explanation_output = open("explain.txt",'w') #entries_output = open("entries.txt", 'w') compat.explain(entries[0]) #print(entries, file=entries_output) if open_elements_specific: gcpd = GrandPotentialPhaseDiagram(entries, open_elements_specific) self.plot_phase_diagram(gcpd, False) self.analyze_phase_diagram(gcpd) if open_element_all: pd = PhaseDiagram(entries) chempots = pd.get_transition_chempots(open_element_all) # print(chempots) #all_gcpds = list() toplot = [] # dic = {} for idx in range(len(chempots)): if idx == len(chempots) - 1: avgchempot = chempots[idx] - 0.1 else: avgchempot = 0.5 * (chempots[idx] + chempots[idx + 1]) gcpd = GrandPotentialPhaseDiagram( entries, {open_element_all: avgchempot}, pd.elements) # min_chempot = None if idx == len( # chempots) - 1 else chempots[idx + 1] # max_chempot = chempots[idx] #gcpd = GrandPotentialPhaseDiagram(entries, {open_element_all: max_chempot}, pd.elements) toplot.append(self.get_grand_potential_phase_diagram(gcpd)) # toplot.append(max_chempot) #self.plot_phase_diagram(gcpd, False) #print({open_element_all: max_chempot}) all_phase_diagrams = toplot # print(all_phase_diagrams) number_of_phase_diagrams = len(all_phase_diagrams) #pd3 = PhaseDiagram(entries) chempot_list = pd.get_transition_chempots(open_element_all) pd_index = 0 chempots_range_of_each_phase = {} for particular_phase_diagram in all_phase_diagrams: chempot = chempot_list[pd_index] if pd_index is not number_of_phase_diagrams - 1: next_chempot = chempot_list[pd_index + 1] else: next_chempot = chempot_list[pd_index] - 2.0 chempot_range = [chempot, next_chempot] phases_list = particular_phase_diagram[0] for phase in phases_list: if phase in chempots_range_of_each_phase.keys(): chempots_range_of_each_phase[phase][1] = next_chempot.copy( ) else: chempots_range_of_each_phase[phase] = chempot_range.copy() pd_index = pd_index + 1 return chempots_range_of_each_phase
def setUp(self): self.drone = VaspToComputedEntryDrone(data=["efermi"]) self.structure_drone = VaspToComputedEntryDrone(True)
def collect_single_folder(job_folder, drone=None, vasprun_parsing_lvl=1): """ Reading and parsing of VASP files in the job_folder folder vasprun_parsing_lvl > 0.5 : parse vasprun, else only parse vasp inputs returns a Rundict instance """ # status : # 0 : not a job folder # 1 : pre-run # 2 : failed run # 3 : converged run # if no drone give, minimal parsing if drone is None: drone = drone = VaspToComputedEntryDrone(inc_structure=True, parameters=["incar"], data=['efermi', "converged"]) status = 0 with warnings.catch_warnings(): # warnings.filterwarnings('once') if PARAM['verbose'] == 0: warnings.simplefilter("ignore") if vasprun_parsing_lvl > 0.5: if if_file_exist_gz(job_folder, "vasprun.xml"): # try unzip the vasprun c_e = drone.assimilate(job_folder) if c_e is not None: print(c_e.parameters['incar']) status = 3 if c_e.data['converged'] else 2 if status <= 0: # try unzip the whole dir c_e = SimpleVaspToComputedEntryDrone( inc_structure=True).assimilate(job_folder) if c_e is not None: incar = Incar.from_file( '{}/INCAR'.format(job_folder)).as_dict() c_e.parameters.update({"incar": incar}) try: status = 2 if c_e.energy < 10000000 else 1 except TypeError as ex: print("exception caught", ex) # c_e.energy = 10000000 status = 1 # if there is an error, the run didn't converge # default energy of parser when ozscicar not read # to distinguish "pre-runs" from corrupted / suppressed vasprun if status > 0: for k in ['LDAUU', 'LDAUJ', 'LDAUL', "@class", "@module"]: # "MAGMOM" c_e.parameters['incar'].pop(k, None) for file_name in ["param", "data"]: file_path = os.path.join(job_folder, '{}.json'.format(file_name)) try: with open(file_path) as file_object: # load file data into object param = json.load(file_object) print(file_name, param) c_e.parameters['custom'] = param except Exception: # print(ex) continue else: break # print("finished gathering c_e data") # if hasattr(c_e, "run_type"): # print(c_e.run_type) # print(c_e.parameters) # print(type(c_e.parameters["run_type"])) if not isinstance(c_e.parameters["run_type"], str): c_e.parameters["run_type"] = None # print("run type changed to None") # print(c_e) rundict = Rundict(c_e, status, job_folder) if PARAM["verbose"] > 0: print("sucessfully parsed : \n", rundict) return (rundict)
def test_get_data(self): drone = VaspToComputedEntryDrone() self.queen = BorgQueen(drone, PymatgenTest.TEST_FILES_DIR, 1) data = self.queen.get_data() self.assertEqual(len(data), 12)
def test_load_data(self): drone = VaspToComputedEntryDrone() queen = BorgQueen(drone) queen.load_data(os.path.join(PymatgenTest.TEST_FILES_DIR, "assimilated.json")) self.assertEqual(len(queen.get_data()), 1)
def submit_vasp_directory(self, rootdir, authors, projects=None, references='', remarks=None, master_data=None, master_history=None, created_at=None, ncpus=None): """ Assimilates all vasp run directories beneath a particular directory using BorgQueen to obtain structures, and then submits thhem to the Materials Project as SNL files. VASP related meta data like initial structure and final energies are automatically incorporated. .. note:: As of now, this MP REST feature is open only to a select group of users. Opening up submissions to all users is being planned for the future. Args: rootdir (str): Rootdir to start assimilating VASP runs from. authors: *List* of {"name":'', "email":''} dicts, *list* of Strings as 'John Doe <*****@*****.**>', or a single String with commas separating authors. The same list of authors should apply to all runs. projects ([str]): List of Strings ['Project A', 'Project B']. This applies to all structures. references (str): A String in BibTeX format. Again, this applies to all structures. remarks ([str]): List of Strings ['Remark A', 'Remark B'] master_data (dict): A free form dict. Namespaced at the root level with an underscore, e.g. {"_materialsproject":<custom data>}. This data is added to all structures detected in the directory, in addition to other vasp data on a per structure basis. master_history: A master history to be added to all entries. created_at (datetime): A datetime object ncpus (int): Number of cpus to use in using BorgQueen to assimilate. Defaults to None, which means serial. """ from pymatgen.apps.borg.hive import VaspToComputedEntryDrone from pymatgen.apps.borg.queen import BorgQueen drone = VaspToComputedEntryDrone( inc_structure=True, data=["filename", "initial_structure"]) queen = BorgQueen(drone, number_of_drones=ncpus) queen.parallel_assimilate(rootdir) structures = [] metadata = [] histories = [] for e in queen.get_data(): structures.append(e.structure) m = { "_vasp": { "parameters": e.parameters, "final_energy": e.energy, "final_energy_per_atom": e.energy_per_atom, "initial_structure": e.data["initial_structure"].as_dict() } } if "history" in e.parameters: histories.append(e.parameters["history"]) if master_data is not None: m.update(master_data) metadata.append(m) if master_history is not None: histories = master_history * len(structures) return self.submit_structures(structures, authors, projects=projects, references=references, remarks=remarks, data=metadata, histories=histories, created_at=created_at)
def get_energies(rootdir, reanalyze, verbose, quick, sort, fmt): """ Get energies of all vaspruns in directory (nested). Args: rootdir (str): Root directory. reanalyze (bool): Whether to ignore saved results and reanalyze verbose (bool): Verbose mode or not. quick (bool): Whether to perform a quick analysis (using OSZICAR instead of vasprun.xml sort (bool): Whether to sort the results in ascending order. fmt (str): tablefmt passed to tabulate. """ if verbose: logformat = "%(relativeCreated)d msecs : %(message)s" logging.basicConfig(level=logging.INFO, format=logformat) if quick: drone = SimpleVaspToComputedEntryDrone(inc_structure=True) else: drone = VaspToComputedEntryDrone( inc_structure=True, data=["filename", "initial_structure"]) ncpus = multiprocessing.cpu_count() logging.info("Detected {} cpus".format(ncpus)) queen = BorgQueen(drone, number_of_drones=ncpus) if os.path.exists(SAVE_FILE) and not reanalyze: msg = ("Using previously assimilated data from {}.".format(SAVE_FILE) + " Use -r to force re-analysis.") queen.load_data(SAVE_FILE) else: if ncpus > 1: queen.parallel_assimilate(rootdir) else: queen.serial_assimilate(rootdir) msg = ("Analysis results saved to {} for faster ".format(SAVE_FILE) + "subsequent loading.") queen.save_data(SAVE_FILE) entries = queen.get_data() if sort == "energy_per_atom": entries = sorted(entries, key=lambda x: x.energy_per_atom) elif sort == "filename": entries = sorted(entries, key=lambda x: x.data["filename"]) all_data = [] for e in entries: if quick: delta_vol = "NA" else: delta_vol = e.structure.volume / e.data[ "initial_structure"].volume - 1 delta_vol = "{:.2f}".format(delta_vol * 100) all_data.append(( e.data["filename"].replace("./", ""), re.sub(r"\s+", "", e.composition.formula), "{:.5f}".format(e.energy), "{:.5f}".format(e.energy_per_atom), delta_vol, )) if len(all_data) > 0: headers = ("Directory", "Formula", "Energy", "E/Atom", "% vol chg") print(tabulate(all_data, headers=headers, tablefmt=fmt)) print("") print(msg) else: print("No valid vasp run found.") os.unlink(SAVE_FILE) return 0
def get_phase_diagram_data(self): """ Returns grand potential phase diagram data to external plot Assumes openelement specific element equals None :return: Data to external plot """ open_elements_specific = None open_element_all = Element(self.open_element) mpr = MPRester("key") # import do dados dos arquivos tipo vasp drone = VaspToComputedEntryDrone() queen = BorgQueen(drone, rootpath=".") entries = queen.get_data() # Get data to make phase diagram mp_entries = mpr.get_entries_in_chemsys(self.system, compatible_only=True) entries.extend(mp_entries) compat = MaterialsProjectCompatibility() entries = compat.process_entries(entries) #explanation_output = open("explain.txt",'w') entries_output = open("entries.txt", 'w') compat.explain(entries[0]) print(entries, file=entries_output) #print(entries) if open_elements_specific: gcpd = GrandPotentialPhaseDiagram(entries, open_elements_specific) self.plot_phase_diagram(gcpd, False) self.analyze_phase_diagram(gcpd) if open_element_all: pd = PhaseDiagram(entries) chempots = pd.get_transition_chempots(open_element_all) #print(chempots) #all_gcpds = list() toplot = [] # dic = {} for idx in range(len(chempots)): if idx == len(chempots) - 1: avgchempot = chempots[idx] - 0.1 else: avgchempot = 0.5 * (chempots[idx] + chempots[idx + 1]) gcpd = GrandPotentialPhaseDiagram( entries, {open_element_all: avgchempot}, pd.elements) # toplot.append(self.get_grand_potential_phase_diagram(gcpd)) min_chempot = None if idx == len(chempots) - 1 else chempots[ idx + 1] max_chempot = chempots[idx] #gcpd = GrandPotentialPhaseDiagram(entries, {open_element_all: max_chempot}, pd.elements) toplot.append(self.get_grand_potential_phase_diagram(gcpd)) #toplot.append(max_chempot) #self.plot_phase_diagram(gcpd, False) #print({open_element_all: max_chempot}) # Data to plot phase diagram return toplot
from pymatgen.ext.matproj import MPRester from pymatgen.apps.borg.hive import VaspToComputedEntryDrone from pymatgen.apps.borg.queen import BorgQueen from pymatgen.entries.compatibility import MaterialsProjectCompatibility from pymatgen.analysis.phase_diagram import PhaseDiagram from pymatgen.analysis.phase_diagram import PDPlotter # Assimilate VASP calculations into ComputedEntry object. Let's assume that # the calculations are for a series of new LixFeyOz phases that we want to # know the phase stability. drone = VaspToComputedEntryDrone() queen = BorgQueen(drone, rootpath=".") entries = queen.get_data() # Obtain all existing Li-Fe-O phases using the Materials Project REST API with MPRester("key") as m: mp_entries = m.get_entries_in_chemsys(["Li", "Sn", "S"]) # Combined entry from calculated run with Materials Project entries entries.extend(mp_entries) # Process entries using the MaterialsProjectCompatibility compat = MaterialsProjectCompatibility() entries = compat.process_entries(entries) # Generate and plot Li-Fe-O phase diagram pd = PhaseDiagram(entries) plotter = PDPlotter(pd) plotter.show()
def setUp(self): drone = VaspToComputedEntryDrone() self.queen = BorgQueen(drone, test_dir, 1)
def test_to_from_dict(self): d = self.structure_drone.to_dict drone = VaspToComputedEntryDrone.from_dict(d) self.assertEqual(type(drone), VaspToComputedEntryDrone)
"""determine_working_ion Determines the identity of the working ion from a ComputedEntry object. :param e: A ComputedEntry object. :return: A String representing the working ion. """ wi = None for el in e.composition.as_dict(): if el in wi_ids: wi = el break return wi if __name__ == "__main__": # Build a drone (we do it here to avoid building a new one for every call) d = VaspToComputedEntryDrone(inc_structure=True) # Read in list of directories containing topotactic states of charge. dirlist = sys.argv[1:] entry_list = [read_entry(f, d) for f in dirlist] # Any entry with more than two ions contains the working ion; find it. for entry in entry_list: if len(entry.composition.as_dict()) > 2: working_ion = determine_working_ion(entry) # Can't proceed without a working ion. if working_ion is None: print("Couldn't find a working ion, quitting.") sys.exit(0)
def extract_json_data(): """ Routine tries to read VASP data into pymatgen objects, and then extracts only the relevant data. This is then written to json, allowing the voluminous OUTCAR and vasprun.xml files to be discarded. """ try: o = Outcar('OUTCAR') found_outcar = True except: print('OUTCAR file missing or not readable') found_outcar = False try: vr = Vasprun('vasprun.xml') found_vasprun = True except: print('vasprun.xml file missing or not readable') found_vasprun = False dictionary_data = {} if found_outcar: dictionary_data['OUTCAR'] = o.as_dict() if found_vasprun: try: # try to extract a Computed Entry object, using # pymatgen technology drone = VaspToComputedEntryDrone() queen = BorgQueen(drone, './', 1) entry = queen.get_data()[0] dictionary_data['ComputedEntry'] = entry.as_dict() except: print('ComputedEntry COULD NOT BE EXTRACTED BY PYMATGEN...') """ # Do not extract DOS in run_data.json; this is too memory intensive! try: dictionary_data['DOS'] = vr.complete_dos.as_dict() pymatgen_dos_success = True except: print('DOS COULD NOT BE EXTRACTED BY PYMATGEN...') pymatgen_dos_success = False """ relaxation_data = [] for step in vr.ionic_steps: data_dict = {} for key in ['forces', 'structure', 'stress']: if key in step: data_dict[key] = step[key] data_dict['electronic'] = step['electronic_steps'][-1] relaxation_data.append(data_dict) dictionary_data['relaxation'] = relaxation_data if found_outcar or found_vasprun: pmg_dump(dictionary_data, 'run_data.json') return
def setUp(self): self.test_dir = os.path.join(os.path.dirname(__file__), "..", "..", "..", "..", 'test_files') self.drone = VaspToComputedEntryDrone(data=["efermi"]) self.structure_drone = VaspToComputedEntryDrone(True)
def collect_valid_runs(mainFolder, checkDiff=False, vasprun_parsing_lvl=1, file_system_choice=None): """ input : mainFolder ,{ param : value} output : [ {vaspRun : v , folder : F } ] COLLECT VALID VASPRUNS ================================================= Walk trhough the folders to find valid vaspruns Convergence is tested by pymatgen built in fct If the converged structure if different from all the others in the list, it is added to the vaspRunList[] Create a list of all the subfolder of the run """ global PARAM sub_dir_list, file_system_choice = get_job_list( mainFolder, file_system_choice=file_system_choice) if vasprun_parsing_lvl is None: try: parse_choice = input("check vasprun level ?\n" + "\n".join([ "[f]ull vasprun parsing", "[m]inimal vasprun parsing", "[o]szicar parsing (energy & structure only)", "[n]o parsing" ])) if parse_choice[0] in ["f", "F"]: # [f]ull parsing vasprun_parsing_lvl = 1 elif parse_choice[0] in ["m", "M"]: # [m]inimal parsing vasprun_parsing_lvl = 0.7 elif parse_choice[0] in ["o", "O"]: # [m]inimal parsing vasprun_parsing_lvl = 0.4 elif parse_choice[0] in ["n", "N"]: # [n]o parsing vasprun_parsing_lvl = 0 except Exception as ex: print("Exception : {}\n default to full parsing".format(ex)) vasprun_parsing_lvl = 1 # print(str(subDirList)+"\n\n") drone = VaspToComputedEntryDrone( inc_structure=True, parameters=["incar"], data=['efermi', "complete_dos", "tdos", "converged"]) with Pool(processes=cpu_count()) as parallel_runs: tmp_list = parallel_runs.starmap(collect_single_folder, [(run, drone, vasprun_parsing_lvl) for run in sub_dir_list]) parallel_runs.close() parallel_runs.join() tmp_list.sort(key=lambda x: x.job_folder) # for d in tmp_list: # print("{} / {} : {}".format(d.stacking, d.str_id, # d.status_string)) converged_runs = [] if checkDiff: for run in [run for run in tmp_list if run.status > 0]: new_struct = True for existing_run in converged_runs: if run.structure.matches(existing_run.structure): print("Structure : {0} match with previous one : {1}". format( run.parameters['incar'].get('SYSTEM', "no_name"), existing_run.parameters['incar'].get( 'SYSTEM', "no_name"))) new_struct = False if new_struct and run.status > 0: converged_runs.append(run) else: valid_runs = [run for run in tmp_list if run.status > 0] # os.chdir(valid_runs) print("\nnb of valid runs : {0}".format(len(valid_runs))) for run in valid_runs: print(run.name_tag, run.status_string) return (valid_runs)
def test_load_data(self): drone = VaspToComputedEntryDrone() queen = BorgQueen(drone) queen.load_data(os.path.join(test_dir, "assimilated.json")) self.assertEqual(len(queen.get_data()), 1)