def structure(self): lattice = self.lammps_box.lattice species = [] positions = [] for specie, charge, coords in self.atoms: positions.append(coords) if isinstance(specie, Specie): symbol = specie.element.symbol else: symbol = specie.symbol if charge: species.append(Specie(symbol, charge)) else: species.append(Element(symbol)) site_properties = {} if self.velocities: site_properties['velocities'] = self.velocities return Structure(lattice, species, positions, coords_are_cartesian=True, site_properties=site_properties)
def prune_defectsites(self, el="C", oxi_state=4, dlta=0.1): """ Prune all the defect sites which can't acoomodate the input elment with the input oxidation state. """ rad = Specie(el, oxi_state).ionic_radius - dlta self.radius_prune_defectsites(rad)
def test_get_representations(self): # tests to convert between storing magnetic moment information # on site_properties or on Specie 'spin' property # test we store magnetic moments on site properties self.Fe.add_site_property('magmom', [5]) msa = CollinearMagneticStructureAnalyzer(self.Fe) self.assertEqual(msa.structure.site_properties['magmom'][0], 5) # and that we can retrieve a spin representaiton Fe_spin = msa.get_structure_with_spin() self.assertFalse('magmom' in Fe_spin.site_properties) self.assertEqual(Fe_spin[0].specie.spin, 5) # test we can remove magnetic moment information Fe_none = msa.get_nonmagnetic_structure() self.assertFalse('magmom' in Fe_spin.site_properties) # test with disorder on magnetic site self.Fe[0] = { Specie('Fe', oxidation_state=0, properties={'spin': 5}): 0.5, 'Ni': 0.5 } self.assertRaises(NotImplementedError, CollinearMagneticStructureAnalyzer, self.Fe)
def _get_ionic_radii(self): """ Computes ionic radii of elements for all sites in the structure. """ rad_dict = {} for k, val in self._valences.items(): el = re.sub('[1-9,+,\-]', '', k) rad_dict[k] = Specie(el, val).ionic_radius if not rad_dict[el]: # get covalent radii later raise LookupError() return rad_dict
def _is_element_or_specie(s: str) -> bool: if s in ['D', 'D+', 'D-', 'T']: return True try: _ = Element(s) except ValueError: try: _ = Specie.from_string(s) except ValueError: print(s) return False return True
def _get_atomic_mass(element_or_specie: str) -> float: """ Get atomic mass from element or specie string Args: element_or_specie (str): specie or element string Returns: float mass """ try: return Element(element_or_specie).atomic_mass except Exception: return Specie.from_string(element_or_specie).element.atomic_mass
def _get_charge(element_or_specie: Union[str, Element, Specie]) -> float: """ Get charge from element or specie Args: element_or_specie (str or Element or Specie): element or specie Returns: charge float """ if isinstance(element_or_specie, Specie): return element_or_specie.oxi_state if isinstance(element_or_specie, str): try: return Specie.from_string(element_or_specie).oxi_state except Exception: return 0.0 return 0.0
def test_get_incar(self): incar = self.mpset.incar self.assertEqual(incar['LDAUU'], [5.3, 0, 0]) self.assertAlmostEqual(incar['EDIFF'], 0.0012) incar = self.mitset.incar self.assertEqual(incar['LDAUU'], [4.0, 0, 0]) self.assertAlmostEqual(incar['EDIFF'], 1e-5) si = 14 coords = list() coords.append(np.array([0, 0, 0])) coords.append(np.array([0.75, 0.5, 0.75])) # Silicon structure for testing. latt = Lattice( np.array([[3.8401979337, 0.00, 0.00], [1.9200989668, 3.3257101909, 0.00], [0.00, -2.2171384943, 3.1355090603]])) struct = Structure(latt, [si, si], coords) incar = MPRelaxSet(struct).incar self.assertNotIn("LDAU", incar) coords = list() coords.append([0, 0, 0]) coords.append([0.75, 0.5, 0.75]) lattice = Lattice([[3.8401979337, 0.00, 0.00], [1.9200989668, 3.3257101909, 0.00], [0.00, -2.2171384943, 3.1355090603]]) struct = Structure(lattice, ["Fe", "Mn"], coords) incar = MPRelaxSet(struct).incar self.assertNotIn('LDAU', incar) # check fluorides struct = Structure(lattice, ["Fe", "F"], coords) incar = MPRelaxSet(struct).incar self.assertEqual(incar['LDAUU'], [5.3, 0]) self.assertEqual(incar['MAGMOM'], [5, 0.6]) struct = Structure(lattice, ["Fe", "F"], coords) incar = MITRelaxSet(struct).incar self.assertEqual(incar['LDAUU'], [4.0, 0]) # Make sure this works with species. struct = Structure(lattice, ["Fe2+", "O2-"], coords) incar = MPRelaxSet(struct).incar self.assertEqual(incar['LDAUU'], [5.3, 0]) struct = Structure(lattice, ["Fe", "Mn"], coords, site_properties={'magmom': (5.2, -4.5)}) incar = MPRelaxSet(struct).incar self.assertEqual(incar['MAGMOM'], [-4.5, 5.2]) incar = MITRelaxSet(struct, sort_structure=False).incar self.assertEqual(incar['MAGMOM'], [5.2, -4.5]) struct = Structure(lattice, [Specie("Fe", 2, {'spin': 4.1}), "Mn"], coords) incar = MPRelaxSet(struct).incar self.assertEqual(incar['MAGMOM'], [5, 4.1]) struct = Structure(lattice, ["Mn3+", "Mn4+"], coords) incar = MITRelaxSet(struct).incar self.assertEqual(incar['MAGMOM'], [4, 3]) userset = MPRelaxSet( struct, user_incar_settings={'MAGMOM': { "Fe": 10, "S": -5, "Mn3+": 100 }}) self.assertEqual(userset.incar['MAGMOM'], [100, 0.6]) # sulfide vs sulfate test coords = list() coords.append([0, 0, 0]) coords.append([0.75, 0.5, 0.75]) coords.append([0.25, 0.5, 0]) struct = Structure(lattice, ["Fe", "Fe", "S"], coords) incar = MITRelaxSet(struct).incar self.assertEqual(incar['LDAUU'], [1.9, 0]) # Make sure Matproject sulfides are ok. self.assertNotIn('LDAUU', MPRelaxSet(struct).incar) struct = Structure(lattice, ["Fe", "S", "O"], coords) incar = MITRelaxSet(struct).incar self.assertEqual(incar['LDAUU'], [4.0, 0, 0]) # Make sure Matproject sulfates are ok. self.assertEqual(MPRelaxSet(struct).incar['LDAUU'], [5.3, 0, 0]) # test for default LDAUU value userset_ldauu_fallback = MPRelaxSet( struct, user_incar_settings={'LDAUU': { 'Fe': 5.0, 'S': 0 }}) self.assertEqual(userset_ldauu_fallback.incar['LDAUU'], [5.0, 0, 0]) # test that van-der-Waals parameters are parsed correctly incar = MITRelaxSet(struct, vdw='optB86b').incar self.assertEqual(incar['GGA'], 'Mk') self.assertEqual(incar['LUSE_VDW'], True) self.assertEqual(incar['PARAM1'], 0.1234) # Test that NELECT is updated when a charge is present si = 14 coords = list() coords.append(np.array([0, 0, 0])) coords.append(np.array([0.75, 0.5, 0.75])) # Silicon structure for testing. latt = Lattice( np.array([[3.8401979337, 0.00, 0.00], [1.9200989668, 3.3257101909, 0.00], [0.00, -2.2171384943, 3.1355090603]])) struct = Structure(latt, [si, si], coords, charge=1) mpr = MPRelaxSet(struct) self.assertEqual(mpr.incar["NELECT"], mpr.nelect + 1, "NELECT not properly set for nonzero charge")
def test_get_incar(self): incar = self.mpset.incar self.assertEqual(incar['LDAUU'], [5.3, 0, 0]) self.assertAlmostEqual(incar['EDIFF'], 0.0012) incar = self.mitset.incar self.assertEqual(incar['LDAUU'], [4.0, 0, 0]) self.assertAlmostEqual(incar['EDIFF'], 1e-5) si = 14 coords = list() coords.append(np.array([0, 0, 0])) coords.append(np.array([0.75, 0.5, 0.75])) # Silicon structure for testing. latt = Lattice( np.array([[3.8401979337, 0.00, 0.00], [1.9200989668, 3.3257101909, 0.00], [0.00, -2.2171384943, 3.1355090603]])) struct = Structure(latt, [si, si], coords) incar = MPRelaxSet(struct).incar self.assertNotIn("LDAU", incar) coords = list() coords.append([0, 0, 0]) coords.append([0.75, 0.5, 0.75]) lattice = Lattice([[3.8401979337, 0.00, 0.00], [1.9200989668, 3.3257101909, 0.00], [0.00, -2.2171384943, 3.1355090603]]) struct = Structure(lattice, ["Fe", "Mn"], coords) incar = MPRelaxSet(struct).incar self.assertNotIn('LDAU', incar) # check fluorides struct = Structure(lattice, ["Fe", "F"], coords) incar = MPRelaxSet(struct).incar self.assertEqual(incar['LDAUU'], [5.3, 0]) self.assertEqual(incar['MAGMOM'], [5, 0.6]) struct = Structure(lattice, ["Fe", "F"], coords) incar = MITRelaxSet(struct).incar self.assertEqual(incar['LDAUU'], [4.0, 0]) # Make sure this works with species. struct = Structure(lattice, ["Fe2+", "O2-"], coords) incar = MPRelaxSet(struct).incar self.assertEqual(incar['LDAUU'], [5.3, 0]) struct = Structure(lattice, ["Fe", "Mn"], coords, site_properties={'magmom': (5.2, -4.5)}) incar = MPRelaxSet(struct).incar self.assertEqual(incar['MAGMOM'], [-4.5, 5.2]) incar = MITRelaxSet(struct, sort_structure=False).incar self.assertEqual(incar['MAGMOM'], [5.2, -4.5]) struct = Structure(lattice, [Specie("Fe", 2, {'spin': 4.1}), "Mn"], coords) incar = MPRelaxSet(struct).incar self.assertEqual(incar['MAGMOM'], [5, 4.1]) struct = Structure(lattice, ["Mn3+", "Mn4+"], coords) incar = MITRelaxSet(struct).incar self.assertEqual(incar['MAGMOM'], [4, 3]) userset = MPRelaxSet( struct, user_incar_settings={'MAGMOM': { "Fe": 10, "S": -5, "Mn3+": 100 }}) self.assertEqual(userset.incar['MAGMOM'], [100, 0.6]) noencutset = MPRelaxSet(struct, user_incar_settings={'ENCUT': None}) self.assertNotIn("ENCUT", noencutset.incar) # sulfide vs sulfate test coords = list() coords.append([0, 0, 0]) coords.append([0.75, 0.5, 0.75]) coords.append([0.25, 0.5, 0]) struct = Structure(lattice, ["Fe", "Fe", "S"], coords) incar = MITRelaxSet(struct).incar self.assertEqual(incar['LDAUU'], [1.9, 0]) # Make sure Matproject sulfides are ok. self.assertNotIn('LDAUU', MPRelaxSet(struct).incar) struct = Structure(lattice, ["Fe", "S", "O"], coords) incar = MITRelaxSet(struct).incar self.assertEqual(incar['LDAUU'], [4.0, 0, 0]) # Make sure Matproject sulfates are ok. self.assertEqual(MPRelaxSet(struct).incar['LDAUU'], [5.3, 0, 0]) # test for default LDAUU value userset_ldauu_fallback = MPRelaxSet( struct, user_incar_settings={'LDAUU': { 'Fe': 5.0, 'S': 0 }}) self.assertEqual(userset_ldauu_fallback.incar['LDAUU'], [5.0, 0, 0]) # Expected to be oxide (O is the most electronegative atom) s = Structure(lattice, ["Fe", "O", "S"], coords) incar = MITRelaxSet(s).incar self.assertEqual(incar["LDAUU"], [4.0, 0, 0]) # Expected to be chloride (Cl is the most electronegative atom) s = Structure(lattice, ["Fe", "Cl", "S"], coords) incar = MITRelaxSet(s, user_incar_settings={"LDAU": True}).incar self.assertFalse("LDAUU" in incar) # LDAU = False # User set a compound to be sulfide by specifing values of "LDAUL" etc. s = Structure(lattice, ["Fe", "Cl", "S"], coords) incar = MITRelaxSet(s, user_incar_settings={ "LDAU": True, "LDAUL": { "Fe": 3 }, "LDAUU": { "Fe": 1.8 } }).incar self.assertEqual(incar["LDAUL"], [3.0, 0, 0]) self.assertEqual(incar["LDAUU"], [1.8, 0, 0]) # test that van-der-Waals parameters are parsed correctly incar = MITRelaxSet(struct, vdw='optB86b').incar self.assertEqual(incar['GGA'], 'Mk') self.assertEqual(incar['LUSE_VDW'], True) self.assertEqual(incar['PARAM1'], 0.1234) # Test that NELECT is updated when a charge is present si = 14 coords = list() coords.append(np.array([0, 0, 0])) coords.append(np.array([0.75, 0.5, 0.75])) # Silicon structure for testing. latt = Lattice( np.array([[3.8401979337, 0.00, 0.00], [1.9200989668, 3.3257101909, 0.00], [0.00, -2.2171384943, 3.1355090603]])) struct = Structure(latt, [si, si], coords, charge=1) mpr = MPRelaxSet(struct, use_structure_charge=True) self.assertEqual(mpr.incar["NELECT"], 7, "NELECT not properly set for nonzero charge") # test that NELECT does not get set when use_structure_charge = False mpr = MPRelaxSet(struct, use_structure_charge=False) self.assertFalse( "NELECT" in mpr.incar.keys(), "NELECT should not be set when " "use_structure_charge is False")
point, normal = plane_from_miller_index(site.lattice, miller_index) distance = np.dot(point - site.coords, normal) / np.linalg.norm(normal) return distance directory = 'runs/melting_point' supercell = np.array([5, 5, 5], dtype=np.int) # Inital Guess 3150 # Iter 1: 3010 K melting_point_guess = 3010 # Kelvin processors = '4' lammps_command = 'lmp_mpi' a = 4.1990858 # From evaluation of potential lattice = Lattice.from_parameters(a, a, a, 90, 90, 90) mg = Specie('Mg', 1.4) o = Specie('O', -1.4) atoms = [mg, o] sites = [[0, 0, 0], [0.5, 0.5, 0.5]] structure = Structure.from_spacegroup(225, lattice, atoms, sites) initial_structure = structure * (supercell * np.array([2, 1, 1], dtype=np.int)) sorted_structure = initial_structure.get_sorted_structure( key=partial(distance_from_miller_index, miller_index=[1, 0, 0])) num_atoms = len(sorted_structure) lammps_potentials = LammpsPotentials( pair={ (mg, mg): '1309362.2766468062 0.104 0.0', (mg, o): '9892.357 0.20199 0.0', (o, o): '2145.7345 0.3 30.2222'
def calculate_sites_order_values(molecule, site_idxs, target_species_type=None, neigh_idxs=None): """ Calculate order parameters around metal centres. Parameters ---------- molecule : :class:`pmg.Molecule` or :class:`pmg.Structure` Pymatgen (pmg) molecule/structure to analyse. site_idxs : :class:`list` of :class:`int` Atom ids of sites to calculate OP of. target_species_type : :class:`str` Target neighbour element to use in OP calculation. Defaults to :class:`NoneType` if no target species is known. neigh_idxs : :class:`list` of :class:`list` of :class:`int` Neighbours of each atom in site_idx. Ordering is important. Defaults to :class:`NoneType` for when using :class:`pmg.Structure` - i.e. a structure with a lattice. Returns ------- results : :class:`dict` Dictionary of format site_idx: dict of order parameters { `oct`: :class:`float`, `sq_plan`: :class:`float`, `q2`: :class:`float`, `q4`: :class:`float`, `q6`: :class:`float` }. """ results = {} if target_species_type is None: targ_species = None else: targ_species = Specie(target_species_type) # Define local order parameters class based on desired types. types = [ 'oct', # Octahedra OP. 'sq_plan', # Square planar envs. 'q2', # l=2 Steinhardt OP. 'q4', # l=4 Steinhardt OP. 'q6', # l=6 Steinhardt OP. ] loc_ops = LocalStructOrderParams(types=types, ) if neigh_idxs is None: for site in site_idxs: site_results = loc_ops.get_order_parameters( structure=molecule, n=site, target_spec=[targ_species]) results[site] = {i: j for i, j in zip(types, site_results)} else: for site, neigh in zip(site_idxs, neigh_idxs): site_results = loc_ops.get_order_parameters( structure=molecule, n=site, indices_neighs=neigh, target_spec=targ_species) results[site] = {i: j for i, j in zip(types, site_results)} return results