def test(self, structure): failures = [] if self.is_valid: if not structure.is_valid(): failures.append("IS_VALID=False") if self.potcar_exists: elements = structure.composition.elements if set(elements).intersection(set(self.NO_POTCARS)): failures.append("POTCAR_EXISTS=False") if self.max_natoms: if structure.num_sites > self.max_natoms: failures.append("MAX_NATOMS=Exceeded") if self.is_ordered: if not structure.is_ordered: failures.append("IS_ORDERED=False") if self.not_in_MP: mpr = MPRester(self.MAPI_KEY) mpids = mpr.find_structure(structure) if mpids: if self.require_bandstructure: for mpid in mpids: try: bs = mpr.get_bandstructure_by_material_id(mpid) if bs: failures.append("NOT_IN_MP=False ({})".format(mpid)) except: pass else: failures.append("NOT_IN_MP=False ({})".format(mpids[0])) return True if not failures else False
def run_task(self, fw_spec): mpr = MPRester(env_chk(self.get("MAPI_KEY"), fw_spec)) vasprun, outcar = get_vasprun_outcar(self.get("calc_dir", "."), parse_dos=False, parse_eigen=False) my_entry = vasprun.get_computed_entry(inc_structure=False) stored_data = mpr.get_stability([my_entry])[0] if stored_data["e_above_hull"] > self.get("ehull_cutoff", 0.05): return FWAction(stored_data=stored_data, exit=True, defuse_workflow=True) else: return FWAction(stored_data=stored_data)
def __init__(self, api_key=None): """ Args: api_key: (str) Your Materials Project API key, or None if you've set up your pymatgen config. """ self.mprester = MPRester(api_key=api_key)
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 get_materials_list(): """Fetch data (from local cache if available).""" try: _log.info('Trying data cache for materials') with open('materials_list.pickle') as f: return pickle.load(f) except IOError: _log.info('Fetching remote data') m = MPRester() materials_list = m.query( criteria={"elasticity": {"$exists": True}}, properties=['pretty_formula', 'reduced_cell_formula', 'task_id', "elasticity.K_VRH", "elasticity.K_VRH", 'volume', 'density', 'formation_energy_per_atom', 'nsites']) # Save for later with open('materials_list.pickle', 'w') as f: pickle.dump(materials_list, f) _log.info('Data loaded') return materials_list
def test_mpr_pipeline(self): from pymatgen import MPRester mpr = MPRester() data = mpr.get_pourbaix_entries(["Zn"]) pbx = PourbaixDiagram(data, filter_solids=True, conc_dict={"Zn": 1e-8}) pbx.find_stable_entry(10, 0) data = mpr.get_pourbaix_entries(["Ag", "Te"]) pbx = PourbaixDiagram(data, filter_solids=True, conc_dict={"Ag": 1e-8, "Te": 1e-8}) self.assertEqual(len(pbx.stable_entries), 30) test_entry = pbx.find_stable_entry(8, 2) self.assertAlmostEqual(test_entry.energy, 2.393900378500001) # Test custom ions entries = mpr.get_pourbaix_entries(["Sn", "C", "Na"]) ion = IonEntry(Ion.from_formula("NaO28H80Sn12C24+"), -161.676) custom_ion_entry = PourbaixEntry(ion, entry_id='my_ion') pbx = PourbaixDiagram(entries + [custom_ion_entry], filter_solids=True, comp_dict={"Na": 1, "Sn": 12, "C": 24}) self.assertAlmostEqual(pbx.get_decomposition_energy(custom_ion_entry, 5, 2), 8.31082110278154)
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 run(mpfile, **kwargs): from pymatgen import MPRester, Composition import pandas as pd input_file = mpfile.document['_hdata'].pop('input_file') file_path = os.path.join(os.environ['HOME'], 'work', input_file) if not os.path.exists(file_path): return 'Please upload', file_path df_dct = pd.read_excel(file_path) columns_units = [ ('A-Site', ''), ('B-Site', ''), ('a', 'Å'), ('Eᶠ|ABO₃', 'eV'), ('Eᶠ|Yᴮ', 'eV'), ('Eᶠ|Vᴼ', 'eV'), ('Eᶠ|Hᵢ', 'eV'), ('ΔEᵢ|Yᴮ-Hᵢ', 'eV') ] columns = df_dct.columns mpr = MPRester(endpoint="http://materialsproject.org:8080/rest/v2") for row_idx, row in df_dct.iterrows(): formula = '{}{}O3'.format(row[columns[0]], row[columns[1]]) comp = Composition(formula) crit = {"reduced_cell_formula": comp.to_reduced_dict, "nsites": 5} docs = mpr.query(criteria=crit, properties=["task_id", "volume"]) if len(docs) > 1: volume = row[columns[2]]**3 volumes = pd.np.array([r['volume'] for r in docs]) idx = pd.np.abs(volumes-volume).argmin() identifier = docs[idx]['task_id'] continue elif not docs: print formula, 'not found on MP' continue else: identifier = docs[0]['task_id'] print formula, '->', identifier d = RecursiveDict() for col, (key, unit) in zip(columns, columns_units): d[key] = clean_value(row[col], unit) mpfile.add_hierarchical_data(nest_dict(d, ['data']), identifier=identifier)
def run(mpfile, hosts=None, download=False, **kwargs): #mpfile.unique_mp_cat_ids = False from pymatgen import MPRester mpr = MPRester() fpath = os.path.join(os.environ['HOME'], 'work', 'dilute_solute_diffusion.xlsx') if download or not os.path.exists(fpath): figshare_id = mpfile.hdata.general['info']['figshare_id'] url = 'https://api.figshare.com/v2/articles/{}'.format(figshare_id) print 'get figshare article {}'.format(figshare_id) r = requests.get(url) figshare = json.loads(r.content) mpfile.document['_hdata']['version'] = figshare['version'] print 'read excel from figshare into DataFrame' df_dct = None for d in figshare['files']: if 'xlsx' in d['name']: # Dict of DataFrames is returned, with keys representing sheets df_dct = read_excel(d['download_url'], sheet_name=None) break if df_dct is None: print 'no excel sheet found on figshare' return print 'save excel to disk' writer = ExcelWriter(fpath) for sheet, df in df_dct.items(): df.to_excel(writer, sheet) writer.save() else: df_dct = read_excel(fpath, sheet_name=None) print len(df_dct), 'sheets loaded.' print 'looping hosts ...' host_info = df_dct['Host Information'] host_info.set_index(host_info.columns[0], inplace=True) host_info.dropna(inplace=True) for idx, host in enumerate(host_info): if hosts is not None: if isinstance(hosts, int) and idx+1 > hosts: break elif isinstance(hosts, list) and not host in hosts: continue print 'get mp-id for {}'.format(host) mpid = None for doc in mpr.query( criteria={'pretty_formula': host}, properties={'task_id': 1} ): if doc['sbxd'][0]['decomposes_to'] is None: mpid = doc['task_id'] break if mpid is None: print 'mp-id for {} not found'.format(host) continue print 'add host info for {}'.format(mpid) hdata = host_info[host].to_dict(into=RecursiveDict) for k in hdata.keys(): v = hdata.pop(k) ks = k.split() if ks[0] not in hdata: hdata[ks[0]] = RecursiveDict() unit = ks[-1][1:-1] if ks[-1].startswith('[') else '' subkey = '_'.join(ks[1:-1] if unit else ks[1:]).split(',')[0] if subkey == "lattice_constant": unit = u'Å' try: hdata[ks[0]][subkey] = clean_value(v, unit.replace('angstrom', u'Å')) except ValueError: hdata[ks[0]][subkey] = v hdata['formula'] = host df = df_dct['{}-X'.format(host)] rows = list(isnull(df).any(1).nonzero()[0]) if rows: cells = df.ix[rows].dropna(how='all').dropna(axis=1)[df.columns[0]] note = cells.iloc[0].replace('following', cells.iloc[1])[:-1] hdata['note'] = note df.drop(rows, inplace=True) mpfile.add_hierarchical_data(nest_dict(hdata, ['data']), identifier=mpid) print 'add table for D₀/Q data for {}'.format(mpid) df.set_index(df['Solute element number'], inplace=True) df.drop('Solute element number', axis=1, inplace=True) df.columns = df.ix[0] df.index.name = 'index' df.drop('Solute element name', inplace=True) df = df.T.reset_index() if str(host) == 'Fe': df_D0_Q = df[[ 'Solute element name', 'Solute D0, paramagnetic [cm^2/s]', 'Solute Q, paramagnetic [eV]' ]] elif hdata['Host']['crystal_structure'] == 'HCP': df_D0_Q = df[['Solute element name', 'Solute D0 basal [cm^2/s]', 'Solute Q basal [eV]']] else: df_D0_Q = df[['Solute element name', 'Solute D0 [cm^2/s]', 'Solute Q [eV]']] df_D0_Q.columns = ['El.', 'D₀ [cm²/s]', 'Q [eV]'] mpfile.add_data_table(mpid, df_D0_Q, 'D₀_Q') if hdata['Host']['crystal_structure'] == 'BCC': print 'add table for hop activation barriers for {} (BCC)'.format(mpid) columns_E = [ 'Hop activation barrier, E_{} [eV]'.format(i) for i in range(2,5) ] + [ "Hop activation barrier, E'_{} [eV]".format(i) for i in range(3,5) ] + [ "Hop activation barrier, E''_{} [eV]".format(i) for i in range(3,5) ] + [ 'Hop activation barrier, E_{} [eV]'.format(i) for i in range(5,7) ] df_E = df[['Solute element name'] + columns_E] df_E.columns = ['El.'] + [ 'E{} [eV]'.format(i) for i in ['₂', '₃', '₄'] ] + [ 'E`{} [eV]'.format(i) for i in ['₃', '₄'] ] + [ 'E``{} [eV]'.format(i) for i in ['₃', '₄'] ] + [ 'E{} [eV]'.format(i) for i in ['₅', '₆'] ] mpfile.add_data_table(mpid, df_E, 'hop_activation_barriers') print 'add table for hop attempt frequencies for {} (BCC)'.format(mpid) columns_v = [ 'Hop attempt frequency, v_{} [THz]'.format(i) for i in range(2,5) ] + [ "Hop attempt frequency, v'_{} [THz]".format(i) for i in range(3,5) ] + [ "Hop attempt frequency, v''_{} [THz]".format(i) for i in range(3,5) ] + [ 'Hop attempt frequency, v_{} [THz]'.format(i) for i in range(5,7) ] df_v = df[['Solute element name'] + columns_v] df_v.columns = ['El.'] + [ 'v{} [THz]'.format(i) for i in ['₂', '₃', '₄'] ] + [ 'v``{} [THz]'.format(i) for i in ['₃', '₄'] ] + [ 'v``{} [THz]'.format(i) for i in ['₃', '₄'] ] + [ 'v{} [THz]'.format(i) for i in ['₅', '₆'] ] mpfile.add_data_table(mpid, df_v, 'hop_attempt_frequencies') elif hdata['Host']['crystal_structure'] == 'FCC': print 'add table for hop activation barriers for {} (FCC)'.format(mpid) columns_E = ['Hop activation barrier, E_{} [eV]'.format(i) for i in range(5)] df_E = df[['Solute element name'] + columns_E] df_E.columns = ['El.'] + ['E{} [eV]'.format(i) for i in ['₀', '₁', '₂', '₃', '₄']] mpfile.add_data_table(mpid, df_E, 'hop_activation_barriers') print 'add table for hop attempt frequencies for {} (FCC)'.format(mpid) columns_v = ['Hop attempt frequency, v_{} [THz]'.format(i) for i in range(5)] df_v = df[['Solute element name'] + columns_v] df_v.columns = ['El.'] + ['v{} [THz]'.format(i) for i in ['₀', '₁', '₂', '₃', '₄']] mpfile.add_data_table(mpid, df_v, 'hop_attempt_frequencies') elif hdata['Host']['crystal_structure'] == 'HCP': print 'add table for hop activation barriers for {} (HCP)'.format(mpid) columns_E = [ "Hop activation barrier, E_X [eV]", "Hop activation barrier, E'_X [eV]", "Hop activation barrier, E_a [eV]", "Hop activation barrier, E'_a [eV]", "Hop activation barrier, E_b [eV]", "Hop activation barrier, E'_b [eV]", "Hop activation barrier, E_c [eV]", "Hop activation barrier, E'_c [eV]" ] df_E = df[['Solute element name'] + columns_E] df_E.columns = ['El.'] + [ 'Eₓ [eV]', 'E`ₓ [eV]', 'Eₐ [eV]', 'E`ₐ [eV]', 'E_b [eV]', 'E`_b [eV]', 'Eꪱ [eV]', 'E`ꪱ [eV]' ] mpfile.add_data_table(mpid, df_E, 'hop_activation_barriers') print 'add table for hop attempt frequencies for {} (HCP)'.format(mpid) columns_v = ['Hop attempt frequency, v_a [THz]'] + ['Hop attempt frequency, v_X [THz]'] df_v = df[['Solute element name'] + columns_v] df_v.columns = ['El.'] + ['vₐ [THz]'] + ['vₓ [THz]'] mpfile.add_data_table(mpid, df_v, 'hop_attempt_frequencies') print mpfile print 'DONE'
import numpy as np from pandas.tools.plotting import scatter_matrix from pymatgen import Composition, Element, MPRester, periodic_table from sklearn import linear_model, cross_validation, ensemble import pandas as pd import matplotlib.pyplot as plt import itertools df = pd.DataFrame() allBinaries = itertools.combinations(periodic_table.all_symbols(), 2) # Create list of all binary systems API_KEY = None # Enter your key received from Materials Project if API_KEY is None: m = MPRester() else: m = MPRester(API_KEY) for system in allBinaries: results = m.get_data(system[0] + '-' + system[1], data_type='vasp') # Download DFT data for each binary system for material in results: # We will receive many compounds within each binary system if material['e_above_hull'] < 1e-6: # Check if this compound is thermodynamically stable dat = [material['pretty_formula'], material['band_gap'], material['formation_energy_per_atom'], material['density']] df = df.append(pd.Series(dat), ignore_index=True) df.columns = ['materials', 'bandgaps', 'formenergies', 'densities'] print df[0:2] print df.columns MAX_Z = 100 # maximum length of vector to hold naive feature set
from __future__ import division import numpy as np import matplotlib.pyplot as plt from pymatgen import MPRester # import/truncate raw data (volume, density, energies, etc) m = MPRester("ID") data = m.query(criteria={"elasticity": {"$exists": True}}, properties=["pretty_formula", "volume", "K_VRH"]) # for now, import parameters and also bulk modulus (known), in future we will use parameters to select bulk moduli to be calculated # subfunction for formatting # define desired objectives and bounds/tolerances (GPa) tolcost = 1e-5 kdes = 205 # define tuning/mating parameters theta = 1/2 w1 = 1 # create objective function cost = lambda k: w1*((kdes-k)/kdes)**2 # randomly sample data and calculate costs
#http://pymatgen.org/examples.html from pymatgen.core import * from pymatgen.io.vasp.sets import * from pymatgen import Lattice, Structure, Molecule from pymatgen.io.vasp.sets import MPRelaxSet from pymatgen import MPRester, Composition, Element from pymatgen.io.vasp import Vasprun from pymatgen.analysis.phase_diagram import CompoundPhaseDiagram, GrandPotentialPhaseDiagram, PDPlotter, PhaseDiagram import palettable import matplotlib as mpl rester = MPRester('5TxDLF4Iwa7rGcAl') #Generate your own key from materials project.. mp_entries = rester.get_entries_in_chemsys(["Li", "Fe", "O","S"]) pd = PhaseDiagram(mp_entries) plotter = PDPlotter(pd) plotter.show()
def compute_environments(chemenv_configuration): string_sources = { 'cif': { 'string': 'a Cif file', 'regexp': '.*\.cif$' }, 'mp': { 'string': 'the Materials Project database', 'regexp': 'mp-[0-9]+$' } } questions = {'c': 'cif'} if chemenv_configuration.has_materials_project_access: questions['m'] = 'mp' lgf = LocalGeometryFinder() lgf.setup_parameters() allcg = AllCoordinationGeometries() strategy_class = strategies_class_lookup[ chemenv_configuration.package_options['default_strategy']['strategy']] #TODO: Add the possibility to change the parameters and save them in the chemenv_configuration default_strategy = strategy_class() default_strategy.setup_options( chemenv_configuration.package_options['default_strategy'] ['strategy_options']) max_dist_factor = chemenv_configuration.package_options[ 'default_max_distance_factor'] firsttime = True while True: if len(questions) > 1: found = False print( 'Enter the source from which the structure is coming or <q> to quit :' ) for key_character, qq in questions.items(): print(' - <{}> for a structure from {}'.format( key_character, string_sources[qq]['string'])) test = input(' ... ') if test == 'q': break if test not in list(questions.keys()): for key_character, qq in questions.items(): if re.match(string_sources[qq]['regexp'], str(test)) is not None: found = True source_type = qq if not found: print('Wrong key, try again ...') continue else: source_type = questions[test] else: found = False source_type = list(questions.values())[0] if found and len(questions) > 1: input_source = test if source_type == 'cif': if not found: input_source = input('Enter path to cif file : ') cp = CifParser(input_source) structure = cp.get_structures()[0] elif source_type == 'mp': if not found: input_source = input( 'Enter materials project id (e.g. "mp-1902") : ') a = MPRester(chemenv_configuration.materials_project_api_key) structure = a.get_structure_by_material_id(input_source) lgf.setup_structure(structure) print('Computing environments for {} ... '.format( structure.composition.reduced_formula)) se = lgf.compute_structure_environments_detailed_voronoi( maximum_distance_factor=max_dist_factor) print('Computing environments finished') while True: test = input( 'See list of environments determined for each (unequivalent) site ? ' '("y" or "n", "d" with details, "g" to see the grid) : ') strategy = default_strategy if test in ['y', 'd', 'g']: strategy.set_structure_environments(se) for eqslist in se.equivalent_sites: site = eqslist[0] isite = se.structure.index(site) try: if strategy.uniquely_determines_coordination_environments: ces = strategy.get_site_coordination_environments( site) else: ces = strategy.get_site_coordination_environments_fractions( site) except NeighborsNotComputedChemenvError: continue if ces is None: continue if len(ces) == 0: continue comp = site.species_and_occu #ce = strategy.get_site_coordination_environment(site) if strategy.uniquely_determines_coordination_environments: ce = ces[0] if ce is None: continue thecg = allcg.get_geometry_from_mp_symbol(ce[0]) mystring = 'Environment for site #{} {} ({}) : {} ({})\n'.format( str(isite), comp.get_reduced_formula_and_factor()[0], str(comp), thecg.name, ce[0]) else: mystring = 'Environments for site #{} {} ({}) : \n'.format( str(isite), comp.get_reduced_formula_and_factor()[0], str(comp)) for ce in ces: cg = allcg.get_geometry_from_mp_symbol(ce[0]) csm = ce[1]['other_symmetry_measures'][ 'csm_wcs_ctwcc'] mystring += ' - {} ({}): {:.2f} % (csm : {:2f})\n'.format( cg.name, cg.mp_symbol, 100.0 * ce[2], csm) if test in [ 'd', 'g' ] and strategy.uniquely_determines_coordination_environments: if thecg.mp_symbol != UNCLEAR_ENVIRONMENT_SYMBOL: mystring += ' <Continuous symmetry measures> ' mingeoms = se.ce_list[isite][ thecg. coordination_number][0].minimum_geometries() for mingeom in mingeoms: csm = mingeom[1]['other_symmetry_measures'][ 'csm_wcs_ctwcc'] mystring += '{} : {:.2f} '.format( mingeom[0], csm) print(mystring) if test == 'g': test = input( 'Enter index of site(s) for which you want to see the grid of parameters : ' ) indices = list(map(int, test.split())) print(indices) for isite in indices: se.plot_environments(isite, additional_condition=se.AC.ONLY_ACB) if no_vis: test = input('Go to next structure ? ("y" to do so)') if test == 'y': break continue test = input( 'View structure with environments ? ("y" for the unit cell or "m" for a supercell or "n") : ' ) if test in ['y', 'm']: if test == 'm': mydeltas = [] test = input('Enter multiplicity (e.g. 3 2 2) : ') nns = test.split() for i0 in range(int(nns[0])): for i1 in range(int(nns[1])): for i2 in range(int(nns[2])): mydeltas.append( np.array([1.0 * i0, 1.0 * i1, 1.0 * i2], np.float)) else: mydeltas = [np.zeros(3, np.float)] if firsttime: vis = StructureVis(show_polyhedron=False, show_unit_cell=True) vis.show_help = False firsttime = False vis.set_structure(se.structure) strategy.set_structure_environments(se) for isite, site in enumerate(se.structure): try: ces = strategy.get_site_coordination_environments(site) except NeighborsNotComputedChemenvError: continue if len(ces) == 0: continue ce = strategy.get_site_coordination_environment(site) if ce is not None and ce[0] != UNCLEAR_ENVIRONMENT_SYMBOL: for mydelta in mydeltas: psite = PeriodicSite(site._species, site._fcoords + mydelta, site._lattice, properties=site._properties) vis.add_site(psite) neighbors = strategy.get_site_neighbors(psite) draw_cg(vis, psite, neighbors, cg=lgf.cg.get_geometry_from_mp_symbol( ce[0]), perm=ce[1]['permutation']) vis.show() test = input('Go to next structure ? ("y" to do so) : ') if test == 'y': break print('')
class MPData(Dataset): """ The MPData dataset is a wrapper for a dataset from Materials Project. atom_init.json: a JSON file that stores the initialization vector for each element. ID.cif: a CIF file that recodes the crystal structure, where ID is the unique ID for the crystal. Parameters ---------- criteria: dict Mongo-like query language for MP structures atom_init_file_dir: str dir of the atom_init_file.json max_num_nbr: int The maximum number of neighbors while constructing the crystal graph radius: float The cutoff radius for searching neighbors dmin: float The minimum distance for constructing GaussianDistance step: float The step size for constructing GaussianDistance random_seed: int Random seed for shuffling the dataset Returns ------- atom_fea: torch.Tensor shape (n_i, atom_fea_len) nbr_fea: torch.Tensor shape (n_i, M, nbr_fea_len) nbr_fea_idx: torch.LongTensor shape (n_i, M) target: torch.Tensor shape (1, ) cif_id: str or int """ def __init__(self, criteria, atom_init_file_dir, api_key="VIqD4QUxH6wNpyc5", max_num_nbr=12, radius=8, dmin=0, step=0.2, random_seed=123): self.api = MPRester(api_key) mp_list = [ i['material_id'] for i in self.api.query(criteria=criteria, properties=['material_id']) ] self.max_num_nbr, self.radius = max_num_nbr, radius atom_init_file = atom_init_file_dir self.ari = AtomCustomJSONInitializer(atom_init_file) self.gdf = GaussianDistance(dmin=dmin, dmax=self.radius, step=step) self.id_prop_data = [(target, cif_id) for target, cif_id in enumerate(mp_list)] def __len__(self): return len(self.id_prop_data) @functools.lru_cache(maxsize=None) def __getitem__(self, idx): target, cif_id = self.id_prop_data[idx] crystal = self.api.get_structure_by_material_id(cif_id) atom_fea = np.vstack([ self.ari.get_atom_fea(crystal[i].specie.number) for i in range(len(crystal)) ]) atom_fea = torch.Tensor(atom_fea) all_nbrs = crystal.get_all_neighbors(self.radius, include_index=True) all_nbrs = [sorted(nbrs, key=lambda x: x[1]) for nbrs in all_nbrs] nbr_fea_idx = np.array([ list( map(lambda x: x[2], nbr[:self.max_num_nbr]) for nbr in all_nbrs) ]) nbr_fea = np.array([list(map(lambda x: x[1], nbr[: self.max_num_nbr])) \ for nbr in all_nbrs] ) atom_fea = torch.Tensor(atom_fea) nbr_fea = torch.Tensor(nbr_fea) nbr_fea_idx = torch.LongTensor(nbr_fea_idx) target = torch.Tensor([float(target)]) return (atom_fea, nbr_fea, nbr_fea_idx), target, cif_id
from pymatgen import MPRester m = MPRester("Your-API-Key") query = { 'elements': { '$in': ['Al', 'Ga', 'In'], '$all': ['O'] }, 'nelements': { '$lte': 4 }, } properties = ['pretty_formula', 'formation_energy_per_atom', 'band_gap'] data = m.query(query, properties) print('Query: ', query) print('data: ', type(data)) print('Number of results: ', len(data), '\n') print('\tE_f_per_atom\tbandgap') for d in data: print( d.get('pretty_formula'), '\t%.4f\t\t%.4f' % (d.get('formation_energy_per_atom'), d.get('band_gap')))
from pymatgen import SETTINGS, SETTINGS_FILE from pymatgen import MPRester try: m = MPRester(SETTINGS['PMG_MAPI_KEY']) except: m = MPRester(SETTINGS['MAPI_KEY'])
def get_tensor(name): m = MPRester(key) tensor = m.query(criteria={"elasticity": {"$exists": True}, "pretty_formula": name}, properties=["elasticity.elastic_tensor"]) return tensor
# import for this example from pymatgen import Structure, Lattice # create Dash app as normal app = dash.Dash() # create the Structure object structure = Structure(Lattice.cubic(4.2), ["Na", "K"], [[0, 0, 0], [0.5, 0.5, 0.5]]) from pymatgen import MPRester # create an input structure as an example structure_component = ctc.StructureMoleculeComponent( MPRester().get_structure_by_material_id("mp-804"), id="structure_in") # and a way to view the transformed structure structure_component_transformed = ctc.StructureMoleculeComponent( MPRester().get_structure_by_material_id("mp-804"), id="structure_out") # and the transformation component itself transformation_component = ctc.AllTransformationsComponent( transformations=[ "AutoOxiStateDecorationTransformationComponent", "SupercellTransformationComponent", # "SlabTransformationComponent", # "SubstitutionTransformationComponent", "CubicSupercellTransformationComponent", # "GrainBoundaryTransformationComponent" ], input_structure=structure_component,
from pymatgen import MPRester from pymatgen.util.string import unicodeify # noinspection PyUnresolvedReferences import propnet.symbols from propnet.core.registry import Registry from propnet.dbtools.correlation import CorrelationBuilder from pymongo.errors import ServerSelectionTimeoutError import logging logger = logging.getLogger(__name__) mpr = MPRester() try: store = loadfn(environ["PROPNET_STORE_FILE"]) store.connect() except (ServerSelectionTimeoutError, KeyError): from maggma.stores import MemoryStore store = MemoryStore() store.connect() # layout won't work if database is down, but at least web app will stay up scalar_symbols = {k: v for k, v in Registry("symbols").items() if (v.category == 'property' and v.shape == 1)} warning_layout = html.Div('No database connection could be established.', style={'font-family': 'monospace', 'color': 'rgb(211, 84, 0)', 'text-align': 'left',
print('Error: Creating directory. ' + directory) ########################################################################### def replace_line(file_name, line_num, text): lines = open(file_name, 'r').readlines() lines[line_num] = text out = open(file_name, 'w') out.writelines(lines) out.close() ############################################################################ load_dotenv(".env") MATERIAL_API_KEY = os.getenv("MATERIAL_API_KEY") mpr = MPRester(MATERIAL_API_KEY) df_entries_ori = pd.read_csv('mpid_list_v2.csv') mpid_list = df_entries_ori['mp_id'].tolist() ############################################################################## alkali_elements = [ 'Sr', 'Ba', 'K', 'Na', 'Li', 'Rb', 'Cs', 'Be', 'Mg', 'Ca', 'Ba', 'Si' ] TM_elements = [ "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Y", "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg"
from pandas._libs import properties from pymatgen import MPRester import matplotlib.pyplot as plt # from pymatgen.analysis.phase_diagram import PhaseDiagram, PDPlotter from pymatgen.analysis.elasticity import elastic from pymatgen.util import plotting import numpy as np api = MPRester("eDCEK5m9WVjmajp7e8af") # datax = api.query(criteria={"nelements": {'$lte': 6 ,'$gte': 1 }, "elements": {'$all': ['S','O']}, "elasticity": {'$ne': None}}, properties=['pretty_formula','elasticity.G_Reuss', 'elasticity.G_VRH', 'elasticity.G_Voigt', 'elasticity.G_Voigt_Reuss_Hill', 'elasticity.K_Reuss', 'elasticity.K_VRH', 'elasticity.K_Voigt', 'elasticity.K_Voigt_Reuss_Hill']) materials = api.query(criteria={"nelements": {'$lte': 6, '$gte': 1}, "elasticity": {'$ne': None}}, properties=['pretty_formula', 'elasticity.G_Reuss', 'elasticity.G_VRH', 'elasticity.G_Voigt', 'elasticity.G_Voigt_Reuss_Hill', 'elasticity.K_Reuss', 'elasticity.K_VRH', 'elasticity.K_Voigt', 'elasticity.K_Voigt_Reuss_Hill']) props = ['elasticity.G_Reuss', 'elasticity.G_VRH', 'elasticity.G_Voigt', 'elasticity.G_Voigt_Reuss_Hill', 'elasticity.K_Reuss', 'elasticity.K_VRH', 'elasticity.K_Voigt', 'elasticity.K_Voigt_Reuss_Hill'] lin = len(props) col = len(materials) def recup(materials): j = 0 tableau = np.zeros(shape=(lin, col)) elements = [] for material in materials:
#Import MPRester from pymatgen import MPRester import sqlite3 #Private key for Materials Project database (MP-DB) mpr = MPRester("") #Open database conn = sqlite3.connect('mpdata.sqlite') #connect to db or create cur = conn.cursor() #database handle #Create SQL tables from outermost to innermost #Set up tables from outermost to innermost cur.executescript(''' CREATE TABLE IF NOT EXISTS SpaceGroup ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, symbol TEXT UNIQUE, number TEXT, point_group TEXT, crystal_system TEXT, hall TEXT ); CREATE TABLE IF NOT EXISTS Material ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, material_id TEXT UNIQUE, density FLOAT, element1 TEXT, element1_num INTEGER, element2 TEXT, element2_num INTEGER,
def get_mp_structure(cls, mpid): m = MPRester() return m.get_structure_by_material_id(mpid)
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)
'V': 1.682, 'Cr': 2.013, 'Mn': 1.68085, 'Fe': 2.733, 'Co': 1.874, 'Ni': 2.164, 'Mo': 3.531, 'W': 5.159 } ############################################################################### load_dotenv('.env') MATERIAL_API_KEY = os.getenv('MATERIAL_API_KEY') mpr = MPRester(MATERIAL_API_KEY) df = pd.read_csv('mpid_list_v3.csv') entries_from_list = mpr.query( criteria={'material_id': { '$in': list(df.mp_id.values) }}, properties=[ "material_id", "task_id", "pretty_formula", "formation_energy_per_atom", "cif", "energy", "energy_per_atom", "structure", "input.incar", "magnetic_type", "total_magnetization", "e_above_hull", "band_gap", "volume", "theoretical" ]) print("Total %d structures were identified from %d mp-ID" %
def run(mpfile, hosts=None, download=False, **kwargs): #mpfile.unique_mp_cat_ids = False from pymatgen import MPRester mpr = MPRester() fpath = os.path.join(os.environ['HOME'], 'work', 'dilute_solute_diffusion.xlsx') if download or not os.path.exists(fpath): figshare_id = mpfile.hdata.general['info']['figshare_id'] url = 'https://api.figshare.com/v2/articles/{}'.format(figshare_id) print 'get figshare article {}'.format(figshare_id) r = requests.get(url) figshare = json.loads(r.content) mpfile.document['_hdata']['version'] = figshare['version'] print 'read excel from figshare into DataFrame' df_dct = None for d in figshare['files']: if 'xlsx' in d['name']: # Dict of DataFrames is returned, with keys representing sheets df_dct = read_excel(d['download_url'], sheet_name=None) break if df_dct is None: print 'no excel sheet found on figshare' return print 'save excel to disk' writer = ExcelWriter(fpath) for sheet, df in df_dct.items(): df.to_excel(writer, sheet) writer.save() else: df_dct = read_excel(fpath, sheet_name=None) print len(df_dct), 'sheets loaded.' print 'looping hosts ...' host_info = df_dct['Host Information'] host_info.set_index(host_info.columns[0], inplace=True) host_info.dropna(inplace=True) for idx, host in enumerate(host_info): if hosts is not None: if isinstance(hosts, int) and idx + 1 > hosts: break elif isinstance(hosts, list) and not host in hosts: continue print 'get mp-id for {}'.format(host) mpid = None for doc in mpr.query(criteria={'pretty_formula': host}, properties={'task_id': 1}): if doc['sbxd'][0]['decomposes_to'] is None: mpid = doc['task_id'] break if mpid is None: print 'mp-id for {} not found'.format(host) continue print 'add host info for {}'.format(mpid) hdata = host_info[host].to_dict(into=RecursiveDict) for k in hdata.keys(): v = hdata.pop(k) ks = k.split() if ks[0] not in hdata: hdata[ks[0]] = RecursiveDict() unit = ks[-1][1:-1] if ks[-1].startswith('[') else '' subkey = '_'.join(ks[1:-1] if unit else ks[1:]).split(',')[0] if subkey == "lattice_constant": unit = u'Å' try: hdata[ks[0]][subkey] = clean_value( v, unit.replace('angstrom', u'Å')) except ValueError: hdata[ks[0]][subkey] = v hdata['formula'] = host df = df_dct['{}-X'.format(host)] rows = list(isnull(df).any(1).nonzero()[0]) if rows: cells = df.ix[rows].dropna(how='all').dropna(axis=1)[df.columns[0]] note = cells.iloc[0].replace('following', cells.iloc[1])[:-1] hdata['note'] = note df.drop(rows, inplace=True) mpfile.add_hierarchical_data(nest_dict(hdata, ['data']), identifier=mpid) print 'add table for D₀/Q data for {}'.format(mpid) df.set_index(df['Solute element number'], inplace=True) df.drop('Solute element number', axis=1, inplace=True) df.columns = df.ix[0] df.index.name = 'index' df.drop('Solute element name', inplace=True) df = df.T.reset_index() if str(host) == 'Fe': df_D0_Q = df[[ 'Solute element name', 'Solute D0, paramagnetic [cm^2/s]', 'Solute Q, paramagnetic [eV]' ]] elif hdata['Host']['crystal_structure'] == 'HCP': df_D0_Q = df[[ 'Solute element name', 'Solute D0 basal [cm^2/s]', 'Solute Q basal [eV]' ]] else: df_D0_Q = df[[ 'Solute element name', 'Solute D0 [cm^2/s]', 'Solute Q [eV]' ]] df_D0_Q.columns = ['El.', 'D₀ [cm²/s]', 'Q [eV]'] mpfile.add_data_table(mpid, df_D0_Q, 'D₀_Q') if hdata['Host']['crystal_structure'] == 'BCC': print 'add table for hop activation barriers for {} (BCC)'.format( mpid) columns_E = [ 'Hop activation barrier, E_{} [eV]'.format(i) for i in range(2, 5) ] + [ "Hop activation barrier, E'_{} [eV]".format(i) for i in range(3, 5) ] + [ "Hop activation barrier, E''_{} [eV]".format(i) for i in range(3, 5) ] + [ 'Hop activation barrier, E_{} [eV]'.format(i) for i in range(5, 7) ] df_E = df[['Solute element name'] + columns_E] df_E.columns = ['El.'] + [ 'E{} [eV]'.format(i) for i in ['₂', '₃', '₄'] ] + ['E`{} [eV]'.format(i) for i in ['₃', '₄']] + [ 'E``{} [eV]'.format(i) for i in ['₃', '₄'] ] + ['E{} [eV]'.format(i) for i in ['₅', '₆']] mpfile.add_data_table(mpid, df_E, 'hop_activation_barriers') print 'add table for hop attempt frequencies for {} (BCC)'.format( mpid) columns_v = [ 'Hop attempt frequency, v_{} [THz]'.format(i) for i in range(2, 5) ] + [ "Hop attempt frequency, v'_{} [THz]".format(i) for i in range(3, 5) ] + [ "Hop attempt frequency, v''_{} [THz]".format(i) for i in range(3, 5) ] + [ 'Hop attempt frequency, v_{} [THz]'.format(i) for i in range(5, 7) ] df_v = df[['Solute element name'] + columns_v] df_v.columns = ['El.'] + [ 'v{} [THz]'.format(i) for i in ['₂', '₃', '₄'] ] + ['v``{} [THz]'.format(i) for i in ['₃', '₄']] + [ 'v``{} [THz]'.format(i) for i in ['₃', '₄'] ] + ['v{} [THz]'.format(i) for i in ['₅', '₆']] mpfile.add_data_table(mpid, df_v, 'hop_attempt_frequencies') elif hdata['Host']['crystal_structure'] == 'FCC': print 'add table for hop activation barriers for {} (FCC)'.format( mpid) columns_E = [ 'Hop activation barrier, E_{} [eV]'.format(i) for i in range(5) ] df_E = df[['Solute element name'] + columns_E] df_E.columns = ['El.'] + [ 'E{} [eV]'.format(i) for i in ['₀', '₁', '₂', '₃', '₄'] ] mpfile.add_data_table(mpid, df_E, 'hop_activation_barriers') print 'add table for hop attempt frequencies for {} (FCC)'.format( mpid) columns_v = [ 'Hop attempt frequency, v_{} [THz]'.format(i) for i in range(5) ] df_v = df[['Solute element name'] + columns_v] df_v.columns = ['El.'] + [ 'v{} [THz]'.format(i) for i in ['₀', '₁', '₂', '₃', '₄'] ] mpfile.add_data_table(mpid, df_v, 'hop_attempt_frequencies') elif hdata['Host']['crystal_structure'] == 'HCP': print 'add table for hop activation barriers for {} (HCP)'.format( mpid) columns_E = [ "Hop activation barrier, E_X [eV]", "Hop activation barrier, E'_X [eV]", "Hop activation barrier, E_a [eV]", "Hop activation barrier, E'_a [eV]", "Hop activation barrier, E_b [eV]", "Hop activation barrier, E'_b [eV]", "Hop activation barrier, E_c [eV]", "Hop activation barrier, E'_c [eV]" ] df_E = df[['Solute element name'] + columns_E] df_E.columns = ['El.'] + [ 'Eₓ [eV]', 'E`ₓ [eV]', 'Eₐ [eV]', 'E`ₐ [eV]', 'E_b [eV]', 'E`_b [eV]', 'Eꪱ [eV]', 'E`ꪱ [eV]' ] mpfile.add_data_table(mpid, df_E, 'hop_activation_barriers') print 'add table for hop attempt frequencies for {} (HCP)'.format( mpid) columns_v = ['Hop attempt frequency, v_a [THz]' ] + ['Hop attempt frequency, v_X [THz]'] df_v = df[['Solute element name'] + columns_v] df_v.columns = ['El.'] + ['vₐ [THz]'] + ['vₓ [THz]'] mpfile.add_data_table(mpid, df_v, 'hop_attempt_frequencies') print mpfile print 'DONE'
class SurfaceEnergyAnalyzer(object): """ A class used for analyzing the surface energies of a material of a given material_id. By default, this will use entries calculated from the Materials Project to obtain chemical potential and bulk energy. As a result, the difference in VASP parameters between the user's entry (vasprun_dict) and the parameters used by Materials Project, may lead to a rough estimate of the surface energy. For best results, it is recommend that the user calculates all decomposition components first, and insert the results into their own database as a pymatgen-db entry and use those entries instead (custom_entries). In addition, this code will only use one bulk entry to calculate surface energy. Ideally, to get the most accurate surface energy, the user should compare their slab energy to the energy of the oriented unit cell with both calculations containing consistent k-points to avoid converegence problems as the slab size is varied. See: Sun, W.; Ceder, G. Efficient creation and convergence of surface slabs, Surface Science, 2013, 617, 53–59, doi:10.1016/j.susc.2013.05.016. and Rogal, J., & Reuter, K. (2007). Ab Initio Atomistic Thermodynamics for Surfaces : A Primer. Experiment, Modeling and Simulation of Gas-Surface Interactions for Reactive Flows in Hypersonic Flights, 2–1 – 2–18. .. attribute:: ref_element All chemical potentials cna be written in terms of the range of chemical potential of this element which will be used to calculate surface energy. .. attribute:: mprester Materials project rester for querying entries from the materials project. Requires user MAPIKEY. .. attribute:: ucell_entry Materials Project entry of the material of the slab. .. attribute:: x Reduced amount composition of decomposed compound A in the bulk. .. attribute:: y Reduced amount composition of ref_element in the bulk. .. attribute:: gbulk Gibbs free energy of the bulk per formula unit .. attribute:: chempot_range List of the min and max chemical potential of ref_element. .. attribute:: e_of_element Energy per atom of ground state ref_element, eg. if ref_element=O, than e_of_element=1/2*E_O2. .. attribute:: vasprun_dict Dictionary containing a list of Vaspruns for slab calculations as items and the corresponding Miller index of the slab as the key """ def __init__(self, material_id, vasprun_dict, ref_element, exclude_ids=[], custom_entries=[], mapi_key=None): """ Analyzes surface energies and Wulff shape of a particular material using the chemical potential. Args: material_id (str): Materials Project material_id (a string, e.g., mp-1234). vasprun_dict (dict): Dictionary containing a list of Vaspruns for slab calculations as items and the corresponding Miller index of the slab as the key. eg. vasprun_dict = {(1,1,1): [vasprun_111_1, vasprun_111_2, vasprun_111_3], (1,1,0): [vasprun_111_1, vasprun_111_2], ...} element: element to be considered as independent variables. E.g., if you want to show the stability ranges of all Li-Co-O phases wrt to uLi exclude_ids (list of material_ids): List of material_ids to exclude when obtaining the decomposition components to calculate the chemical potential custom_entries (list of pymatgen-db type entries): List of user specified pymatgen-db type entries to use in finding decomposition components for the chemical potential mapi_key (str): Materials Project API key for accessing the MP database via MPRester """ self.ref_element = ref_element self.mprester = MPRester(mapi_key) if mapi_key else MPRester() self.ucell_entry = \ self.mprester.get_entry_by_material_id(material_id, inc_structure=True, property_data= ["formation_energy_per_atom"]) ucell = self.ucell_entry.structure # Get x and y, the number of species in a formula unit of the bulk reduced_comp = ucell.composition.reduced_composition.as_dict() if len(reduced_comp.keys()) == 1: x = y = reduced_comp[ucell[0].species_string] else: for el in reduced_comp.keys(): if self.ref_element == el: y = reduced_comp[el] else: x = reduced_comp[el] # Calculate Gibbs free energy of the bulk per unit formula gbulk = self.ucell_entry.energy /\ (len([site for site in ucell if site.species_string == self.ref_element]) / y) entries = [entry for entry in self.mprester.get_entries_in_chemsys(list(reduced_comp.keys()), property_data=["e_above_hull", "material_id"]) if entry.data["e_above_hull"] == 0 and entry.data["material_id"] not in exclude_ids] \ if not custom_entries else custom_entries pd = PhaseDiagram(entries) chempot_ranges = pd.get_chempot_range_map([Element(self.ref_element)]) # If no chemical potential is found, we return u=0, eg. # for a elemental system, the relative u of Cu for Cu is 0 chempot_range = [chempot_ranges[entry] for entry in chempot_ranges.keys() if entry.composition == self.ucell_entry.composition][0][0]._coords if \ chempot_ranges else [[0,0], [0,0]] e_of_element = [entry.energy_per_atom for entry in entries if str(entry.composition.reduced_composition) == self.ref_element + "1"][0] self.x = x self.y = y self.gbulk = gbulk chempot_range = list(chempot_range) self.chempot_range = sorted([chempot_range[0][0], chempot_range[1][0]]) self.e_of_element = e_of_element self.vasprun_dict = vasprun_dict def calculate_gamma(self, vasprun): """ Calculates the surface energy for a single slab. Args: vasprun (Vasprun): A Vasprun object Returns (list): The surface energy for the minimum/maximun chemical potential and the second list gives the range of the chemical potential """ reduced_comp = self.ucell_entry.composition.reduced_composition.as_dict() # Get the composition in the slab slab = vasprun.final_structure comp = slab.composition.as_dict() if len(reduced_comp.keys()) == 1: Ny = comp[self.ucell_entry.structure[0].species_string] Nx = Ny else: for el in reduced_comp.keys(): if self.ref_element == el: Ny = comp[el] else: Nx = comp[el] # Calculate surface area m = slab.lattice.matrix A = np.linalg.norm(np.cross(m[0], m[1])) # calculate the surface energy for the max and min chemical potential return [(1 / (2 * A)) * (vasprun.final_energy - (Nx / self.x) * self.gbulk - (Ny - (self.y / self.x) * Nx) * (delu + self.e_of_element)) for delu in self.chempot_range] def wulff_shape_from_chempot(self, chempot, symprec=1e-5): """ Method to get the Wulff shape at a specific chemical potential. Args: chempot (float): The chemical potential the Wulff Shape exist in. """ # Check if the user provided chemical potential is within the # predetermine range of chemical potential. If not, raise a warning if not max(self.chempot_range) >= chempot >= min(self.chempot_range): warnings.warn("The provided chemical potential is outside the range " "of chemical potential (%s to %s). The resulting Wulff " "shape might not be reasonable." %(min(self.chempot_range), max(self.chempot_range))) latt = SpacegroupAnalyzer(self.ucell_entry.structure).\ get_conventional_standard_structure().lattice miller_list = self.vasprun_dict.keys() e_surf_list = [] for hkl in miller_list: # At each possible configuration, we calculate surface energy as a # function of u and take the lowest surface energy (corresponds to # the most stable slab termination at that particular u) surf_e_range_list = [self.calculate_gamma(vasprun) for vasprun in self.vasprun_dict[hkl]] e_list = [] for e_range in surf_e_range_list: slope, intercept = self.get_slope_and_intercept(e_range) e_list.append(slope * chempot + intercept) e_surf_list.append(min(e_list)) return WulffShape(latt, miller_list, e_surf_list, symprec=symprec) def wulff_shape_dict(self, symprec=1e-5, at_intersections=False): """ As the surface energy is a function of chemical potential, so too is the Wulff shape. This methods generates a dictionary of Wulff shapes at certain chemical potentials where a facet goes through a transition. Returns a dict, eg. {chempot1: WulffShape1, chempot2: WulffShape2} Args: symprec (float): for recp_operation, default is 1e-5. at_intersections (bool): Whether to generate a Wulff shape for each intersection of surface energy for a specific facet (eg. at the point where a (111) stoichiometric surface energy plot intersects with the (111) nonstoichiometric plot) or to just generate two Wulff shapes, one at the min and max chemical potential. """ # First lets get the Wulff shape at the # minimum and maximum chemical potential wulff_dict = {self.chempot_range[0]: \ self.wulff_shape_from_chempot(self.chempot_range[0], symprec=symprec), self.chempot_range[1]: \ self.wulff_shape_from_chempot(self.chempot_range[1], symprec=symprec)} # Now we get the Wulff shape each time a facet changes its configuration # (ie, adsorption coverage, stoichiometric to nonstoichiometric, etc) if at_intersections: # Get all values of chemical potential where an intersection occurs u_at_intersection = [self.get_intersections(hkl)[0] for hkl in self.vasprun_dict.keys() if self.get_intersections(hkl)] # Get a Wulff shape for each intersection. The change in the Wulff shape # will vary if the rate of change in surface energy for any facet changes for u in u_at_intersection: wulff_dict[u] = self.wulff_shape_from_chempot(u, symprec=symprec) return wulff_dict def get_slope_and_intercept(self, surf_e_pair): """ Returns the slope and intercept of the surface energy vs chemical potential line Args: surf_e_pair ([e_at_min_u, e_at_max_u]): The surface energy at the minimum chemical potential and maximum chemical potential """ slope, intercept, r_value, p_value, std_err = \ linregress(self.chempot_range, surf_e_pair) slope = 0 if str(slope) == 'nan' else slope intercept = surf_e_pair[0] if str(intercept) == 'nan' else intercept return slope, intercept def get_intersections(self, miller_index): """ Returns a all intersections for a specific facet. Useful for finding when the configuration of a particular facet changes. Args: miller_index ((h, k, l)): Miller index of the facet we are interested in """ # First lets calculate the range of surface # energies for all terminations of a specific facet all_se_ranges = [self.calculate_gamma(vasprun) for vasprun in self.vasprun_dict[miller_index]] if len(all_se_ranges) == 1: return [] # Now get all possible intersection coordinates for each pair of lines intersections = [] for pair_ranges in itertools.combinations(all_se_ranges, 2): slope1, intercept1 = self.get_slope_and_intercept(pair_ranges[0]) slope2, intercept2 = self.get_slope_and_intercept(pair_ranges[1]) # Calculate the intersection coordinates u = (intercept1-intercept2)/(slope2-slope1) # if the intersection is beyond the chemical potential # range or if the lines are parallel, we ignore it if slope1-slope2 == 0 or u < min(self.chempot_range) \ or u > max(self.chempot_range): continue intersections.append([u, slope1 * u + intercept1]) return sorted(intersections, key=lambda ints: ints[0]) def area_frac_vs_chempot_plot(self, cmap=cm.jet, at_intersections=False, increments=10): """ Plots the change in the area contribution of each facet as a function of chemical potential. Args: cmap (cm): A matplotlib colormap object, defaults to jet. at_intersections (bool): Whether to generate a Wulff shape for each intersection of surface energy for a specific facet (eg. at the point where a (111) stoichiometric surface energy plot intersects with the (111) nonstoichiometric plot) or to just generate two Wulff shapes, one at the min and max chemical potential. increments (bool): Number of data points between min/max or point of intersection. Defaults to 5 points. """ # Choose unique colors for each facet f = [int(i) for i in np.linspace(0, 255, len(self.vasprun_dict.keys()))] # Get all points of min/max chempot and intersections chempot_intersections = [] chempot_intersections.extend(self.chempot_range) for hkl in self.vasprun_dict.keys(): chempot_intersections.extend([ints[0] for ints in self.get_intersections(hkl)]) chempot_intersections = sorted(chempot_intersections) # Get all chempots if at_intersections: all_chempots = [] for i, intersection in enumerate(chempot_intersections): if i < len(chempot_intersections)-1: all_chempots.extend(np.linspace(intersection, chempot_intersections[i+1], increments)) else: all_chempots = np.linspace(min(self.chempot_range), max(self.chempot_range), increments) # initialize a dictionary of lists of fractional areas for each hkl hkl_area_dict = {} for hkl in self.vasprun_dict.keys(): hkl_area_dict[hkl] = [] # Get plot points for each Miller index for u in all_chempots: wulffshape = self.wulff_shape_from_chempot(u) for hkl in wulffshape.area_fraction_dict.keys(): hkl_area_dict[hkl].append(wulffshape.area_fraction_dict[hkl]) # Plot the area fraction vs chemical potential for each facet plt = pretty_plot() for i, hkl in enumerate(self.vasprun_dict.keys()): # Ignore any facets that never show up on the # Wulff shape regardless of chemical potential if all([a == 0 for a in hkl_area_dict[hkl]]): continue else: plt.plot(all_chempots, hkl_area_dict[hkl], '--', color=cmap(f[i]), label=str(hkl)) # Make the figure look nice plt.ylim([0,1]) plt.xlim(self.chempot_range) plt.ylabel(r"Fractional area $A^{Wulff}_{hkl}/A^{Wulff}$") plt.xlabel(r"Chemical potential $\Delta\mu_{%s}$ (eV)" %(self.ref_element)) plt.legend(bbox_to_anchor=(1.01, 1), loc=2, borderaxespad=0.) return plt def chempot_vs_gamma_plot(self, cmap=cm.jet, show_unstable_points=False): """ Plots the surface energy of all facets as a function of chemical potential. Each facet will be associated with its own distinct colors. Dashed lines will represent stoichiometries different from that of the mpid's compound. Args: cmap (cm): A matplotlib colormap object, defaults to jet. show_unstable_points (bool): For each facet, there may be various terminations or stoichiometries and the relative stability of these different slabs may change with chemical potential. This option will only plot the most stable surface energy for a given chemical potential. """ plt = pretty_plot() # Choose unique colors for each facet f = [int(i) for i in np.linspace(0, 255, sum([len(vaspruns) for vaspruns in self.vasprun_dict.values()]))] i, already_labelled, colors = 0, [], [] for hkl in self.vasprun_dict.keys(): for vasprun in self.vasprun_dict[hkl]: slab = vasprun.final_structure # Generate a label for the type of slab label = str(hkl) # use dashed lines for slabs that are not stoichiometric # wrt bulk. Label with formula if nonstoichiometric if slab.composition.reduced_composition != \ self.ucell_entry.composition.reduced_composition: mark = '--' label += " %s" % (slab.composition.reduced_composition) else: mark = '-' # label the chemical environment at the surface if different from the bulk. # First get the surface sites, then get the reduced composition at the surface # s = vasprun.final_structure # ucell = SpacegroupAnalyzer(self.ucell_entry.structure).\ # get_conventional_standard_structure() # slab = Slab(s.lattice, s.species, s.frac_coords, hkl, ucell, 0, None) # surf_comp = slab.surface_composition() # # if surf_comp.reduced_composition != ucell.composition.reduced_composition: # label += " %s" %(surf_comp.reduced_composition) if label in already_labelled: c = colors[already_labelled.index(label)] label = None else: already_labelled.append(label) c = cmap(f[i]) colors.append(c) se_range = self.calculate_gamma(vasprun) plt.plot(self.chempot_range, se_range, mark, color=c, label=label) i += 1 # Make the figure look nice axes = plt.gca() ylim = axes.get_ylim() plt.ylim(ylim) plt.xlim(self.chempot_range) plt.ylabel(r"Surface energy (eV/$\AA$)") plt.xlabel(r"Chemical potential $\Delta\mu_{%s}$ (eV)" %(self.ref_element)) plt.legend(bbox_to_anchor=(1.01, 1), loc=2, borderaxespad=0.) return plt def broken_bond_vs_gamma(self): return
MessageBody( dcc.Markdown( "This is a pre-release version of Crystal Toolkit and " "may not behave reliably. Please visit " "[https://viewer.materialsproject.org](https://viewer.materialsproject.org) " "for a stable version.")), ], kind="warning", ), ], id="banner", ) api_offline, api_error = True, "Unknown error connecting to Materials Project API." try: with MPRester() as mpr: api_check = mpr._make_request("/api_check") if not api_check.get("api_key_valid", False): api_error = ("Materials Project API key not supplied or not valid, " "please set PMG_MAPI_KEY in your environment.") else: api_offline = False except Exception as exception: api_error = str(exception) if api_offline: banner = html.Div( [ html.Br(), MessageContainer( [ MessageHeader(
import numpy as np from pandas.tools.plotting import scatter_matrix from pymatgen import Composition, Element, MPRester, periodic_table from sklearn import linear_model, cross_validation, metrics, ensemble import pandas as pd import matplotlib.pyplot as plt import itertools # matplotlib.style.use('ggplot') #binaries_data = np.array df = pd.DataFrame() allBinaries = itertools.combinations(periodic_table.all_symbols(), 2) # Create list of all binary systems with MPRester() as m: for system in allBinaries: results = m.get_data(system[0] + '-' + system[1],data_type='vasp')# Download DFT data for each binary system for material in results: # We will receive many compounds within each binary system if material['e_above_hull'] < 1e-6: # Check if this compound is thermodynamically stable dat = [] dat.append(material['pretty_formula']) dat.append(material['band_gap']) dat.append(material['formation_energy_per_atom']) dat.append(material['density']) df = df.append(pd.Series(dat), ignore_index=True) df.columns = ['materials', 'bandgaps','formenergies','densities'] #df = pd.DataFrame(binaries_data) #df = pd.read_csv('bandgap_energy_densityDFT.csv', header=None, names=['materials', 'bandgaps','formenergies','densities']) print df[0:2] print df.columns
class MPDataRetrieval(BaseDataRetrieval): """ Retrieves data from the Materials Project database. If you use this data retrieval class, please additionally cite: Ong, S.P., Cholia, S., Jain, A., Brafman, M., Gunter, D., Ceder, G., Persson, K.A., 2015. The Materials Application Programming Interface (API): A simple, flexible and efficient API for materials data based on REpresentational State Transfer (REST) principles. Computational Materials Science 97, 209–215. https://doi.org/10.1016/j.commatsci.2014.10.037 """ def __init__(self, api_key=None): """ Args: api_key: (str) Your Materials Project API key, or None if you've set up your pymatgen config. """ self.mprester = MPRester(api_key=api_key) def api_link(self): return "https://materialsproject.org/wiki/index.php/The_Materials_API" def get_dataframe(self, criteria, properties, index_mpid=True, **kwargs): """ Gets data from MP in a dataframe format. See api_link for more details. Args: criteria (dict): the same as in get_data properties ([str]): the same properties supported as in get_data plus: "structure", "initial_structure", "final_structure", "bandstructure" (line mode), "bandstructure_uniform", "phonon_bandstructure", "phonon_ddb", "phonon_bandstructure", "phonon_dos". Note that for a long list of compounds, it may take a long time to retrieve some of these objects. index_mpid (bool): the same as in get_data kwargs (dict): the same keyword arguments as in get_data Returns (pandas.Dataframe): """ data = self.get_data(criteria=criteria, properties=properties, index_mpid=index_mpid, **kwargs) df = pd.DataFrame(data, columns=properties) for prop in [ "dos", "phonon_dos", "phonon_bandstructure", "phonon_ddb" ]: if prop in properties: df[prop] = self.try_get_prop_by_material_id( prop=prop, material_id_list=df["material_id"].values) if "bandstructure" in properties: df["bandstructure"] = self.try_get_prop_by_material_id( prop="bandstructure", material_id_list=df["material_id"].values, line_mode=True) if "bandstructure_uniform" in properties: df["bandstructure_uniform"] = self.try_get_prop_by_material_id( prop="bandstructure", material_id_list=df["material_id"].values, line_mode=False) if index_mpid: df = df.set_index("material_id") return df def get_data(self, criteria, properties, mp_decode=False, index_mpid=True): """ Args: criteria: (str/dict) see MPRester.query() for a description of this parameter. String examples: "mp-1234", "Fe2O3", "Li-Fe-O', "\\*2O3". Dict example: {"band_gap": {"$gt": 1}} properties: (list) see MPRester.query() for a description of this parameter. Example: ["formula", "formation_energy_per_atom"] mp_decode: (bool) see MPRester.query() for a description of this parameter. Whether to decode to a Pymatgen object where possible. index_mpid: (bool) Whether to set the materials_id as the dataframe index. Returns ([dict]): a list of jsons that match the criteria and contain properties """ if index_mpid and "material_id" not in properties: properties.append("material_id") data = self.mprester.query(criteria, properties, mp_decode) return data def try_get_prop_by_material_id(self, prop, material_id_list, **kwargs): """ Call the relevant get_prop_by_material_id. "prop" is a property such as bandstructure that is not readily available in supported properties of the get_data function but via the get_bandstructure_by_material_id method for example. Args: prop (str): the name of the property. Options are: "bandstructure", "dos", "phonon_dos", "phonon_bandstructure", "phonon_ddb" material_id_list ([str]): list of material_id of compounds kwargs (dict): other keyword arguments that get_*_by_material_id may have; e.g. line_mode in get_bandstructure_by_material_id Returns ([target prop object or NaN]): If the target property is not available for a certain material_id, NaN is returned. """ method = getattr(self.mprester, "get_{}_by_material_id".format(prop)) props = [] for material_id in material_id_list: try: props.append(method(material_id=material_id, **kwargs)) except MPRestError: props.append(float('NaN')) return props
from pymatgen import MPRester import urllib.request import json import csv if __name__ == "__main__": MAPI_KEY = "zQIrujyVEwEhTBRW" # You must change this to your Materials API key! (or set MAPI_KEY env variable) # fetch list of a list of all available materials with urllib.request.urlopen( 'https://www.materialsproject.org/rest/v1/materials//mids' ) as myurl: data = json.loads(myurl.read().decode()) material_ids = data['response'] # 75,000'ish material IDs are returned with MPRester(MAPI_KEY) as m: # object for connecting to MP Rest interface criteria = { 'material_id': { '$in': material_ids[:] } } # to avoid straining the servers, this is only using the first 4 materials properties = ['energy', 'pretty_formula'] # list a few quanteties of interest data = m.query(criteria, properties) print(data[:100]) keys = data[0].keys() with open('first_dataset.csv', 'w') as output_file: dict_writer = csv.DictWriter(output_file, keys) dict_writer.writeheader() dict_writer.writerows(data)
############################################################################### def createFolder(directory): try: if not os.path.exists(directory): os.makedirs(directory) except OSError: print('Error: Creating directory. ' + directory) ############################################################################### load_dotenv('.env') MATERIAL_API_KEY = os.getenv('MATERIAL_API_KEY') mpr = MPRester(MATERIAL_API_KEY) mpid_list = [] with open('mpid_list.csv', 'r') as f: reader = csv.reader(f, delimiter=',') for line in reader: mpid = line[0] mpid_list.append(mpid) len(mpid_list) # 243 ############################################################################### entries_from_list = mpr.query(criteria={"material_id": { "$in": mpid_list }}, properties=["pretty_formula", "e_above_hull"])
def mpr_query(criteria, properties): with MPRester() as mpr: entries = mpr.query(criteria=criteria, properties=properties) return entries
from pymatgen import MPRester import matplotlib.pyplot as plt import matplotlib.cm as cm import matplotlib.colors as color import matplotlib.backends.backend_pdf import numpy as np pdf = matplotlib.backends.backend_pdf.PdfPages( "tracage-proprietes-avecPoisson-HYPO.pdf") api = MPRester("eDCEK5m9WVjmajp7e8af") compos = ['S', 'O'] covalent = ['B', 'C', 'Si'] ionique = ['N', 'O', 'F', 'P', 'S', 'Cl', 'Se', 'Br', 'I'] alkali = ['Li', 'Na', 'K', 'Rb', 'Cs', 'Fr'] alkaline = ['Be', 'Mg', 'Ca', 'Sr', 'Ba', 'Ra'] chalcogen = ['O', 'S', 'Se', 'Te', 'Po'] metalloid = ['B', 'Si', 'Ge', 'As', 'Sb', 'Te', 'Po'] # Proprietes utilisees dans la requete propsTableauCritere = [ 'pretty_formula', 'elasticity.poisson_ratio', 'elasticity.G_Reuss', 'elasticity.G_Voigt', 'elasticity.G_Voigt_Reuss_Hill', 'elasticity.K_Reuss', 'elasticity.K_Voigt', 'elasticity.K_Voigt_Reuss_Hill' ] # Proprietes utilisees dans la generation du tableau propsTableau = [ 'elasticity.poisson_ratio', 'elasticity.G_Reuss', 'elasticity.G_Voigt', 'elasticity.G_Voigt_Reuss_Hill', 'elasticity.K_Reuss', 'elasticity.K_Voigt', 'elasticity.K_Voigt_Reuss_Hill'
def plot_band_structure(mpid, band_index, width, k_highlight, pattern): """ - Plots two bands (which one is indicated by band_index) - Highlights a window of width `width` at k `k_highlight` """ mpr = MPRester('4JzM8sNnMkyVJceK') bs = mpr.get_bandstructure_by_material_id(mpid) dos = mpr.get_dos_by_material_id(mpid) kpoints = pymatgen.Kpoints(bs) doscar = pymatgen.Doscar(dos) fermi_energy = doscar.fermi_energy eigenval = pymatgen.Eigenval(bs, fermi_energy) bands = eigenval.spin_up lower_fermi_band_index = np.argmax(np.nanmax(bands, axis=1) > 0) - 1 """ segment_sizes = kpoints.segment_sizes segmented_lower_band = np.split(bands[lower_fermi_band_index+band_index], np.cumsum(segment_sizes))[:-1] segmented_upper_band = np.split(bands[lower_fermi_band_index+band_index+1], np.cumsum(segment_sizes))[:-1] segmented_kpoints = np.split(eigenval.k_points, np.cumsum(segment_sizes))[:-1] last_k = 0 """ k = eigenval.k_points band_l = bands[lower_fermi_band_index + band_index] band_u = bands[lower_fermi_band_index + band_index + 1] #for k, band_l, band_u in zip(segmented_kpoints, segmented_lower_band, segmented_upper_band): #k_1D = np.array(path_1D(k)) + last_k k_1D = np.array(path_1D(k)) plt.plot(k_1D, band_l, 'k') plt.plot(k_1D, band_u, 'k') #last_k = np.max(k_1D) plt.axvspan(float(k_highlight), float(k_highlight) + width, color='red', alpha=0.5) # Collect axis ticks (high symmetry points) from KPOINTS.gz last_k = 0 label_k = [] label_names = [] #NOTE: Labels for none are question marks for left_k, right_k in pymatgen.chunks(kpoints.k_points, 2): if len(label_names) == 0: label_k.append(last_k) #label_names.append(left_k[0]) #elif label_names[-1] != left_k[0]: #label_names[-1] += (';' + left_k[0]) last_k += np.linalg.norm(right_k[1] - left_k[1]) label_k.append(last_k) #label_names.append(right_k[0]) #plt.xticks(label_k, label_names) #plt.xticks(label_k) plt.ylabel('Energy') plt.xlabel('k') plt.grid(True) plt.title('material ' + mpid) plt.savefig('misc/' + pattern + '_search_result.png') plt.show()
return [phases] if __name__ == "__main__": MAPI_KEY = config.KEY[ "key"] # You must change this to your Materials API key! (or set MAPI_KEY env variable) system = ["Li", "B", "O"] # system we want to get open PD for # system = ["Li", "Fe", "P", "O"] # alternate system example open_elements_specific = None # e.g., {Element("O"): 0} where 0 is the specific chemical potential open_element_all = Element( "O" ) # plot a series of open phase diagrams at critical chem pots with this element open mpr = MPRester(MAPI_KEY) # object for connecting to MP Rest interface # get data entries = mpr.get_entries_in_chemsys(system, compatible_only=True) if open_elements_specific: gcpd = GrandPotentialPhaseDiagram(entries, open_elements_specific) plot_pd(gcpd, False) analyze_pd(gcpd) if open_element_all: pd = PhaseDiagram(entries) chempots = pd.get_transition_chempots(open_element_all) all_gcpds = list() toplot = [] arquivo = open("dados.txt", "w")
#!/usr/bin/env python # coding: utf-8 from pymatgen import MPRester import pandas as pd from ase.data import atomic_numbers, chemical_symbols #Read the task ids of single element reference df_ref = pd.read_excel("Ref_atoms_taskid.xlsx") ref_ids = df_ref["task_id"].tolist() #Get property values of single element reference with MPRester("1ZEWhG2nVio5ykmM") as mpr: data_ref = mpr.query(criteria={"task_id": { "$in": ref_ids }}, properties=[ "task_id", "formula", "density", "spacegroup.number", "band_gap.search_gap.band_gap", "magnetism.total_magnetization_normalized_vol", "e_above_hull", "final_energy_per_atom" ]) #Transfer property values of single element reference to database df_ref_data = pd.DataFrame(data_ref) df_ref_data = df_ref_data.sort_values(by=['task_id']) df_ref = df_ref.sort_values(by=['task_id']) dref_final = pd.merge(df_ref, df_ref_data, on="task_id") #dref_final.to_excel("output_ref_final.xlsx")
# ######################################################### # from dft_energies import ion_dict_solids_expt #__| # + # | - Script Inputs #This initializes the REST adaptor. Put your own API key in. path_i = os.path.join(os.environ["PROJ_irox"], "config", "config.yml") with open(path_i) as file: config_dict = yaml.load(file, Loader=yaml.FullLoader) api_key = config_dict["materials_project"]["api_key"] mpr = MPRester(api_key) # Raul #__| # - entries = mpr.get_pourbaix_entries( [ "Ir", ] ) entry = entries[0] entry.uncorrected_energy # entry # Pourbaix Entry : Ir1 O4 with energy = 7.4405, npH = -8.0, nPhi = -7.0, nH2O = 4.0, entry_id = None
def __init__(self, material_id, vasprun_dict, ref_element, exclude_ids=[], custom_entries=[], mapi_key=None): """ Analyzes surface energies and Wulff shape of a particular material using the chemical potential. Args: material_id (str): Materials Project material_id (a string, e.g., mp-1234). vasprun_dict (dict): Dictionary containing a list of Vaspruns for slab calculations as items and the corresponding Miller index of the slab as the key. eg. vasprun_dict = {(1,1,1): [vasprun_111_1, vasprun_111_2, vasprun_111_3], (1,1,0): [vasprun_111_1, vasprun_111_2], ...} element: element to be considered as independent variables. E.g., if you want to show the stability ranges of all Li-Co-O phases wrt to uLi exclude_ids (list of material_ids): List of material_ids to exclude when obtaining the decomposition components to calculate the chemical potential custom_entries (list of pymatgen-db type entries): List of user specified pymatgen-db type entries to use in finding decomposition components for the chemical potential mapi_key (str): Materials Project API key for accessing the MP database via MPRester """ self.ref_element = ref_element self.mprester = MPRester(mapi_key) if mapi_key else MPRester() self.ucell_entry = \ self.mprester.get_entry_by_material_id(material_id, inc_structure=True, property_data= ["formation_energy_per_atom"]) ucell = self.ucell_entry.structure # Get x and y, the number of species in a formula unit of the bulk reduced_comp = ucell.composition.reduced_composition.as_dict() if len(reduced_comp.keys()) == 1: x = y = reduced_comp[ucell[0].species_string] else: for el in reduced_comp.keys(): if self.ref_element == el: y = reduced_comp[el] else: x = reduced_comp[el] # Calculate Gibbs free energy of the bulk per unit formula gbulk = self.ucell_entry.energy /\ (len([site for site in ucell if site.species_string == self.ref_element]) / y) entries = [entry for entry in self.mprester.get_entries_in_chemsys(list(reduced_comp.keys()), property_data=["e_above_hull", "material_id"]) if entry.data["e_above_hull"] == 0 and entry.data["material_id"] not in exclude_ids] \ if not custom_entries else custom_entries pd = PhaseDiagram(entries) chempot_ranges = pd.get_chempot_range_map([Element(self.ref_element)]) # If no chemical potential is found, we return u=0, eg. # for a elemental system, the relative u of Cu for Cu is 0 chempot_range = [chempot_ranges[entry] for entry in chempot_ranges.keys() if entry.composition == self.ucell_entry.composition][0][0]._coords if \ chempot_ranges else [[0,0], [0,0]] e_of_element = [entry.energy_per_atom for entry in entries if str(entry.composition.reduced_composition) == self.ref_element + "1"][0] self.x = x self.y = y self.gbulk = gbulk chempot_range = list(chempot_range) self.chempot_range = sorted([chempot_range[0][0], chempot_range[1][0]]) self.e_of_element = e_of_element self.vasprun_dict = vasprun_dict
def get_formula(x, y, z): formula = [] for ix in x: for iy in y: for iz in z: formula.append([ix, iy, iz]) return formula #comps = get_formula(M, A, X) comps = [['Mg', 'Al', 'O']] f = open('in.txt', 'w') fcsv = open('id_prop.csv', 'w') mpr = MPRester("7UnVyVXyetJ5WK3r") for comp in comps: print(comp) try: entries = mpr.get_entries_in_chemsys(comp) except: continue if len(entries) == 0: continue # pd = PhaseDiagram(entries) # data = collections.defaultdict(list) for e in entries: #print(e) #print(type(e)) #print(e.energy)
class MaterialsEhullBuilder: 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): print("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) self._materials.update_one({"material_id": m["material_id"]}, {"$set": {"stability": self.mpr.get_stability([my_entry])[0]}}) mpids = self.mpr.find_structure(structure) self._materials.update_one({"material_id": m["material_id"]}, {"$set": {"mpids": mpids}}) except: import traceback print("<---") print("There was an error processing material_id: {}".format(m)) traceback.print_exc() print("--->") print("MaterialsEhullBuilder finished processing.") def reset(self): self._materials.update_many({}, {"$unset": {"stability": 1}}) self._build_indexes() def _build_indexes(self): self._materials.create_index("stability.e_above_hull") @staticmethod def from_db_file(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 MaterialsEhullBuilder(db_write[m], **kwargs)
from pymatgen import MPRester from pprint import pprint with MPRester("iUCzg5aBMJ1w30KT") as mpr: data = mpr.query(criteria={}, properties=[ "pretty_formula", "material_id", "e_above_hull", "spacegroup", "band_gap" ]) all_names = [d['pretty_formula'] for d in data] print('retrieval complete') chem_formulas = [] PC_mats = [] for index, a in enumerate(all_names): if all_names.count(a) > 1: PC_mats.append([ data[index]['material_id'], data[index]['pretty_formula'], data[index]['e_above_hull'], data[index]['spacegroup']['symbol'], data[index]['band_gap'] ]) chem_formulas.append([ data[index]['material_id'], data[index]['pretty_formula'], data[index]['e_above_hull'], data[index]['spacegroup']['symbol'], data[index]['band_gap'] ]) PC_mats = sorted(PC_mats, key=lambda x: (x[1])) print('PC_mats is now sorted') other_half = [] placeholderred_pc_mats = [] object = []
import pymongo from pymatgen import MPRester, Composition, Structure from pymatgen.matproj.snl import StructureNL client = pymongo.MongoClient() db = client.springer mpr = MPRester() def create_mincoll(): origcoll = db['pauling_file'] min_collname = 'pauling_file_mpmin' db[min_collname].drop() origcoll.aggregate([{'$match': {'structure': {'$exists': True}, 'metadata._structure.is_ordered': True, 'metadata._structure.is_valid': True, 'errors': { '$nin': ['structural composition and refined/alphabetic formula do not match']}}}, {'$project': {'key': 1, 'metadata': 1, 'structure': 1, 'webpage_link': 1}}, {'$out': min_collname}]) db[min_collname].create_index([('key', pymongo.ASCENDING)], unique=True) # Remove Deuterium for doc in db[min_collname].find().batch_size(75): for el in doc['metadata']['_structure']['elements']: if el == 'D': db[min_collname].remove({'key': doc['key']}) break def get_meta_from_structure(structure): """ Used by `structure_to_mock_job`, to "fill out" a job document. :param structure: pymatgen structure object
from pymatgen import MPRester from pymatgen.io.cif import CifWriter import csv import os import json import math if __name__ == "__main__": MAPI_KEY = "h9GBsMfA1JvXbC7n" # You must change this to your Materials API key! (or set MAPI_KEY env variable) QUERY = "mp-1180346" # change this to the mp-id of your compound of interest # QUERY = "TiO" # change this to a formula of interest # QUERY = "Ti-O" # change this to a chemical system of interest mpr = MPRester(MAPI_KEY) # object for connecting to MP Rest interface # all information 2+2 warning label result = mpr.get_data("mp-9272") print(result) print() result = mpr.get_data("mp-571420") print(result) print() result = mpr.get_data("mp-1094115") print(result) print() result = mpr.get_data("mp-1180226") print(result) print() # structures = mpr.get_structures(QUERY) # for s in structures:
def compute_environments(chemenv_configuration): string_sources = {'cif': {'string': 'a Cif file', 'regexp': '.*\.cif$'}, 'mp': {'string': 'the Materials Project database', 'regexp': 'mp-[0-9]+$'}} questions = {'c': 'cif'} if chemenv_configuration.has_materials_project_access: questions['m'] = 'mp' lgf = LocalGeometryFinder() lgf.setup_parameters() allcg = AllCoordinationGeometries() strategy_class = strategies_class_lookup[chemenv_configuration.package_options['default_strategy']['strategy']] #TODO: Add the possibility to change the parameters and save them in the chemenv_configuration default_strategy = strategy_class() default_strategy.setup_options(chemenv_configuration.package_options['default_strategy']['strategy_options']) max_dist_factor = chemenv_configuration.package_options['default_max_distance_factor'] firsttime = True while True: if len(questions) > 1: found = False print('Enter the source from which the structure is coming or <q> to quit :') for key_character, qq in questions.items(): print(' - <{}> for a structure from {}'.format(key_character, string_sources[qq]['string'])) test = input(' ... ') if test == 'q': break if test not in list(questions.keys()): for key_character, qq in questions.items(): if re.match(string_sources[qq]['regexp'], str(test)) is not None: found = True source_type = qq if not found: print('Wrong key, try again ...') continue else: source_type = questions[test] else: found = False source_type = list(questions.values())[0] if found and len(questions) > 1: input_source = test if source_type == 'cif': if not found: input_source = input('Enter path to cif file : ') cp = CifParser(input_source) structure = cp.get_structures()[0] elif source_type == 'mp': if not found: input_source = input('Enter materials project id (e.g. "mp-1902") : ') a = MPRester(chemenv_configuration.materials_project_api_key) structure = a.get_structure_by_material_id(input_source) lgf.setup_structure(structure) print('Computing environments for {} ... '.format(structure.composition.reduced_formula)) se = lgf.compute_structure_environments_detailed_voronoi(maximum_distance_factor=max_dist_factor) print('Computing environments finished') while True: test = input('See list of environments determined for each (unequivalent) site ? ' '("y" or "n", "d" with details, "g" to see the grid) : ') strategy = default_strategy if test in ['y', 'd', 'g']: strategy.set_structure_environments(se) for eqslist in se.equivalent_sites: site = eqslist[0] isite = se.structure.index(site) try: if strategy.uniquely_determines_coordination_environments: ces = strategy.get_site_coordination_environments(site) else: ces = strategy.get_site_coordination_environments_fractions(site) except NeighborsNotComputedChemenvError: continue if ces is None: continue if len(ces) == 0: continue comp = site.species_and_occu #ce = strategy.get_site_coordination_environment(site) if strategy.uniquely_determines_coordination_environments: ce = ces[0] if ce is None: continue thecg = allcg.get_geometry_from_mp_symbol(ce[0]) mystring = 'Environment for site #{} {} ({}) : {} ({})\n'.format(str(isite), comp.get_reduced_formula_and_factor()[0], str(comp), thecg.name, ce[0]) else: mystring = 'Environments for site #{} {} ({}) : \n'.format(str(isite), comp.get_reduced_formula_and_factor()[0], str(comp)) for ce in ces: cg = allcg.get_geometry_from_mp_symbol(ce[0]) csm = ce[1]['other_symmetry_measures']['csm_wcs_ctwcc'] mystring += ' - {} ({}): {:.2f} % (csm : {:2f})\n'.format(cg.name, cg.mp_symbol, 100.0*ce[2], csm) if test in ['d', 'g'] and strategy.uniquely_determines_coordination_environments: if thecg.mp_symbol != UNCLEAR_ENVIRONMENT_SYMBOL: mystring += ' <Continuous symmetry measures> ' mingeoms = se.ce_list[isite][thecg.coordination_number][0].minimum_geometries() for mingeom in mingeoms: csm = mingeom[1]['other_symmetry_measures']['csm_wcs_ctwcc'] mystring += '{} : {:.2f} '.format(mingeom[0], csm) print(mystring) if test == 'g': test = input('Enter index of site(s) for which you want to see the grid of parameters : ') indices = list(map(int, test.split())) print(indices) for isite in indices: se.plot_environments(isite, additional_condition=se.AC.ONLY_ACB) if no_vis: test = input('Go to next structure ? ("y" to do so)') if test == 'y': break continue test = input('View structure with environments ? ("y" for the unit cell or "m" for a supercell or "n") : ') if test in ['y', 'm']: if test == 'm': mydeltas = [] test = input('Enter multiplicity (e.g. 3 2 2) : ') nns = test.split() for i0 in range(int(nns[0])): for i1 in range(int(nns[1])): for i2 in range(int(nns[2])): mydeltas.append(np.array([1.0*i0, 1.0*i1, 1.0*i2], np.float)) else: mydeltas = [np.zeros(3, np.float)] if firsttime: vis = StructureVis(show_polyhedron=False, show_unit_cell=True) vis.show_help = False firsttime = False vis.set_structure(se.structure) strategy.set_structure_environments(se) for isite, site in enumerate(se.structure): try: ces = strategy.get_site_coordination_environments(site) except NeighborsNotComputedChemenvError: continue if len(ces) == 0: continue ce = strategy.get_site_coordination_environment(site) if ce is not None and ce[0] != UNCLEAR_ENVIRONMENT_SYMBOL: for mydelta in mydeltas: psite = PeriodicSite(site._species, site._fcoords + mydelta, site._lattice, properties=site._properties) vis.add_site(psite) neighbors = strategy.get_site_neighbors(psite) draw_cg(vis, psite, neighbors, cg=lgf.cg.get_geometry_from_mp_symbol(ce[0]), perm=ce[1]['permutation']) vis.show() test = input('Go to next structure ? ("y" to do so) : ') if test == 'y': break print('')
def cif_lib_build(self, crystal_system, size_limit=None): ''' function to build cif and pdf library based on space group symbol Parameters ---------- crystal_system: str name of crystal system. It capitalized, like CUBIC. space group symbol will be generated by get_symbol_list method size_list : int optional. Uppder limit of data pulled out per symbol ''' self.crystal_system = crystal_system space_group_symbol = self.get_symbol_list(crystal_system) if isinstance(space_group_symbol, list): space_group_symbol_set = space_group_symbol else: space_group_symbol_set = list(spac_group_symbol) ## changing dir data_dir = os.path.join(self.working_dir, crystal_system) self.data_dir = data_dir self._makedirs(data_dir) os.chdir(data_dir) if os.getcwd() == data_dir: print('Library will be built at %s' % data_dir) else: e = 'Werid, return' raise RuntimeError(e) # summary lists missed_list = [] # reference m_id_list = [] # reference for searchs have been done in the past time_info = time.strftime('%Y-%m-%d') # create dirs, cif and calculated dir cif_dir = os.path.join(data_dir, 'cif_data') self._makedirs(cif_dir) self.cif_dir = cif_dir # looping for space_group_symbol in space_group_symbol_set: print('Building library with space_group symbol: {}'.format(space_group_symbol)) ## search query m = MPRester(self.API_key) search = m.query(criteria = {"spacegroup.symbol": space_group_symbol}, properties = ["material_id"]) if search: ## crazy looping if size_limit: dim = 400 # 400 data sets per symbol else: dim = len(search) print('Pull out %s data sets' % dim) print('Now, starts to save cif and compute pdf...') for i in range(dim): # part 1: grab cif files from data base m_id = search[i]['material_id'] m_id_list.append(m_id) m_struc = m.get_structure_by_material_id(m_id) m_formula = m_struc.formula m_name = m_formula.replace(' ', '') # material name cif_w = CifWriter(m_struc) cif_name = '{}_{}.cif'.format(space_group_symbol, m_name) cif_w_name = os.path.join(cif_dir, cif_name) if os.path.isfile(cif_w_name): print('already have {}, skip'.format(cif_name)) pass # skip files already exist else: cif_w.write_file(cif_w_name) print('{} has been saved'.format(cif_name)) else: print('Hmm, no reasult. Something wrong') missed_list.append(space_group_symbol) pass m_id_list_name = '{}_{}_material_id.txt'.format(crystal_system, time_info) m_id_list_w_name = os.path.join(data_dir, m_id_list_name) np.savetxt(m_id_list_w_name, m_id_list) print('''SUMMARY: for {} cystsal sytem, Symbols {} can't be found from data base'''.format(crystal_system, missed_list)) return cif_dir
class MPDataRetrieval(BaseDataRetrieval): """ Retrieves data from the Materials Project database. If you use this data retrieval class, please additionally cite: Ong, S.P., Cholia, S., Jain, A., Brafman, M., Gunter, D., Ceder, G., Persson, K.A., 2015. The Materials Application Programming Interface (API): A simple, flexible and efficient API for materials data based on REpresentational State Transfer (REST) principles. Computational Materials Science 97, 209–215. https://doi.org/10.1016/j.commatsci.2014.10.037 """ def __init__(self, api_key=None): """ Args: api_key: (str) Your Materials Project API key, or None if you've set up your pymatgen config. """ self.mprester = MPRester(api_key=api_key) def api_link(self): return "https://materialsproject.org/wiki/index.php/The_Materials_API" def get_dataframe(self, criteria, properties, index_mpid=True, **kwargs): """ Gets data from MP in a dataframe format. See api_link for more details. Args: criteria (dict): the same as in get_data properties ([str]): the same properties supported as in get_data plus: "structure", "initial_structure", "final_structure", "bandstructure" (line mode), "bandstructure_uniform", "phonon_bandstructure", "phonon_ddb", "phonon_bandstructure", "phonon_dos". Note that for a long list of compounds, it may take a long time to retrieve some of these objects. index_mpid (bool): the same as in get_data kwargs (dict): the same keyword arguments as in get_data Returns (pandas.Dataframe): """ data = self.get_data(criteria=criteria, properties=properties, index_mpid=index_mpid, **kwargs) df = pd.DataFrame(data, columns=properties) for prop in ["dos", "phonon_dos", "phonon_bandstructure", "phonon_ddb"]: if prop in properties: df[prop] = self.try_get_prop_by_material_id( prop=prop, material_id_list=df["material_id"].values) if "bandstructure" in properties: df["bandstructure"] = self.try_get_prop_by_material_id( prop="bandstructure", material_id_list=df["material_id"].values, line_mode=True) if "bandstructure_uniform" in properties: df["bandstructure_uniform"] = self.try_get_prop_by_material_id( prop="bandstructure", material_id_list=df["material_id"].values, line_mode=False) if index_mpid: df = df.set_index("material_id") return df def get_data(self, criteria, properties, mp_decode=False, index_mpid=True): """ Args: criteria: (str/dict) see MPRester.query() for a description of this parameter. String examples: "mp-1234", "Fe2O3", "Li-Fe-O', "\\*2O3". Dict example: {"band_gap": {"$gt": 1}} properties: (list) see MPRester.query() for a description of this parameter. Example: ["formula", "formation_energy_per_atom"] mp_decode: (bool) see MPRester.query() for a description of this parameter. Whether to decode to a Pymatgen object where possible. index_mpid: (bool) Whether to set the materials_id as the dataframe index. Returns ([dict]): a list of jsons that match the criteria and contain properties """ if index_mpid and "material_id" not in properties: properties.append("material_id") data = self.mprester.query(criteria, properties, mp_decode) return data def try_get_prop_by_material_id(self, prop, material_id_list, **kwargs): """ Call the relevant get_prop_by_material_id. "prop" is a property such as bandstructure that is not readily available in supported properties of the get_data function but via the get_bandstructure_by_material_id method for example. Args: prop (str): the name of the property. Options are: "bandstructure", "dos", "phonon_dos", "phonon_bandstructure", "phonon_ddb" material_id_list ([str]): list of material_id of compounds kwargs (dict): other keyword arguments that get_*_by_material_id may have; e.g. line_mode in get_bandstructure_by_material_id Returns ([target prop object or NaN]): If the target property is not available for a certain material_id, NaN is returned. """ method = getattr(self.mprester, "get_{}_by_material_id".format(prop)) props = [] for material_id in material_id_list: try: props.append(method(material_id=material_id, **kwargs)) except MPRestError: props.append(float('NaN')) return props
def __init__(self, target_col_id='structure', overwrite_data=False, mapi_key=None): super().__init__(target_col_id, overwrite_data) self.mpr = MPRester(mapi_key)
from pymatgen import MPRester from pymatgen.analysis.defects import point_defects from pymatgen.io import vasp from pymatgen.io.vasp.sets import MPStaticVaspInputSet from pymatgen.io.zeoone import get_voronoi_nodes, get_void_volume_surfarea, get_high_accuracy_voronoi_nodes try: from zeo.netstorage import AtomNetwork, VoronoiNetwork from zeo.area_volume import volume, surface_area from zeo.cluster import get_nearest_largest_diameter_highaccuracy_vornode,\ generate_simplified_highaccuracy_voronoi_network, \ prune_voronoi_network_close_node zeo_found = True except ImportError: zeo_found = False m = MPRester(key) #def get_POSCAR(elements, interstitial, supercell_size, ): results = m.query("Fe", ['structure']) print(type(results[2]['structure'])) #Mg_cell = mg.Lattice.hexagonal(3.184, 5.249) #print(Mg_cell.lengths_and_angles) #Mg_Lattice = mg.Structure(Mg_cell, ["Mg","Mg"], [[.333333333,.66666666666,.25], [.66666666666,.33333333333333,.75]]) print(results[2]['structure']) Mg_Lattice=results[2]['structure'] #Mg_Lattice = results[0] Mg_Interstitial = point_defects.Interstitial(Mg_Lattice, {u"Fe":0}, {u"Fe":1.26}, 'voronoi_vertex',accuracy=u'Normal',symmetry_flag=True,oxi_state=False)
# This script performs a blanket search for all systems with elasticity data. from pymatgen import MPRester import numpy as np import os key = os.environ['MAPI_KEY'] # Assuming you've done `export MAPI_KEY="USER_API_KEY"` at the command line # See materialsproject.org/dashboard to get your API key m = MPRester(key) data = m.query(criteria={"elasticity": {"$exists": True}}, properties=["pretty_formula", "elasticity.elastic_tensor"])
import copy import numpy as np from pymatgen import Structure, MPRester from pymatgen.transformations.standard_transformations import SubstitutionTransformation from fireworks import LaunchPad, Firework, Workflow from atomate.utils.utils import get_fws_and_tasks from atomate.vasp.workflows.presets.core import wf_bandstructure from atomate.vasp.fireworks.core import OptimizeFW, StaticFW from atomate.vasp.powerups import add_bandgap_check, add_stability_check, add_modify_incar, add_tags m = MPRester() comp_list = [ # ['Mg','Sb',2], # ['Ca','Sb',2], # ['Sr','Sb',2],['Ba','Sb',2], # ['Mg','As',2],['Ca','As',2],['Sr','As',2],['Ba','As',2], # ['Mg','Bi',2],['Ca','Bi',2],['Sr','Bi',2],['Ba','Bi',2], # ['Sc','Sb',1],['La','Sb',1],['Y','Sb',1],['Eu','Sb',1], # ['Sc','Sb',1],['La','As',1],['Y','As',1],['Eu','As',1], # ['Sc','Sb',1],['La','Bi',1],['Y','Bi',1],['Eu','Bi',1], # ['Sc','Sn',2],['La','Sn',2],['Y','Sn',2],['Eu','Sn',2],#['Ce','Sn',1], # ['Sc','Sn',2],['La','Ge',2],['Y','Ge',2],['Eu','Ge',2],#['Ce','Ge',1], # ['Li','Te',2],['Na','Te',2],['K','Te',2],['Rb','Te',2],['Cs','Te',2], # ['Li','Se',2],['Na','Se',2],['K','Se',2],['Rb','Se',2],['Cs','Se',2], # ['Sc','Te',2],['La','Te',2],['Y','Te',2],['Eu','Te',2],#['Ce','Te',1], # ['Sc','Se',2],['La','Se',2],['Y','Se',2],['Eu','Se',2],#['Ce','Se',1],
return total_energy def get_avg_Z_num(material, elem_list): Z_list = [] for element in elem_list: Z_list += [log(Element(element).Z)] return np.average(Z_list) def get_sd_X(material, elem_list): X_list = [] for element in elem_list: X_list += [log(Element(element).X)] return np.std(X_list) key = os.environ['MAPI_KEY'] m = MPRester(key) materials_list = m.query(criteria={"elasticity": {"$exists": True}}, properties=['pretty_formula', 'reduced_cell_formula', "elasticity.K_VRH", 'volume', 'density', 'formation_energy_per_atom', 'formation_energy_per_atom', 'nsites']) def vectorize_and_catalog(materials): vector_list = [] catalog = {} for material in materials: element_list = element_lister(material) vector = [get_ln_volume(material, element_list), get_c_energy_per_atom(material, element_list), get_avg_Z_num(material, element_list), get_sd_X(material, element_list)] vector_list += [vector] catalog[tuple(vector)] = material return vector_list, catalog def vector_to_material(vector):
class CompositionToStructureFromMP(ConversionFeaturizer): """ Featurizer to get a Structure object from Materials Project using the composition alone. The most stable entry from Materials Project is selected, or NaN if no entry is found in the Materials Project. Args: target_col_id (str or None): The column in which the converted data will be written. If the column already exists then an error will be thrown unless `overwrite_data` is set to `True`. If `target_col_id` begins with an underscore the data will be written to the column: `"{}_{}".format(col_id, target_col_id[1:])`, where `col_id` is the column being featurized. If `target_col_id` is set to None then the data will be written "in place" to the `col_id` column (this will only work if `overwrite_data=True`). overwrite_data (bool): Overwrite any data in `target_column` if it exists. map_key (str): Materials API key """ def __init__(self, target_col_id='structure', overwrite_data=False, mapi_key=None): super().__init__(target_col_id, overwrite_data) self.mpr = MPRester(mapi_key) def featurize(self, comp): """ Get the most stable structure from Materials Project Args: comp (`pymatgen.core.composition.Composition`): A composition. Returns: (`pymatgen.core.structure.Structure`): A Structure object. """ entries = self.mpr.get_data(comp.reduced_formula, prop="energy_per_atom") if len(entries) > 0: most_stable_entry = \ sorted(entries, key=lambda e: e['energy_per_atom'])[0] s = self.mpr.get_structure_by_material_id( most_stable_entry["material_id"]) return[s] return [float("nan")] def citations(self): return [ "@article{doi:10.1063/1.4812323, author = {Jain,Anubhav and Ong," "Shyue Ping and Hautier,Geoffroy and Chen,Wei and Richards, " "William Davidson and Dacek,Stephen and Cholia,Shreyas " "and Gunter,Dan and Skinner,David and Ceder,Gerbrand " "and Persson,Kristin A. }, title = {Commentary: The Materials " "Project: A materials genome approach to accelerating materials " "innovation}, journal = {APL Materials}, volume = {1}, number = " "{1}, pages = {011002}, year = {2013}, doi = {10.1063/1.4812323}, " "URL = {https://doi.org/10.1063/1.4812323}, " "eprint = {https://doi.org/10.1063/1.4812323}}", "@article{Ong2015, author = {Ong, Shyue Ping and Cholia, " "Shreyas and Jain, Anubhav and Brafman, Miriam and Gunter, Dan " "and Ceder, Gerbrand and Persson, Kristin a.}, doi = " "{10.1016/j.commatsci.2014.10.037}, issn = {09270256}, " "journal = {Computational Materials Science}, month = {feb}, " "pages = {209--215}, publisher = {Elsevier B.V.}, title = " "{{The Materials Application Programming Interface (API): A simple, " "flexible and efficient API for materials data based on " "REpresentational State Transfer (REST) principles}}, " "url = {http://linkinghub.elsevier.com/retrieve/pii/S0927025614007113}, " "volume = {97}, year = {2015} } "] def implementors(self): return ["Anubhav Jain"]
'atomic_mass-1', 'atomic_mass-0', 'atomic_mass1', 'atomic_mass2', 'atomic_mass3', 'atomic_mass4', 'atomic_number-4', 'atomic_number-3', 'atomic_number-2', 'atomic_number-1', 'atomic_number-0', 'atomic_number1', 'atomic_number2', 'atomic_number3', 'atomic_number4', 'atomic_radius-4', 'atomic_radius-3', 'atomic_radius-2', 'atomic_radius-1', 'atomic_radius-0', 'atomic_radius1', 'atomic_radius2', 'atomic_radius3', 'atomic_radius4', 'row-4', 'row-3', 'row-2', 'row-1', 'row-0', 'row1', 'row2', 'row3', 'row4', 'x-4', 'x-3', 'x-2', 'x-1', 'x-0', 'x1', 'x2', 'x3', 'x4', 'eBlPt-4', 'eBlPt-3', 'eBlPt-2', 'eBlPt-1', 'eBlPt-0', 'eBlPt1', 'eBlPt2', 'eBlPt3', 'eBlPt4', 'eMlPt-4', 'eMlPt-3', 'eMlPt-2', 'eMlPt-1', 'eMlPt-0', 'eMlPt1', 'eMlPt2', 'eMlPt3', 'eMlPt4', 'lvpa', 'cepa', 'cohesive_energy', 'average_electroneg', 'bandgap', 'density', 'formation_energy-peratom', 'e_above_hull' ] api = MPRester("eDCEK5m9WVjmajp7e8af") CAVEAT_AIAB = 'Unable to estimate cohesive energy for material.' CAVEAT_F_BLOCK = 'Predictions are likely less reliable for materials containing F-block elements.' CAVEAT_HUBBARD = 'Predictions may be less reliable for materials with non-GGA runs.' DATAFILE_AIAB = 'data/element_aiab_energy.json' VERY_SMALL = 1E-12 propsTableauCritere = [ 'material_id', 'pretty_formula', 'energy', 'energy_per_atom', 'density', 'formation_energy_per_atom', 'volume', 'is_hubbard', 'nsites', 'spacegroup', 'band_gap', 'e_above_hull' ] all_elements = dict()
# !/usr/bin/env python # -*- coding:utf-8 -*- # author:春梅 # Import necessary tools from pymatgen from pymatgen import MPRester from pymatgen.analysis.pourbaix_diagram import PourbaixDiagram, PourbaixPlotter # %matplotlib inline # Initialize the MP Rester mpr = MPRester("hvSDrzMafUtXE0JQ") ##将API 秘钥输入适配器中,并且初始化适配器,需要自己申请。 # Get all pourbaix entries corresponding to the Cu-O-H chemical system. entries = mpr.get_pourbaix_entries(["Cu"]) # Construct the PourbaixDiagram object pbx = PourbaixDiagram(entries) # Get an entry stability as a function of pH and V entry = [e for e in entries if e.entry_id == 'mp-1692'][0] print( "CuO's potential energy per atom relative to the most", "stable decomposition product is {:0.2f} eV/atom".format( pbx.get_decomposition_energy(entry, pH=7, V=-0.2))) plotter = PourbaixPlotter(pbx) plotter.get_pourbaix_plot().show() plt = plotter.plot_entry_stability(entry) plt.show() # Get all pourbaix entries corresponding to the Fe-O-H chemical system. entries = mpr.get_pourbaix_entries(["Bi", "V"]) # Construct the PourbaixDiagram object pbx = PourbaixDiagram(entries, comp_dict={ "Bi": 0.5, "V": 0.5 },
type=str, help='The materialsproject.org API key') parser.add_argument('--out', '-o', action='store', default=None, help='The path to the pickle file to be created.') parser.add_argument( '--stable', '-s', action='store_true', help= 'If present, indicates that only stable compounds should be included.') args = parser.parse_args() client = MPRester(args.key) criteria = {"e_above_hull": 0.0} if args.stable else {} properties = ['structure', 'band_gap'] print('Fetching data...') result = client.query(criteria, properties) print('Converting to dataframe...') gaps_data = pd.DataFrame(result) print('Pickling...')
# Assuming you've done `export MAPI_KEY="USER_API_KEY"` at the command line # See materialsproject.org/dashboard to get your API key from pymatgen import MPRester import numpy as np import os key = os.environ['MAPI_KEY'] m = MPRester(key) e_cutoff = m.query("mp-46", ["elasticity.calculations.energy_cutoff"])[0]['elasticity.calculations.energy_cutoff'] # units (eV) file = open("INCAR", "w") file.write("LWAVE = .FALSE.\n") file.write("LCHARG= .FALSE.\n") file.write("PREC = Accurate\n") file.write("LREAL = AUTO\n") file.write("ADDGRID = .TRUE.\n") file.write("POTIM = 0.1\n") file.write("SIGMA = 0.05\n") file.write("IBRION = 2\n") file.write("NSW = 100\n") file.write("ENCUT ={0:3d}\n".format(int(e_cutoff))) file.write("EDIFF = 1e-8\n") file.write("EDIFFG = -1e-3\n") file.write("ISIF = 3\n") file.close()
import numpy as np import matplotlib.pyplot as plt import pymongo from pymatgen import MPRester connection = pymongo.Connection("mongodb://localhost", safe=True) db = connection.coordination cddb = db.Zn # example data cursor = cddb.find() API_KEY = "Neo5xcHNOTE41tZi" mpr = MPRester(api_key=API_KEY, host="www.materialsproject.org") #print "coordination number = 2, e^hull < 50meV/atom" #for ic in cursor: # if ic["c_num"] == 2 and ic["ehull"] <0.05: # print mpr.get_entry_by_material_id(ic["task_id"]).composition.reduced_formula # print "https://materialsproject.org/materials/"+ic["task_id"]+"/" #cursor = cddb.find() #print "coordination number = 3, e^hull < 50meV/atom" #for ic in cursor: # if ic["c_num"] == 3 and ic["ehull"] <0.05: # print mpr.get_entry_by_material_id(ic["task_id"]).composition.reduced_formula # print "https://materialsproject.org/materials/"+ic["task_id"]+"/" cursor = cddb.find() print "coordination number = 5, e^hull < 50meV/atom"
def submit_tests(names=None, params=None): sma = SubmissionMongoAdapter.auto_load() # note: TiO2 is duplicated twice purposely, duplicate check should catch this compounds = {"Si": 149, "Al": 134, "ZnO": 2133, "FeO": 18905, "LiCoO2": 601860, "LiFePO4": 585433, "GaAs": 2534, "Ge": 32, "PbTe": 19717, "YbO": 1216, "SiC": 567551, "Fe3C": 510623, "SiO2": 547211, "Na2O": 2352, "InSb (unstable)": 10148, "Sb2O5": 1705, "N2O5": 554368, "BaTiO3": 5020, "Rb2O": 1394, "TiO2": 554278, "TiO2 (2)": 554278, 'BaNbTePO8': 560794, "AgCl": 22922, "AgCl (2)": 570858, "SiO2 (2)": 555211, "Mg2SiO4": 2895, "CO2": 20066, "PbSO4": 22298, "SrTiO3": 5532, "FeAl": 2658, "AlFeCo2": 10884, "NaCoO2": 554427, "ReO3": 547271, "LaH2": 24153, "SiH3I": 28538, "LiBH4": 30209, "H8S5N2": 28143, "LiOH": 23856, "SrO2": 2697, "Mn": 35, "Hg4Pt": 2312, "PdF4": 13868, "Gd2WO6": 651333, 'MnO2': 19395, 'VO2': 504800} mpr = MPRester() for name, sid in compounds.iteritems(): if not names or name in names: sid = mpr.get_materials_id_from_task_id("mp-{}".format(sid)) s = mpr.get_structure_by_material_id(sid, final=False) snl = StructureNL(s, 'Anubhav Jain <*****@*****.**>') parameters = {'priority': 10} if name == 'Si' else None if params: parameters.update(params) sma.submit_snl(snl, '*****@*****.**', parameters=parameters)