def get_entry_MP(entry_s, password=None): """Returns a specific entry from the Materials Project database Parameters: ----------- ent: """ mpr = MPRester(password) entryid_prefix = entry_s[:3] if entryid_prefix == 'mp-': out = mpr.get_entries(entry_s)[0] else: out = mpr.get_entries(entry_s) return out
def do_query(args): m = MPRester() try: criteria = json.loads(args.criteria) except json.decoder.JSONDecodeError: criteria = args.criteria if args.structure: count = 0 for d in m.query(criteria, properties=["structure", "task_id"]): s = d["structure"] formula = re.sub("\s+", "", s.formula) if args.structure == "poscar": fname = "POSCAR.%s_%s" % (d["task_id"], formula) else: fname = "%s-%s.%s" % (d["task_id"], formula, args.structure) s.to(filename=fname) count += 1 print("%d structures written!" % count) elif args.entries: entries = m.get_entries(criteria) dumpfn(entries, args.entries) print("%d entries written to %s!" % (len(entries), args.entries)) else: props = ["e_above_hull", "spacegroup"] props += args.data entries = m.get_entries(criteria, property_data=props) t = [] headers = [ "mp-id", "Formula", "Spacegroup", "E/atom (eV)", "E above hull (eV)" ] + args.data for e in entries: row = [ e.entry_id, e.composition.reduced_formula, e.data["spacegroup"]["symbol"], e.energy_per_atom, e.data["e_above_hull"] ] row += [e.data[s] for s in args.data] t.append(row) t = sorted(t, key=lambda x: x[headers.index("E above hull (eV)")]) print(tabulate(t, headers=headers, tablefmt="pipe", floatfmt=".3f"))
def do_query(args): m = MPRester() try: criteria = json.loads(args.criteria) except json.decoder.JSONDecodeError: criteria = args.criteria if args.structure: count = 0 for d in m.query(criteria, properties=["structure", "task_id"]): s = d["structure"] formula = re.sub("\s+", "", s.formula) if args.structure == "poscar": fname = "POSCAR.%s_%s" % (d["task_id"], formula) else: fname = "%s-%s.%s" % (d["task_id"], formula, args.structure) s.to(filename=fname) count += 1 print("%d structures written!" % count) elif args.entries: entries = m.get_entries(criteria) dumpfn(entries, args.entries) print("%d entries written to %s!" % (len(entries), args.entries)) else: props = ["e_above_hull", "spacegroup"] props += args.data entries = m.get_entries(criteria, property_data=props) t = [] headers = ["mp-id", "Formula", "Spacegroup", "E/atom (eV)", "E above hull (eV)"] + args.data for e in entries: row = [e.entry_id, e.composition.reduced_formula, e.data["spacegroup"]["symbol"], e.energy_per_atom, e.data["e_above_hull"]] row += [e.data[s] for s in args.data] t.append(row) t = sorted(t, key=lambda x: x[headers.index("E above hull (eV)")]) print(tabulate(t, headers=headers, tablefmt="pipe", floatfmt=".3f"))
class MaterialsEhullBuilder(AbstractBuilder): def __init__(self, materials_write, mapi_key=None, update_all=False): """ Starting with an existing materials collection, adds stability information and The Materials Project ID. Args: materials_write: mongodb collection for materials (write access needed) mapi_key: (str) Materials API key (if MAPI_KEY env. var. not set) update_all: (bool) - if true, updates all docs. If false, only updates docs w/o a stability key """ self._materials = materials_write self.mpr = MPRester(api_key=mapi_key) self.update_all = update_all def run(self): logger.info("MaterialsEhullBuilder starting...") self._build_indexes() q = {"thermo.energy": {"$exists": True}} if not self.update_all: q["stability"] = {"$exists": False} mats = [ m for m in self._materials.find( q, { "calc_settings": 1, "structure": 1, "thermo.energy": 1, "material_id": 1 }) ] pbar = tqdm(mats) for m in pbar: pbar.set_description("Processing materials_id: {}".format( m['material_id'])) try: params = {} for x in ["is_hubbard", "hubbards", "potcar_spec"]: params[x] = m["calc_settings"][x] structure = Structure.from_dict(m["structure"]) energy = m["thermo"]["energy"] my_entry = ComputedEntry(structure.composition, energy, parameters=params) # TODO: @computron This only calculates Ehull with respect to Materials Project. # It should also account for the current database's results. -computron self._materials.update_one({"material_id": m["material_id"]}, { "$set": { "stability": self.mpr.get_stability([my_entry])[0] } }) # TODO: @computron: also add additional properties like inverse hull energy? # TODO: @computron it's better to use PD tool or reaction energy calculator # Otherwise the compatibility schemes might have issues...one strategy might be # use MP only to retrieve entries but compute the PD locally -computron for el, elx in my_entry.composition.items(): entries = self.mpr.get_entries(el.symbol, compatible_only=True) min_e = min( entries, key=lambda x: x.energy_per_atom).energy_per_atom energy -= elx * min_e self._materials.update_one({"material_id": m["material_id"]}, { "$set": { "thermo.formation_energy_per_atom": energy / structure.num_sites } }) mpids = self.mpr.find_structure(structure) self._materials.update_one({"material_id": m["material_id"]}, {"$set": { "mpids": mpids }}) except: import traceback logger.exception("<---") logger.exception( "There was an error processing material_id: {}".format(m)) logger.exception(traceback.format_exc()) logger.exception("--->") logger.info("MaterialsEhullBuilder finished processing.") def reset(self): logger.info("Resetting MaterialsEhullBuilder") self._materials.update_many({}, {"$unset": {"stability": 1}}) self._build_indexes() logger.info("Finished resetting MaterialsEhullBuilder") def _build_indexes(self): self._materials.create_index("stability.e_above_hull") @classmethod def from_file(cls, db_file, m="materials", **kwargs): """ Get a MaterialsEhullBuilder using only a db file Args: db_file: (str) path to db file m: (str) name of "materials" collection **kwargs: other parameters to feed into the builder, e.g. mapi_key """ db_write = get_database(db_file, admin=True) return cls(db_write[m], **kwargs)
import re from pymatgen.entries.computed_entries import ComputedEntry from pymatgen.entries.compatibility import MaterialsProjectCompatibility from pymatgen import MPRester #To do our testing, let's use the MPRester to get a sample computed entry from the Materials Project. m = MPRester() entries = m.get_entries("LiFePO4") entry = entries[0]
# mp-25545 MnO2, mp-619628 MgMn2O4 charged_prototype = "mp-25545" discharged_prototype = "mp-619628" formula_list = [] spinel_list = [] for working_ion in Working_ion_pool: for redox_ion in Redox_pool: formula_list.append([redox_ion, working_ion]) for formula in formula_list: print(formula) charged_entry = mpr.get_entries(charged_prototype, inc_structure="final")[0] charged_structure = charged_entry.structure discharged_entry = \ mpr.get_entries(discharged_prototype, inc_structure="final")[0] discharged_structure = discharged_entry.structure print(charged_structure.formula, ":", discharged_structure.formula) charged_structure.replace_species({Element("Mn"): Element(formula[0])}) discharged_structure.replace_species({ Element("Mn"): Element(formula[0]), Element("Mg"): Element(formula[1]) }) print(charged_structure.formula, ":", discharged_structure.formula) cursor = materials.find({"pretty_formula": formula[0] + "O2"}, {"_id": 0}) counter = 1
rest = MPRester('XaCJrv4nBIeuy3kd') params_dict = {} structures = {} psps = os.listdir('/home/bcomer3/sparc/ase_sparc/pysparcx/sparc/pseudos/LDA_pseudos/') available_psps = [a.split('.')[0] for a in psps] # metals metals = ['Pt', 'Sc', 'La', 'Na', 'Au', 'Os', 'V', 'Zn', 'Bi', 'Co', 'Pd'] sizes = [(4,2,2), (4,3,2), (3,1,1), (3,2,1), (1,1,7), (2,2,2), (2,1,1),(2,2,1), (1,1,1), (2,1,1), (2,2,1)] for size, metal in zip(sizes, metals): struc_l = rest.get_entries(metal, sort_by_e_above_hull=True) struc_l = struc_l[0] struct = rest.get_structure_by_material_id(struc_l.entry_id) if metal == 'Pt': struct.add_site_property('magmom', [0] * len(struct)) struct *= size if metal in ['Pt', 'Sc']: del struct[0] if metal == 'Hf': del struct[50] del struct[35] del struct[100] #print(len(struct)) if metal == 'Sc': print(len(struct)) add_to_dict(struct)
#!/opt/anaconda3/bin/python from pymatgen import MPRester api = MPRester("eDCEK5m9WVjmajp7e8af") compteur = 0 for i in range(1, 7): # Nous pouvons mettre (2,7) puisque nous recherchons 2 composés entries = api.get_entries({"nelements": i}, property_data=['elasticity']) for entry in entries: if entry.data["elasticity"]: oxygenFound = False soufreFound = False position = 0 while position < len(entry.composition.elements) and not (oxygenFound and soufreFound): # element = entry.composition.elements[position] if entry.composition.elements[position].name == "O": # element.name oxygenFound = True if entry.composition.elements[position].name == "S": # element.name soufreFound = True position += 1 if oxygenFound and soufreFound: compteur = compteur + 1 print("Le nombre d'éléments contenant S et O est : " + str(compteur))
return object[0] return None # 1- On recupere toutes les lignes du fichiers csv data_from_cv = importer("elasticElate_ALL_revisionArt_without_Zero.csv") print("\nNombre de tous les éléments dans le fichier csv = {}\n".format( data_from_cv.shape[0])) # 2- Lister tous les material Ids Materials_Ids = tuple(list(data_from_cv.index.values)) # 3- Recuperation de tous les entries avec les propriétés correspondantes entries = api.get_entries({'material_id': { '$in': Materials_Ids }}, property_data=propsTableauCritere) # materials = api.query(criteria={'material_id': {'$in': Materials_Ids}}, properties=propsTableauCritere) # 4- Recupération des propriétés des éléments du tableau periodique get_all_elements() # 5-Calcul des propriétés à completer au fichier csv data_additional_prop = get_calculated_properties(entries) # # 6- Generation du nouveau fichier csv contenant toutes les proprietes export_additional_properties(data_from_cv, data_additional_prop, 'Extract_Allvalues_descriptors_sans_voronoi.csv')
dict_charge = materials.find({"task_id": id_charge})[0] dict_discharge = materials.find({"task_id": id_discharge})[0] charge_struc = Structure.from_dict(dict_charge["structure"]) charge_energy = dict_charge["final_energy"] entry_charge = ComputedStructureEntry(charge_struc, charge_energy) charge_ehull = dict_charge["e_above_hull"] discharge_struc = Structure.from_dict(dict_discharge["structure"]) discharge_energy = dict_discharge["final_energy"] entry_discharge = ComputedStructureEntry(discharge_struc, discharge_energy) discharge_ehull = dict_discharge["e_above_hull"] mpr = MPRester(api_key=API_KEY, host="www.materialsproject.org") entries = mpr.get_entries(result[0][1], inc_structure="final") counter = 0 energies = [] for entry in entries: energies.append(entry.energy_per_atom) working_ion_entry = entries[(energies.index(min(energies)))] cathode = InsertionElectrode([entry_charge, entry_discharge], working_ion_entry) batt_list.append( [result[0], result[1], result[2], charge_struc.formula, charge_ehull, discharge_struc.formula, discharge_ehull, cathode.max_voltage_step, cathode.get_average_voltage(), cathode.get_capacity_vol(), cathode.get_capacity_grav(),
parser.add_option("-f", "--format", dest="format", default='poscar', help="export structure in which format, poscar or cif", metavar="format") (options, args) = parser.parse_args() mpr = MPRester('9RTlN5ZOXst6PAdS') strucs = [] if options.id is None: system = parse_system(options.element) if type(system) is not list: mp_entries = mpr.get_entries(system) else: mp_entries = mpr.get_entries_in_chemsys(system) pd = PhaseDiagram(mp_entries) if options.dimension is None: options.dimension = len(system) for entry in mp_entries: accept = False if type(system) is list: if len(entry.composition) >= options.dimension: eng = pd.get_e_above_hull(entry) if eng <= options.cutoff: accept = True else: eng = entry.energy_per_atom accept = True
class MaterialsEhullBuilder(AbstractBuilder): def __init__(self, materials_write, mapi_key=None, update_all=False): """ Starting with an existing materials collection, adds stability information and The Materials Project ID. Args: materials_write: mongodb collection for materials (write access needed) mapi_key: (str) Materials API key (if MAPI_KEY env. var. not set) update_all: (bool) - if true, updates all docs. If false, only updates docs w/o a stability key """ self._materials = materials_write self.mpr = MPRester(api_key=mapi_key) self.update_all = update_all def run(self): logger.info("MaterialsEhullBuilder starting...") self._build_indexes() q = {"thermo.energy": {"$exists": True}} if not self.update_all: q["stability"] = {"$exists": False} mats = [m for m in self._materials.find(q, {"calc_settings": 1, "structure": 1, "thermo.energy": 1, "material_id": 1})] pbar = tqdm(mats) for m in pbar: pbar.set_description("Processing materials_id: {}".format(m['material_id'])) try: params = {} for x in ["is_hubbard", "hubbards", "potcar_spec"]: params[x] = m["calc_settings"][x] structure = Structure.from_dict(m["structure"]) energy = m["thermo"]["energy"] my_entry = ComputedEntry(structure.composition, energy, parameters=params) # TODO: @computron This only calculates Ehull with respect to Materials Project. # It should also account for the current database's results. -computron self._materials.update_one({"material_id": m["material_id"]}, {"$set": {"stability": self.mpr.get_stability([my_entry])[0]}}) # TODO: @computron: also add additional properties like inverse hull energy? # TODO: @computron it's better to use PD tool or reaction energy calculator # Otherwise the compatibility schemes might have issues...one strategy might be # use MP only to retrieve entries but compute the PD locally -computron for el, elx in my_entry.composition.items(): entries = self.mpr.get_entries(el.symbol, compatible_only=True) min_e = min(entries, key=lambda x: x.energy_per_atom).energy_per_atom energy -= elx * min_e self._materials.update_one({"material_id": m["material_id"]}, {"$set": {"thermo.formation_energy_per_atom": energy / structure.num_sites}}) mpids = self.mpr.find_structure(structure) self._materials.update_one({"material_id": m["material_id"]}, {"$set": {"mpids": mpids}}) except: import traceback logger.exception("<---") logger.exception("There was an error processing material_id: {}".format(m)) logger.exception(traceback.format_exc()) logger.exception("--->") logger.info("MaterialsEhullBuilder finished processing.") def reset(self): logger.info("Resetting MaterialsEhullBuilder") self._materials.update_many({}, {"$unset": {"stability": 1}}) self._build_indexes() logger.info("Finished resetting MaterialsEhullBuilder") def _build_indexes(self): self._materials.create_index("stability.e_above_hull") @classmethod def from_file(cls, db_file, m="materials", **kwargs): """ Get a MaterialsEhullBuilder using only a db file Args: db_file: (str) path to db file m: (str) name of "materials" collection **kwargs: other parameters to feed into the builder, e.g. mapi_key """ db_write = get_database(db_file, admin=True) return cls(db_write[m], **kwargs)
def get_random_packed(composition, add_specie=None, target_atoms=100, vol_per_atom=None, vol_exp=1.0, modify_species=None, use_random_seed=True): mpr = MPRester() if type(composition) == str: composition = Composition(composition) if type(add_specie) == str: add_specie = Composition(add_specie) comp_entries = mpr.get_entries(composition.reduced_formula, inc_structure=True) if vol_per_atom is None: if len(comp_entries) > 0: vols = np.min([ entry.structure.volume / entry.structure.num_sites for entry in comp_entries ]) else: # Find all Materials project entries containing the elements in the # desired composition to estimate starting volume. _entries = mpr.get_entries_in_chemsys( [str(el) for el in composition.elements], inc_structure=True) entries = [] for entry in _entries: if set(entry.structure.composition.elements) == set( composition.elements): entries.append(entry) if len(entry.structure.composition.elements) >= 2: entries.append(entry) vols = [ entry.structure.volume / entry.structure.num_sites for entry in entries ] vol_per_atom = np.mean(vols) # Find total composition of atoms in the unit cell formula, factor = composition.get_integer_formula_and_factor() composition = Composition(formula) comp = composition * np.ceil(target_atoms / composition.num_atoms) if add_specie is not None: comp += add_specie # comp = Composition(comp) # Generate dict of elements and amounts for AmorphousMaker structure = {} for el in comp: structure[str(el)] = int(comp.element_composition.get(el)) if modify_species is not None: for i, v in modify_species.items(): structure[i] += v # use packmol to get a random configured structure packmol_path = os.environ['PACKMOL_PATH'] amorphous_maker_params = { 'box_scale': (vol_per_atom * comp.num_atoms * vol_exp)**(1 / 3), 'packmol_path': packmol_path, 'xyz_paths': None, 'time_seed': use_random_seed } glass = AmorphousMaker(structure, **amorphous_maker_params) structure = glass.random_packed_structure return structure