def alkali_vs_anion(self): """Ratio of the alkali metal radius to the anion radius. This method uses the average of the positive oxidation states for the alkali and the negative oxidation states for the anion. Returns: The ratio of the alkali ionic radius and anion ionic radius. Returns 0 if ions are missing. """ alkali_radius = 0.0 anion_radius = 0.0 for ele in self.comp: ox_states = Element(ele).oxidation_states if ele in self.working_cations: pos_ox_states = [oxs for oxs in ox_states if oxs > 0] alkali_radius = mean([ Element(ele).ionic_radii[oxs] for oxs in pos_ox_states if oxs in Element(ele).ionic_radii ]) if ele in self.anions: neg_ox_states = [oxs for oxs in ox_states if oxs < 0] anion_radius = mean([ Element(ele).ionic_radii[oxs] for oxs in neg_ox_states if oxs in Element(ele).ionic_radii ]) if anion_radius == 0.0: return 0.0 else: return alkali_radius / anion_radius
def metal_vs_anion(self): """Ratio of the metal radius to the anion radius. Specifically, this method uses the average of the positive oxidation states for the metal ions and the negative average for anions. Returns: The ratio of the metal and anion ionic radii. 0 if ions missing. """ metal_radius = 0.0 anion_radius = 0.0 for ele in self.comp: ox_states = Element(ele).oxidation_states if ele in self.metal_cations: pos_ox_states = [oxs for oxs in ox_states if oxs > 0] metal_radius = mean([ Element(ele).ionic_radii[oxs] for oxs in pos_ox_states if oxs in Element(ele).ionic_radii ]) if ele in self.anions: neg_ox_states = [oxs for oxs in ox_states if oxs < 0] anion_radius = mean([ Element(ele).ionic_radii[oxs] for oxs in neg_ox_states if oxs in Element(ele).ionic_radii ]) if anion_radius == 0.0: return 0.0 else: return metal_radius / anion_radius
def test_get_coordination_number(self): s = self.get_structure('LiFePO4') # test the default coordination finder finder = JMolCoordFinder() nsites_checked = 0 for site_idx, site in enumerate(s): if site.specie == Element("Li"): self.assertEqual(finder.get_coordination_number(s, site_idx), 0) nsites_checked += 1 elif site.specie == Element("Fe"): self.assertEqual(finder.get_coordination_number(s, site_idx), 6) nsites_checked += 1 elif site.specie == Element("P"): self.assertEqual(finder.get_coordination_number(s, site_idx), 4) nsites_checked += 1 self.assertEqual(nsites_checked, 12) # test a user override that would cause Li to show up as 6-coordinated finder = JMolCoordFinder({"Li": 1}) self.assertEqual(finder.get_coordination_number(s, 0), 6) # verify get_coordinated_sites function works self.assertEqual(len(finder.get_coordinated_sites(s, 0)), 6)
def setUpClass(cls): mass_info = [ ("A", "H"), ("B", Element("C")), ("C", Element("O")), ("D", 1.00794), ] nonbond_coeffs = [ [1, 1, 1.1225], [1, 1.175, 1.31894], [1, 1.55, 1.73988], [1, 1, 1.1225], [1, 1.35, 4], [1, 1.725, 1.93631], [1, 1.175, 1.31894], [1, 2.1, 4], [1, 1.55, 1.73988], [1, 1, 1.1225], ] topo_coeffs = { "Bond Coeffs": [ {"coeffs": [50, 0.659469], "types": [("A", "B"), ("C", "D")]}, {"coeffs": [50, 0.855906], "types": [("B", "C")]}, ] } cls.virus = ForceField( mass_info=mass_info, nonbond_coeffs=nonbond_coeffs, topo_coeffs=topo_coeffs ) cls.ethane = ForceField.from_file(os.path.join(test_dir, "ff_ethane.yaml"))
def alkali_vs_metal(self): """Ratio of the alkali and metal ionic radii. Specifically, this method uses the average of the positive oxidation states for the alkali and metal ions. Returns: The ratio of the alkai and metal ionic radii. 0 if ions not present. """ alkali_radius = 0.0 metal_radius = 0.0 for ele in self.comp: ox_states = Element(ele).oxidation_states if ele in self.working_cations: pos_ox_states = [oxs for oxs in ox_states if oxs > 0] alkali_radius = mean([ Element(ele).ionic_radii[oxs] for oxs in pos_ox_states if oxs in Element(ele).ionic_radii ]) if ele in self.metal_cations: pos_ox_states = [oxs for oxs in ox_states if oxs > 0] metal_radius = mean([ Element(ele).ionic_radii[oxs] for oxs in pos_ox_states if oxs in Element(ele).ionic_radii ]) if metal_radius == 0.0: return 0.0 else: return alkali_radius / metal_radius
def test_process_entry_superoxide(self): el_li = Element("Li") el_o = Element("O") latt = Lattice([[3.985034, 0.0, 0.0], [0.0, 4.881506, 0.0], [0.0, 0.0, 2.959824]]) elts = [el_li, el_li, el_o, el_o, el_o, el_o] coords = list() coords.append([0.500000, 0.500000, 0.500000]) coords.append([0.0, 0.0, 0.0]) coords.append([0.632568, 0.085090, 0.500000]) coords.append([0.367432, 0.914910, 0.500000]) coords.append([0.132568, 0.414910, 0.000000]) coords.append([0.867432, 0.585090, 0.000000]) struct = Structure(latt, elts, coords) lio2_entry = ComputedStructureEntry( struct, -3, parameters={ 'is_hubbard': False, 'hubbards': None, 'run_type': 'GGA', 'potcar_symbols': ['PAW_PBE Fe 06Sep2000', 'PAW_PBE O 08Apr2002'] }) lio2_entry_corrected = self.compat.process_entry(lio2_entry) self.assertAlmostEqual(lio2_entry_corrected.energy, -3 - 0.13893 * 4, 4)
def setUp(self): element_profile = {'Ni': {'r': 0.5, 'w': 1}} describer1 = BispectrumCoefficients(rcutfac=4.1, twojmax=8, element_profile=element_profile, quadratic=False, pot_fit=True) model1 = LinearModel(describer=describer1) model1.model.coef_ = coeff model1.model.intercept_ = intercept snap1 = SNAPotential(model=model1) snap1.specie = Element('Ni') self.ff_settings1 = snap1 describer2 = BispectrumCoefficients(rcutfac=4.1, twojmax=8, element_profile=element_profile, quadratic=True, pot_fit=True) model2 = LinearModel(describer=describer2) model2.model.coef_ = coeff model2.model.intercept_ = intercept snap2 = SNAPotential(model=model2) snap2.specie = Element('Ni') self.ff_settings2 = snap2 self.struct = Structure.from_spacegroup('Fm-3m', Lattice.cubic(3.506), ['Ni'], [[0, 0, 0]])
def len_elts(entry): if "(s)" in entry: comp = Composition(entry[:-3]) else: comp = Ion.from_formula(entry) return len([el for el in comp.elements if el not in [Element("H"), Element("O")]])
def test_aqueous_compat(self): el_li = Element("Li") el_o = Element("O") el_h = Element("H") latt = Lattice.from_parameters(3.565276, 3.565276, 4.384277, 90.000000, 90.000000, 90.000000) elts = [el_h, el_h, el_li, el_li, el_o, el_o] coords = [[0.000000, 0.500000, 0.413969], [0.500000, 0.000000, 0.586031], [0.000000, 0.000000, 0.000000], [0.500000, 0.500000, 0.000000], [0.000000, 0.500000, 0.192672], [0.500000, 0.000000, 0.807328]] struct = Structure(latt, elts, coords) lioh_entry = ComputedStructureEntry(struct, -3, parameters={'is_hubbard': False, 'hubbards': None, 'run_type': 'GGA', 'potcar_spec': [{'titel':'PAW_PBE Li 17Jan2003', 'hash': '65e83282d1707ec078c1012afbd05be8'}, {'titel': 'PAW_PBE O 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}, {"titel": 'PAW_PBE H 15Jun2001', 'hash': "bb43c666e3d36577264afe07669e9582"}]}) lioh_entry_compat = self.compat.process_entry(lioh_entry) lioh_entry_compat_aqcorr = self.aqcorr.correct_entry(lioh_entry_compat) lioh_entry_aqcompat = self.aqcompat.process_entry(lioh_entry) self.assertAlmostEqual(lioh_entry_compat_aqcorr.energy, lioh_entry_aqcompat.energy, 4)
def test_peroxide_energy_corr(self): latt = Lattice.from_parameters(3.159597, 3.159572, 7.685205, 89.999884, 89.999674, 60.000510) el_li = Element("Li") el_o = Element("O") elts = [el_li, el_li, el_li, el_li, el_o, el_o, el_o, el_o] coords = [[0.666656, 0.666705, 0.750001], [0.333342, 0.333378, 0.250001], [0.000001, 0.000041, 0.500001], [0.000001, 0.000021, 0.000001], [0.333347, 0.333332, 0.649191], [0.333322, 0.333353, 0.850803], [0.666666, 0.666686, 0.350813], [0.666665, 0.666684, 0.149189]] struct = Structure(latt, elts, coords) li2o2_entry = ComputedStructureEntry(struct, -3, parameters={'is_hubbard': False, 'hubbards': None, 'run_type': 'GGA', 'potcar_spec': [{'titel':'PAW_PBE Li 17Jan2003', 'hash': '65e83282d1707ec078c1012afbd05be8'}, {'titel': 'PAW_PBE O 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}]}) li2o2_entry_corrected = self.compat.process_entry(li2o2_entry) self.assertRaises(AssertionError, self.assertAlmostEqual, *(li2o2_entry_corrected.energy, -3 - 0.44317 * 4, 4)) self.assertAlmostEqual(li2o2_entry_corrected.energy, -3 - 0.66975 * 4, 4)
def test_process_entry_superoxide(self): el_li = Element("Li") el_o = Element("O") latt = Lattice([[3.985034, 0.0, 0.0], [0.0, 4.881506, 0.0], [0.0, 0.0, 2.959824]]) elts = [el_li, el_li, el_o, el_o, el_o, el_o] coords = list() coords.append([0.500000, 0.500000, 0.500000]) coords.append([0.0, 0.0, 0.0]) coords.append([0.632568, 0.085090, 0.500000]) coords.append([0.367432, 0.914910, 0.500000]) coords.append([0.132568, 0.414910, 0.000000]) coords.append([0.867432, 0.585090, 0.000000]) struct = Structure(latt, elts, coords) lio2_entry = ComputedStructureEntry(struct, -3, parameters={'is_hubbard': False, 'hubbards': None, 'run_type': 'GGA', 'potcar_spec': [{'titel':'PAW_PBE Li 17Jan2003', 'hash': '65e83282d1707ec078c1012afbd05be8'}, {'titel': 'PAW_PBE O 08Apr2002', 'hash': '7a25bc5b9a5393f46600a4939d357982'}]}) lio2_entry_corrected = self.compat.process_entry(lio2_entry) self.assertAlmostEqual(lio2_entry_corrected.energy, -3 -0.13893*4, 4)
def setUp(self): module_dir = os.path.dirname(os.path.abspath(__file__)) (self.elements, self.entries) = PDEntryIO.from_csv( os.path.join(module_dir, "pdentries_test.csv")) self.pd = GrandPotentialPhaseDiagram(self.entries, {Element("O"): -5}, self.elements) self.pd6 = GrandPotentialPhaseDiagram(self.entries, {Element("O"): -6})
def test_aqueous_compat(self): el_li = Element("Li") el_o = Element("O") el_h = Element("H") latt = Lattice.from_parameters(3.565276, 3.565276, 4.384277, 90.000000, 90.000000, 90.000000) elts = [el_h, el_h, el_li, el_li, el_o, el_o] coords = [[0.000000, 0.500000, 0.413969], [0.500000, 0.000000, 0.586031], [0.000000, 0.000000, 0.000000], [0.500000, 0.500000, 0.000000], [0.000000, 0.500000, 0.192672], [0.500000, 0.000000, 0.807328]] struct = Structure(latt, elts, coords) lioh_entry = ComputedStructureEntry(struct, -3, parameters={ 'is_hubbard': False, 'hubbards': None, 'run_type': 'GGA', 'potcar_symbols': [ 'PAW_PBE Fe 17Jan2003', 'PAW_PBE O 08Apr2002', 'PAW_PBE H 15Jun2001' ] }) lioh_entry_compat = self.compat.process_entry(lioh_entry) lioh_entry_compat_aqcorr = self.aqcorr.correct_entry(lioh_entry_compat) lioh_entry_aqcompat = self.aqcompat.process_entry(lioh_entry) self.assertAlmostEqual(lioh_entry_compat_aqcorr.energy, lioh_entry_aqcompat.energy, 4)
def test_peroxide_energy_corr(self): latt = Lattice.from_parameters(3.159597, 3.159572, 7.685205, 89.999884, 89.999674, 60.000510) el_li = Element("Li") el_o = Element("O") elts = [el_li, el_li, el_li, el_li, el_o, el_o, el_o, el_o] coords = [[0.666656, 0.666705, 0.750001], [0.333342, 0.333378, 0.250001], [0.000001, 0.000041, 0.500001], [0.000001, 0.000021, 0.000001], [0.333347, 0.333332, 0.649191], [0.333322, 0.333353, 0.850803], [0.666666, 0.666686, 0.350813], [0.666665, 0.666684, 0.149189]] struct = Structure(latt, elts, coords) li2o2_entry = ComputedStructureEntry( struct, -3, parameters={ 'is_hubbard': False, 'hubbards': None, 'run_type': 'GGA', 'potcar_symbols': ['PAW_PBE Fe 06Sep2000', 'PAW_PBE O 08Apr2002'] }) li2o2_entry_corrected = self.compat.process_entry(li2o2_entry) self.assertRaises(AssertionError, self.assertAlmostEqual, *(li2o2_entry_corrected.energy, -3 - 0.44317 * 4, 4)) self.assertAlmostEqual(li2o2_entry_corrected.energy, -3 - 0.66975 * 4, 4)
def test_get_property(self): embedding_cu = self.data_source.get_elemental_property( Element("Cu"), "embedding 3") self.assertAlmostEqual(0.028666902333498, embedding_cu) with self.assertRaises(ValueError): self.data_source.get_elemental_property(Element("Db"), "embedding 9")
def get_naive_bond_length(el1, el2): """ Use pymatgen to get approximate bond length as the sum of atomic radii :param el1: Element 1 :param el2: Element 2 :return: estimated bond length """ return Element(el1).atomic_radius + Element(el2).atomic_radius
def get_pymatgen_descriptor(comp, prop): """ Get descriptor data for elements in a compound from pymatgen. Args: comp: (str) compound composition, eg: "NaCl" prop: (str) pymatgen element attribute, as defined in the Element class at http://pymatgen.org/_modules/pymatgen/core/periodic_table.html Returns: (list) of values containing descriptor floats for each atom in the compound """ eldata = [] eldata_tup_lst = [] eldata_tup = collections.namedtuple( 'eldata_tup', 'element propname propvalue propunit amt') el_amt_dict = Composition(comp).get_el_amt_dict() for el in el_amt_dict: if callable(getattr(Element(el), prop)) is None: raise ValueError('Invalid pymatgen Element attribute(property)') if getattr(Element(el), prop) is not None: # units are None for these pymatgen descriptors # todo: there seem to be a lot more unitless descriptors which are not listed here... -Alex D if prop in [ 'X', 'Z', 'ionic_radii', 'group', 'row', 'number', 'mendeleev_no', 'oxidation_states', 'common_oxidation_states' ]: units = None else: units = getattr(Element(el), prop).unit # Make a named tuple out of all the available information eldata_tup_lst.append( eldata_tup(element=el, propname=prop, propvalue=float(getattr(Element(el), prop)), propunit=units, amt=el_amt_dict[el])) # Add descriptor values, one for each atom in the compound for i in range(int(el_amt_dict[el])): eldata.append(float(getattr(Element(el), prop))) else: eldata_tup_lst.append( eldata_tup(element=el, propname=prop, propvalue=None, propunit=None, amt=el_amt_dict[el])) return eldata
def test_get_property(self): self.assertAlmostEqual(-4.3853, self.data_source.get_elemental_property(Element("Bi"), "mus_fere"), 4) self.assertEqual(59600, self.data_source.get_elemental_property(Element("Li"), "electron_affin")) self.assertAlmostEqual(2372300, self.data_source.get_elemental_property(Element("He"), "first_ioniz")) self.assertAlmostEqual(sum([2372300,5250500]), self.data_source.get_charge_dependent_property_from_specie(Specie("He", 2), "total_ioniz")) self.assertAlmostEqual(18.6, self.data_source.get_charge_dependent_property_from_specie(Specie("V", 3), "xtal_field_split"))
def test_coulomb_mat(self): cm = CoulombMatrix() cmat = cm.transform_one(self.s1).values.reshape(self.s1.num_sites, self.s1.num_sites) na = Element('Na') cl = Element('Cl') dist = self.s1.distance_matrix self.assertEqual(cmat[0][0], (na.Z ** 2.4) * 0.5) self.assertEqual(cmat[4][4], (cl.Z ** 2.4) * 0.5) self.assertEqual(cmat[0][1], (na.Z * na.Z) / dist[0][1])
def test_get_property(self): self.assertAlmostEqual( 9.012182, self.data_source.get_elemental_property(Element("Be"), "atomic_mass")) self.assertAlmostEqual( 1.26, self.data_source.get_charge_dependent_property( Element("Ac"), 3, "ionic_radii"))
def test_get_plot(self): # Some very basic non-tests. Just to make sure the methods are callable. self.plotter.get_plot() self.plotter3d.get_plot() # self.plotter.get_plot(energy_colormap="Reds", process_attributes=True) # plt = self.plotter3d.get_plot(energy_colormap="Reds", process_attributes=True) # self.plotter.get_plot(energy_colormap="Reds", process_attributes=False) # plt = self.plotter3d.get_plot(energy_colormap="Reds", # process_attributes=False) self.plotter.get_chempot_range_map_plot([Element("Li"), Element("O")])
def test_get_property(self): embedding_cu = self.data_source.get_elemental_property(Element("Cu"), "embedding 1") self.assertAlmostEqual(0.18259364366531372, embedding_cu) # MEGNet embeddings have element data for elements 1-94, plus 0 for # "dummy" atoms. embedding_md = self.data_source.get_elemental_property(Element("Md"), "embedding 1") self.assertAlmostEqual(-0.044910576194524765, embedding_md) embedding_dummy = self.data_source.all_element_data["Dummy"]["embedding 1"] self.assertAlmostEqual(-0.044910576194524765, embedding_dummy)
def test_apply_transformation(self): l = Lattice.cubic(4) s_orig = Structure(l, [{"Li": 0.19, "Na": 0.19, "K": 0.62}, {"O": 1}], [[0, 0, 0], [0.5, 0.5, 0.5]]) dot = DiscretizeOccupanciesTransformation(max_denominator=5, tol=0.25) s = dot.apply_transformation(s_orig) self.assertEqual(dict(s[0].species_and_occu), {Element("Li"): 0.2, Element("Na"): 0.2, Element("K"): 0.6}) dot = DiscretizeOccupanciesTransformation(max_denominator=5, tol=0.1) self.assertRaises(RuntimeError, dot.apply_transformation, s_orig)
def setUp(self): self.Al2O3_xane_1 = XAS(Al2O3_spect['x'], Al2O3_spect['y'], Al2O3_stru, Element('Al'), 'K') self.Al2O3_xane_2 = deepcopy(self.Al2O3_xane_1) self.Al2O3_xane_2.x = self.Al2O3_xane_2.x - 40 self.Al2O3_xane_left_shift5 = deepcopy(self.Al2O3_xane_1) self.Al2O3_xane_left_shift5.x = self.Al2O3_xane_left_shift5.x - 5 self.Al2O3_xane_right_shift5 = deepcopy(self.Al2O3_xane_1) self.Al2O3_xane_right_shift5.x = self.Al2O3_xane_right_shift5.x + 5 self.LiCoO2_xane = XAS(LiCoO2_spect['x'], LiCoO2_spect['y'], LiCoO2_stru, Element('Co'), 'K')
def CalcKISC(self, atoms, coords, mesos, RingAtoms): center_coords = np.array([ np.mean([coords[meso][0] for meso in mesos]), np.mean([coords[meso][1] for meso in mesos]), np.mean([coords[meso][2] for meso in mesos]) ]) dist_vec = [] # vector of distances of atoms from the center of the ring for coord in coords: dist_vec.append(np.sqrt(np.sum(np.square(np.array(coord) - center_coords)))) ring_radius = np.mean([dist_vec[atom] for atom in RingAtoms]) # finding normal vector to the 4N plane v1 = np.array(coords[mesos[0]]) - center_coords v2 = np.array(coords[mesos[1]]) - center_coords for coord in [coords[mesos[i]] for i in range(2, len(mesos))]: if round(np.sum(v1 * v2) / (np.linalg.norm(v1) * np.linalg.norm(v2))) == 0: break else: v2 = np.array(coord) - center_coords normal_vec = np.array([ v1[1] * v2[2] - v1[2] * v2[1], v1[2] * v2[0] - v1[0] * v2[2], v1[0] * v2[1] - v1[1] * v2[0] ]) # calculating effective electric field def i1(m): return integrate.quad(lambda x: 1 / (np.power(1 - m * np.cos(x), 1.5)), 0, np.pi)[0] def i2(m): return integrate.quad(lambda x: np.cos(x) / (np.power(1 - m * np.cos(x), 1.5)), 0, np.pi)[0] field_vec = [] for dist, coord in zip(dist_vec, coords): sin = np.sum(normal_vec * (np.array(coord) - center_coords)) / (dist * np.linalg.norm(normal_vec)) cos = np.sqrt(1 - np.square(sin)) rel_dist = dist / ring_radius m = 2 * rel_dist / (np.square(rel_dist) + 1) * sin field = 24 / np.square(ring_radius) * np.sqrt((rel_dist * sin / np.power(1 + np.square(rel_dist), 1.5) * i1(m) - i2(m) / np.power(1 + np.square(rel_dist),1.5))**2 + (rel_dist * cos / np.power(1 + np.square(rel_dist),1.5) * i1(m))**2) field_vec.append(field) kISC = 0 for atom, field in zip(atoms, field_vec): Z = Element(atom).Z r = Element(atom).atomic_radius kISC = kISC + Z * (Z + np.square(r) * field) return kISC
def test_structure_to_oxidstructure(self): cscl = Structure( Lattice([[4.209, 0, 0], [0, 4.209, 0], [0, 0, 4.209]]), ["Cl", "Cs"], [[0.45, 0.5, 0.5], [0, 0, 0]]) d = {'structure': [cscl]} df = DataFrame(data=d) sto = StructureToOxidStructure() df = sto.featurize_dataframe(df, 'structure') self.assertEqual(df["structure_oxid"].tolist()[0][0].specie.oxi_state, -1) self.assertEqual(df["structure_oxid"].tolist()[0][1].specie.oxi_state, +1) sto = StructureToOxidStructure(target_col_id='structure_oxid2', oxi_states_override={ "Cl": [-2], "Cs": [+2] }) df = sto.featurize_dataframe(df, 'structure') self.assertEqual(df["structure_oxid2"].tolist()[0][0].specie.oxi_state, -2) self.assertEqual(df["structure_oxid2"].tolist()[0][1].specie.oxi_state, +2) # original is preserved self.assertEqual(df["structure"].tolist()[0][0].specie, Element("Cl")) # test in-place sto = StructureToOxidStructure(target_col_id=None, overwrite_data=True) df = sto.featurize_dataframe(df, 'structure') self.assertEqual( df["structure"].iloc[0]["structure"].iloc[0][0].specie, Element("Cl")) # test error handling test_struct = Structure([5, 0, 0, 0, 5, 0, 0, 0, 5], ['Sb', 'F', 'O'], [[0, 0, 0], [0.2, 0.2, 0.2], [0.5, 0.5, 0.5]]) df = DataFrame(data={'structure': [test_struct]}) sto = StructureToOxidStructure(return_original_on_error=False, max_sites=2) self.assertRaises(ValueError, sto.featurize_dataframe, df, 'structure') # check non oxi state structure returned correctly sto = StructureToOxidStructure(return_original_on_error=True, max_sites=2) df = sto.featurize_dataframe(df, 'structure') self.assertEqual(df["structure_oxid"].tolist()[0][0].specie, Element("Sb"))
def __str__(self): """ Returns a string representation of potential parameters to be used in the feff.inp file, determined from structure object. The lines are arranged as follows: ipot Z element lmax1 lmax2 stoichiometry spinph Returns: String representation of Atomic Coordinate Shells. """ central_element = Element(self.central_atom) ipotrow = [[0, central_element.Z, central_element.symbol, -1, -1, .0001, 0]] for el, amt in self.struct.composition.items(): ipot = self.pot_dict[el.symbol] ipotrow.append([ipot, el.Z, el.symbol, -1, -1, amt, 0]) ipot_sorted = sorted(ipotrow, key=itemgetter(0)) ipotrow = str(tabulate(ipot_sorted, headers=["*ipot", "Z", "tag", "lmax1", "lmax2", "xnatph(stoichometry)", "spinph"])) ipotlist = ipotrow.replace("--", "**") ipotlist = ''.join(["POTENTIALS\n", ipotlist]) return ipotlist
def train(self, train_structures, energies, forces, stresses=None, **kwargs): """ Training data with model. Args: train_structures ([Structure]): The list of Pymatgen Structure object. energies ([float]): The list of total energies of each structure in structures list. energies ([float]): List of total energies of each structure in structures list. forces ([np.array]): List of (m, 3) forces array of each structure with m atoms in structures list. m can be varied with each single structure case. stresses (list): List of (6, ) virial stresses of each structure in structures list. """ train_pool = pool_from(train_structures, energies, forces, stresses) _, df = convert_docs(train_pool) ytrain = df['y_orig'] / df['n'] self.model.fit(inputs=train_structures, outputs=ytrain, **kwargs) self.specie = Element(train_structures[0].symbol_set[0])
def write_cfgs(self, filename, cfg_pool): lines = [] for dataset in cfg_pool: if isinstance(dataset['structure'], dict): structure = Structure.from_dict(dataset['structure']) else: structure = dataset['structure'] energy = dataset['outputs']['energy'] forces = dataset['outputs']['forces'] virial_stress = dataset['outputs']['virial_stress'] lines.append( self._line_up(structure, energy, forces, virial_stress)) # dist = np.unique(structure.distance_matrix.ravel())[1] # if self.shortest_distance > dist: # self.shortest_distance = dist self.specie = Element(structure.symbol_set[0]) with open(filename, 'w') as f: f.write('\n'.join(lines)) return filename
def has_common_oxi_states(row): comp = Composition(row.StructuredFormula) int_comp = Composition( comp.get_integer_formula_and_factor()[0]) # get integer formular ############################################################################################### # according to the documentation of pymatgen's Composition class' oxi_state_guesses(), the default # value of the argument all_oxi_states is False, which means that it should only use most common # oxidation states of elements to make the guesses. However, it seems to be using all oxidation states. # E.g. Try the compound - KCa9V10O30, This can't be solved only with Vanadium's common oxidation state (+5) # However, this is solved by oxi_state_guesses() function, which means it's using other oxidation states as well. # Therefore, we are going to overide the elements' oxidation states with the most common oxidation states # by setting the argument oxi_states_override in oxi_state_guesses() ################################################################################################ ## create a common oxidation states dictonary to overide dic = {} for element in ElementSym('H').ox_st_dict.keys( ): # dummy element to instantiate the ElementSym class if element == 'Eu': # common and most stable ox. st. of Eu is +3, pymatgen provides both (+2 & +3). However, we select only +3 common_ox_st = (3, ) else: common_ox_st = Element(element).common_oxidation_states dic[element] = common_ox_st # return true if it could be solved using common oxi states if len(int_comp.oxi_state_guesses(oxi_states_override=dic)) > 0: return 1 else: return 0