Пример #1
0
    def test_displacements(self):
        poscar = Poscar.from_file(os.path.join(test_dir, "POSCAR"))
        structures = [poscar.structure]
        displacements = np.zeros((11, *np.shape(structures[-1].frac_coords)))
        for i in range(10):
            displacement = np.random.random_sample(
                np.shape(structures[-1].frac_coords)) / 20
            new_coords = displacement + structures[-1].frac_coords
            structures.append(
                Structure(structures[-1].lattice, structures[-1].species,
                          new_coords))
            displacements[i + 1, :, :] = displacement

        traj = Trajectory.from_structures(structures, constant_lattice=True)
        traj.to_displacements()

        self.assertTrue(np.allclose(traj.frac_coords, displacements))
Пример #2
0
    def test_get_energy(self):
        coords = [[0, 0, 0], [0.75, 0.75, 0.75], [0.5, 0.5, 0.5],
                  [0.25, 0.25, 0.25]]
        lattice = Lattice([[3.0, 0.0, 0.0],
                           [1.0, 3.0, 0.00],
                           [0.00, -2.0, 3.0]])
        s = Structure(lattice,
                      [{"Si4+": 0.5, "O2-": 0.25, "P5+": 0.25},
                       {"Si4+": 0.5, "O2-": 0.25, "P5+": 0.25},
                       {"Si4+": 0.5, "O2-": 0.25, "P5+": 0.25},
                       {"Si4+": 0.5, "O2-": 0.25, "P5+": 0.25}], coords)

        m = EwaldElectrostaticModel()
        # large tolerance because scipy constants changed between 0.16.1 and 0.17
        self.assertAlmostEqual(m.get_energy(s), -59.322817600353616, 4)
        s2 = Structure.from_file(os.path.join(test_dir, "Li2O.cif"))
        self.assertAlmostEqual(m.get_energy(s2), -145.39050015844839, 4)
Пример #3
0
 def setUp(self):
     mgo_latt = [[4.212, 0, 0], [0, 4.212, 0], [0, 0, 4.212]]
     mgo_specie = ["Mg"] * 4 + ["O"] * 4
     mgo_frac_cord = [[0, 0, 0], [0.5, 0.5, 0], [0.5, 0, 0.5],
                      [0, 0.5, 0.5], [0.5, 0, 0], [0, 0.5, 0], [0, 0, 0.5],
                      [0.5, 0.5, 0.5]]
     mgo_uc = Structure(mgo_latt, mgo_specie, mgo_frac_cord, True, True)
     self.gio = GulpIO()
     gin = self.gio.keyword_line('optimise', 'conp')
     gin += self.gio.structure_lines(mgo_uc, symm_flg=False)
     #gin += self.gc.gulp_lib('catlow.lib')
     gin += "species\nMg    core  2.00000\nO core  0.86902\nO shel -2.86902\n"
     gin += "buck\n"
     gin += "Mg core O shel   946.627 0.31813  0.00000 0.0 10.0\n"
     gin += "O  shel O shel 22764.000 0.14900 27.87900 0.0 12.0\n"
     self.gin = gin
     self.gc = GulpCaller()
Пример #4
0
    def test_disordered(self):
        si = Element("Si")
        n = Element("N")
        coords = list()
        coords.append(np.array([0, 0, 0]))
        coords.append(np.array([0.75, 0.5, 0.75]))
        lattice = Lattice(
            np.array([
                [3.8401979337, 0.00, 0.00],
                [1.9200989668, 3.3257101909, 0.00],
                [0.00, -2.2171384943, 3.1355090603],
            ]))
        struct = Structure(lattice, [si, {si: 0.5, n: 0.5}], coords)
        writer = CifWriter(struct)
        ans = """# generated using pymatgen
data_Si1.5N0.5
_symmetry_space_group_name_H-M   'P 1'
_cell_length_a   3.84019793
_cell_length_b   3.84019899
_cell_length_c   3.84019793
_cell_angle_alpha   119.99999086
_cell_angle_beta   90.00000000
_cell_angle_gamma   60.00000914
_symmetry_Int_Tables_number   1
_chemical_formula_structural   Si1.5N0.5
_chemical_formula_sum   'Si1.5 N0.5'
_cell_volume   40.04479464
_cell_formula_units_Z   1
loop_
 _symmetry_equiv_pos_site_id
 _symmetry_equiv_pos_as_xyz
  1  'x, y, z'
loop_
 _atom_site_type_symbol
 _atom_site_label
 _atom_site_symmetry_multiplicity
 _atom_site_fract_x
 _atom_site_fract_y
 _atom_site_fract_z
 _atom_site_occupancy
  Si  Si0  1  0.00000000  0.00000000  0.00000000  1
  Si  Si1  1  0.75000000  0.50000000  0.75000000  0.5
  N  N2  1  0.75000000  0.50000000  0.75000000  0.5"""

        for l1, l2 in zip(str(writer).split("\n"), ans.split("\n")):
            self.assertEqual(l1.strip(), l2.strip())
Пример #5
0
    def test_get_pattern(self):
        s = self.get_structure("CsCl")
        c = NDCalculator(wavelength=1.54184)  # CuKa radiation
        nd = c.get_pattern(s, two_theta_range=(0, 90))
        # Check the first two peaks
        self.assertAlmostEqual(nd.x[0], 21.107738329639844)
        self.assertEqual(nd.hkls[0], {(1, 0, 0): 6})
        self.assertAlmostEqual(nd.d_hkls[0], 4.2089999999999996)
        self.assertAlmostEqual(nd.x[1], 30.024695921112777)
        self.assertEqual(nd.hkls[1], {(1, 1, 0): 12})
        self.assertAlmostEqual(nd.d_hkls[1], 2.976212442014178)

        s = self.get_structure("LiFePO4")
        nd = c.get_pattern(s, two_theta_range=(0, 90))
        self.assertAlmostEqual(nd.x[1], 17.03504233621785)
        self.assertAlmostEqual(nd.y[1], 46.2985965)

        s = self.get_structure("Li10GeP2S12")
        nd = c.get_pattern(s, two_theta_range=(0, 90))
        self.assertAlmostEqual(nd.x[1], 14.058274883353876)
        self.assertAlmostEqual(nd.y[1], 3.60588013)

        # Test a hexagonal structure.
        s = self.get_structure("Graphite")
        nd = c.get_pattern(s, two_theta_range=(0, 90))
        self.assertAlmostEqual(nd.x[0], 26.21057350859598)
        self.assertAlmostEqual(nd.y[0], 100)
        self.assertAlmostEqual(nd.x[2], 44.39599754)
        self.assertAlmostEqual(nd.y[2], 42.62382267)
        self.assertAlmostEqual(len(list(nd.hkls[0].keys())[0]), 4)

        # Test an exception in case of the input element is
        # not in scattering length table.
        # This curium structure is just for test, not the actual structure.
        something = Structure(Lattice.cubic(a=1), ["Cm"], [[0, 0, 0]])
        with self.assertRaises(ValueError):
            nd = c.get_pattern(something, two_theta_range=(0, 90))

        # Test with Debye-Waller factor
        s = self.get_structure("Graphite")
        c = NDCalculator(wavelength=1.54184, debye_waller_factors={'C': 1})
        nd = c.get_pattern(s, two_theta_range=(0, 90))
        self.assertAlmostEqual(nd.x[0], 26.21057350859598)
        self.assertAlmostEqual(nd.y[0], 100)
        self.assertAlmostEqual(nd.x[2], 44.39599754)
        self.assertAlmostEqual(nd.y[2], 39.471514740)
Пример #6
0
    def get_structure(atoms):
        """
        Returns pymatgen structure from JARVIS Atoms.

        Args:
            atoms: JARVIS Atoms object

        Returns:
            Equivalent pymatgen.core.structure.Structure
        """
        elements = atoms.elements
        coords = atoms.frac_coords
        lattice_mat = atoms.lattice_mat

        return Structure(
            lattice_mat, elements, coords, coords_are_cartesian=False
        )
Пример #7
0
    def test_primitive_positions(self):
        coords = [[0, 0, 0], [0.3, 0.35, 0.45]]
        s = Structure(Lattice.from_parameters(1, 2, 3, 50, 66, 88), ["Ag"] * 2,
                      coords)

        a = [[-1, 2, -3], [3, 2, -4], [1, 0, -1]]
        b = [[4, 0, 0], [1, 1, 0], [3, 0, 1]]
        c = [[2, 0, 0], [1, 3, 0], [1, 1, 1]]

        for sc_matrix in [c]:
            sc = s.copy()
            sc.make_supercell(sc_matrix)
            prim = sc.get_primitive_structure(0.01)

            self.assertEqual(len(prim), 2)
            self.assertAlmostEqual(prim.distance_matrix[0, 1],
                                   1.0203432356739286)
Пример #8
0
    def __init__(self, structure):
        """
        Removes oxidation states from a structure

        Args:
            structure:
                pymatgen.core.structure Structure object.
        """
        warnings.warn("OxidationStateRemover has been deprecated. Use "
                      "StructureEditor.remove_oxidation_states instead.")
        self._original_structure = structure
        new_species = [{
            Element(el.symbol): occu
            for el, occu in site.species_and_occu.items()
        } for site in structure]
        self._modified_structure = Structure(structure.lattice, new_species,
                                             structure.frac_coords, False)
Пример #9
0
 def test_apply_transformation(self):
     sub_dict = {1: ["Na", "K"]}
     t = MultipleSubstitutionTransformation("Li+", 0.5, sub_dict, None)
     coords = []
     coords.append([0, 0, 0])
     coords.append([0.75, 0.75, 0.75])
     coords.append([0.5, 0.5, 0.5])
     coords.append([0.25, 0.25, 0.25])
     lattice = Lattice(
         [
             [3.8401979337, 0.00, 0.00],
             [1.9200989668, 3.3257101909, 0.00],
             [0.00, -2.2171384943, 3.1355090603],
         ]
     )
     struct = Structure(lattice, ["Li+", "Li+", "O2-", "O2-"], coords)
     self.assertEqual(len(t.apply_transformation(struct, return_ranked_list=True)), 2)
Пример #10
0
    def test_apply_transformation(self):
        t = SubstitutionPredictorTransformation(threshold=1e-3, alpha=-5, lambda_table=get_table())
        coords = []
        coords.append([0, 0, 0])
        coords.append([0.75, 0.75, 0.75])
        coords.append([0.5, 0.5, 0.5])
        lattice = Lattice(
            [
                [3.8401979337, 0.00, 0.00],
                [1.9200989668, 3.3257101909, 0.00],
                [0.00, -2.2171384943, 3.1355090603],
            ]
        )
        struct = Structure(lattice, ["O2-", "Li1+", "Li1+"], coords)

        outputs = t.apply_transformation(struct, return_ranked_list=True)
        self.assertEqual(len(outputs), 4, "incorrect number of structures")
Пример #11
0
 def test_tersoff_potential(self):
     mgo_latt = [[4.212, 0, 0], [0, 4.212, 0], [0, 0, 4.212]]
     mgo_specie = ["Mg", "O"] * 4
     mgo_frac_cord = [
         [0, 0, 0],
         [0.5, 0, 0],
         [0.5, 0.5, 0],
         [0, 0.5, 0],
         [0.5, 0, 0.5],
         [0, 0, 0.5],
         [0, 0.5, 0.5],
         [0.5, 0.5, 0.5],
     ]
     mgo_uc = Structure(mgo_latt, mgo_specie, mgo_frac_cord, True, True)
     gin = self.gio.tersoff_potential(mgo_uc)
     self.assertIn("specie", gin)
     self.assertIn("Mg core", gin)
Пример #12
0
    def test_apply_transformation_mult(self):
        # Test returning multiple structures from each transformation.
        disord = Structure(
            np.eye(3) * 4.209,
            [{"Cs+": 0.5, "K+": 0.5}, "Cl-"],
            [[0, 0, 0], [0.5, 0.5, 0.5]],
        )
        disord.make_supercell([2, 2, 1])

        tl = [
            EnumerateStructureTransformation(),
            OrderDisorderedStructureTransformation(),
        ]
        t = SuperTransformation(tl, nstructures_per_trans=10)
        self.assertEqual(len(t.apply_transformation(disord, return_ranked_list=20)), 8)
        t = SuperTransformation(tl)
        self.assertEqual(len(t.apply_transformation(disord, return_ranked_list=20)), 2)
 def test_apply_transformation(self):
     t = InterstitialTransformation("Na+", [2, 2, 2])
     coords = list()
     coords.append([0, 0, 0])
     coords.append([0.75, 0.75, 0.75])
     coords.append([0.5, 0.5, 0.5])
     coords.append([0.25, 0.25, 0.25])
     lattice = Lattice([[3.8401979337, 0.00, 0.00],
                        [1.9200989668, 3.3257101909, 0.00],
                        [0.00, -2.2171384943, 3.1355090603]])
     struct = Structure(lattice, ["Li+", "Li+", "O2-", "O2-"], coords)
     scs = t.apply_transformation(struct, return_ranked_list=100000)
     #self.assertEqual(len(scs),3)
     for sc in scs:
         #print sc.composition.formula
         self.assertIn(sc['structure'].composition.formula,
                       ["Li16 O16", "Na1 Li16 O16", "Li16 Na1 O16"])
Пример #14
0
    def get_structure(atoms):
        """
        Returns pymatgen structure from ASE Atoms.

        Args:
            atoms: ASE Atoms object

        Returns:
            Equivalent pymatgen.core.structure.Structure
        """
        symbols = atoms.get_chemical_symbols()
        positions = atoms.get_positions()
        lattice = atoms.get_cell()
        return Structure(lattice,
                         symbols,
                         positions,
                         coords_are_cartesian=True)
Пример #15
0
    def setUp(self):
        """
        Setup MgO rocksalt structure for testing Vacancy
        """
        mgo_latt = [[4.212, 0, 0], [0, 4.212, 0], [0, 0, 4.212]]
        mgo_specie = ["Mg"] * 4 + ["O"] * 4
        mgo_frac_cord = [[0, 0, 0], [0.5, 0.5, 0], [0.5, 0, 0.5], [0, 0.5, 0.5],
                         [0.5, 0, 0], [0, 0.5, 0], [0, 0, 0.5], [0.5, 0.5, 0.5]]
        self._mgo_uc = Structure(mgo_latt, mgo_specie, mgo_frac_cord, True,
                                 True)

        bv = BVAnalyzer()
        self._mgo_uc = bv.get_oxi_state_decorated_structure(self._mgo_uc)
        self._mgo_val_rad_eval = ValenceIonicRadiusEvaluator(self._mgo_uc)
        self._mgo_val = self._mgo_val_rad_eval.valences
        self._mgo_rad = self._mgo_val_rad_eval.radii
        self._mgo_vac = Vacancy(self._mgo_uc, self._mgo_val, self._mgo_rad)
Пример #16
0
 def setUp(self):
     """
     Setup MgO rocksalt structure for testing Interstitial
     """
     mgo_latt = [[4.212, 0, 0], [0, 4.212, 0], [0, 0, 4.212]]
     mgo_specie = ["Mg"] * 4 + ["O"] * 4
     mgo_frac_cord = [[0, 0, 0], [0.5, 0.5, 0], [0.5, 0, 0.5], [0, 0.5, 0.5],
                      [0.5, 0, 0], [0, 0.5, 0], [0, 0, 0.5], [0.5, 0.5, 0.5]]
     self._mgo_uc = Structure(mgo_latt, mgo_specie, mgo_frac_cord, True,
                              True)
     mgo_val_rad_eval = ValenceIonicRadiusEvaluator(self._mgo_uc)
     self._mgo_val = mgo_val_rad_eval.valences
     self._mgo_rad = mgo_val_rad_eval.radii
     self._mgo_interstitial = Interstitial(
         self._mgo_uc, self._mgo_val, self._mgo_rad,
         site_type='voronoi_facecenter'
     )
Пример #17
0
 def setUp(self):
     self.silicon = Structure(
         Lattice.from_lengths_and_angles(
             [5.47, 5.47, 5.47],
             [90.0, 90.0, 90.0]),
         ["Si", "Si", "Si", "Si", "Si", "Si", "Si", "Si"],
         [[0.000000, 0.000000, 0.500000],
          [0.750000, 0.750000, 0.750000],
          [0.000000, 0.500000, 1.000000],
          [0.750000, 0.250000, 0.250000],
          [0.500000, 0.000000, 1.000000],
          [0.250000, 0.750000, 0.250000],
          [0.500000, 0.500000, 0.500000],
          [0.250000, 0.250000, 0.750000]],
         validate_proximity=False, to_unit_cell=False,
         coords_are_cartesian=False, site_properties=None)
     self.smi = StructureMotifInterstitial(self.silicon, "Si",
                                           motif_types=["tet", "oct"],
                                           op_threshs=[0.3, 0.5],
                                           dl=0.4, doverlap=1.0,
                                           facmaxdl=1.01)
     self.diamond = Structure(
         Lattice([[2.189, 0, 1.264], [0.73, 2.064, 1.264],
                  [0, 0, 2.528]]), ["C0+", "C0+"], [[2.554, 1.806, 4.423],
                                                    [0.365, 0.258, 0.632]],
         validate_proximity=False,
         to_unit_cell=False, coords_are_cartesian=True,
         site_properties=None)
     self.nacl = Structure(
         Lattice([[3.485, 0, 2.012], [1.162, 3.286, 2.012],
                  [0, 0, 4.025]]), ["Na1+", "Cl1-"], [[0, 0, 0],
                                                      [2.324, 1.643, 4.025]],
         validate_proximity=False,
         to_unit_cell=False, coords_are_cartesian=True,
         site_properties=None)
     self.cscl = Structure(
         Lattice([[4.209, 0, 0], [0, 4.209, 0], [0, 0, 4.209]]),
         ["Cl1-", "Cs1+"], [[2.105, 2.105, 2.105], [0, 0, 0]],
         validate_proximity=False, to_unit_cell=False,
         coords_are_cartesian=True, site_properties=None)
     self.square_pyramid = Structure(
         Lattice([[100, 0, 0], [0, 100, 0], [0, 0, 100]]),
         ["C", "C", "C", "C", "C", "C"], [
             [0, 0, 0], [1, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0], \
             [0, 0, 1]], validate_proximity=False, to_unit_cell=False,
         coords_are_cartesian=True, site_properties=None)
     self.trigonal_bipyramid = Structure(
         Lattice([[100, 0, 0], [0, 100, 0], [0, 0, 100]]),
         ["P", "Cl", "Cl", "Cl", "Cl", "Cl"], [
             [0, 0, 0], [0, 0, 2.14], [0, 2.02, 0], [1.74937, -1.01, 0], \
             [-1.74937, -1.01, 0], [0, 0, -2.14]], validate_proximity=False,
         to_unit_cell=False, coords_are_cartesian=True,
         site_properties=None)
Пример #18
0
    def generate_defect_structure(self, supercell=(1, 1, 1)):
        """
        Returns Defective Interstitial structure, decorated with charge
        Args:
            supercell (int, [3x1], or [[]] (3x3)): supercell integer, vector, or scaling matrix
        """
        defect_structure = self.bulk_structure.copy()
        defect_structure.make_supercell(supercell)

        # consider modifying velocity property to make sure defect site is decorated
        # consistently with bulk structure for final defect_structure
        defect_properties = self.site.properties.copy()
        if ('velocities' in self.bulk_structure.site_properties) and \
            'velocities' not in defect_properties:
            if all(vel == self.bulk_structure.site_properties['velocities'][0]
                   for vel in
                   self.bulk_structure.site_properties['velocities']):
                defect_properties[
                    'velocities'] = self.bulk_structure.site_properties[
                        'velocities'][0]
            else:
                raise ValueError(
                    "No velocity property specified for defect site and "
                    "bulk_structure velocities are not homogeneous. Please specify this "
                    "property within the initialized defect_site object.")

        #create a trivial defect structure to find where supercell transformation moves the defect site
        site_properties_for_fake_struct = {
            prop: [val]
            for prop, val in defect_properties.items()
        }
        struct_for_defect_site = Structure(
            self.bulk_structure.copy().lattice, [self.site.specie],
            [self.site.frac_coords],
            to_unit_cell=True,
            site_properties=site_properties_for_fake_struct)
        struct_for_defect_site.make_supercell(supercell)
        defect_site = struct_for_defect_site[0]

        defect_structure.append(self.site.specie.symbol,
                                defect_site.coords,
                                coords_are_cartesian=True,
                                properties=defect_site.properties)
        defect_structure.set_charge(self.charge)
        return defect_structure
Пример #19
0
    def get_minimax_rms_anonymous(self, struct1, struct2):
        """
        Performs an anonymous fitting, which allows distinct species in one
        structure to map to another. E.g., to compare if the Li2O and Na2O
        structures are similar.

        Args:
            struct1:
                1st structure
            struct2:
                2nd structure

        Returns:
            (minimax_rms, min_mapping)
            min_rms is the minimum of the max rms calculated, and min_mapping
            is the corresponding minimal species mapping that would map
            struct1 to struct2. (None, None) is returned if the minimax_rms
            exceeds the threshold.
        """
        sp1 = list(set(struct1.species_and_occu))
        sp2 = list(set(struct2.species_and_occu))

        if len(sp1) != len(sp2):
            return None, None

        latt1 = struct1.lattice
        fcoords1 = struct1.frac_coords
        min_rms = float("inf")
        min_mapping = None
        for perm in itertools.permutations(sp2):
            sp_mapping = dict(zip(sp1, perm))
            mapped_sp = [sp_mapping[site.species_and_occu] for site in struct1]
            transformed_structure = Structure(latt1, mapped_sp, fcoords1)
            rms = self.get_rms_dist(transformed_structure, struct2)
            if rms is not None:
                if min_rms > rms[1]:
                    min_rms = rms[1]
                    min_mapping = {
                        k: v
                        for k, v in sp_mapping.items() if k != v
                    }
        if min_mapping is None:
            return None, None
        else:
            return min_rms, min_mapping
Пример #20
0
    def test_properties(self):

        self.assertEqual(self.mos2_sg.name, "bonds")
        self.assertEqual(self.mos2_sg.edge_weight_name, "bond_length")
        self.assertEqual(self.mos2_sg.edge_weight_unit, "Å")
        self.assertEqual(self.mos2_sg.get_coordination_of_site(0), 6)
        self.assertEqual(len(self.mos2_sg.get_connected_sites(0)), 6)
        self.assertTrue(
            isinstance(self.mos2_sg.get_connected_sites(0)[0].site, PeriodicSite)
        )
        self.assertEqual(str(self.mos2_sg.get_connected_sites(0)[0].site.specie), "S")
        self.assertAlmostEqual(
            self.mos2_sg.get_connected_sites(0, jimage=(0, 0, 100))[0].site.frac_coords[
                2
            ],
            100.303027,
        )

        # these two graphs should be equivalent
        for n in range(len(self.bc_square_sg)):
            self.assertEqual(
                self.bc_square_sg.get_coordination_of_site(n),
                self.bc_square_sg_r.get_coordination_of_site(n),
            )

        # test we're not getting duplicate connected sites
        # thanks to Jack D. Sundberg for reporting this bug

        # known example where this bug occurred due to edge weights not being
        # bit-for-bit identical in otherwise identical edges
        nacl_lattice = Lattice(
            [
                [3.48543625, 0.0, 2.01231756],
                [1.16181208, 3.28610081, 2.01231756],
                [0.0, 0.0, 4.02463512],
            ]
        )
        nacl = Structure(nacl_lattice, ["Na", "Cl"], [[0, 0, 0], [0.5, 0.5, 0.5]])

        nacl_graph = StructureGraph.with_local_env_strategy(
            nacl, CutOffDictNN({("Cl", "Cl"): 5.0})
        )

        self.assertEqual(len(nacl_graph.get_connected_sites(1)), 12)
        self.assertEqual(len(nacl_graph.graph.get_edge_data(1, 1)), 12)
Пример #21
0
    def from_string(self, input_string):
        """
        Initialize a `Structure` object from a string with data in XSF format.
        See http://www.xcrysden.org/doc/XSF.html
        """
        # CRYSTAL                                        see (1)
        # these are primitive lattice vectors (in Angstroms)
        # PRIMVEC
        #    0.0000000    2.7100000    2.7100000         see (2)
        #    2.7100000    0.0000000    2.7100000
        #    2.7100000    2.7100000    0.0000000

        # these are conventional lattice vectors (in Angstroms)
        # CONVVEC
        #    5.4200000    0.0000000    0.0000000         see (3)
        #    0.0000000    5.4200000    0.0000000
        #    0.0000000    0.0000000    5.4200000

        # these are atomic coordinates in a primitive unit cell  (in Angstroms)
        # PRIMCOORD
        # 2 1                                            see (4)
        # 16      0.0000000     0.0000000     0.0000000  see (5)
        # 30      1.3550000    -1.3550000    -1.3550000

        lattice, coords, species = [], [], []
        lines = input_string.splitlines()

        for i in range(len(lines)):
            if "PRIMVEC" in lines[i]:
                for j in range(i + 1, i + 4):
                    lattice.append([float(c) for c in lines[j].split()])

            if "PRIMCOORD" in lines[i]:
                num_sites = int(lines[i + 1].split()[0])

                for j in range(i + 2, i + 2 + num_sites):
                    tokens = lines[j].split()
                    species.append(int(tokens[0]))
                    coords.append([float(j) for j in tokens[1:]])
                break
        else:
            raise ValueError("Invalid XSF data")

        s = Structure(lattice, species, coords, coords_are_cartesian=True)
        return XSF(s)
def centered_vacuum(struc, vacuum_thickness=10, direction=3, box=False):
    '''Function that centers structure along one, two, or all three directions with vacuum of thickness 'vacuum_thickness' on each side.
    If 'box' is set to True, then vacuum is added in all 3 directions and the enclosing box will be orthogonal (commonly used for molecules)
    Crystal 'direction' can be either an integer/string or a list containing the integers 1, 2, 3,
    or the strings 'a', 'b', 'c', or 'x', 'y', 'z'. List can be of up to length 3.
    Returns centered structure in vacuum.
    '''
    structure = struc.copy()
    #First, deal with different input parameter formats for 'direction'
    if not isinstance(direction, list):
        direction = [direction]
    try:
        direction[:] = [int(dir) - 1 for dir in direction]
    except:
        for num, i in enumerate(direction):
            if i == 'a' or i == 'x':
                direction[num] = 0
            if i == 'b' or i == 'y':
                direction[num] = 1
            if i == 'c' or i == 'z':
                direction[num] = 2
    #If box is True, set directions to all 3 directions and increase vacuum that is added temporarily
    #(to avoid overflow of atoms for small vacuum_thickness and high unit cell angles)
    if box:
        direction = list(range(3))
        vac = vacuum_thickness
        if vacuum_thickness < max(structure.lattice.abc):
            vacuum_thickness = max(structure.lattice.abc)
    #Add vacuum in all given directions and centering the structure
    for i in direction:
        structure = center_single_direction(structure, i, vacuum_thickness)
    #If box is False, done, otherwise: Restore original vacuum_thickness (stored in 'vac')
    if box:
        direction = list(range(3))
        newlatt = np.zeros((3, 3), float)
        np.fill_diagonal(
            newlatt,
            [structure.lattice.a, structure.lattice.b, structure.lattice.c])
        structure = Structure(newlatt,
                              structure.species,
                              structure.cart_coords,
                              coords_are_cartesian=True)
        for i in direction:
            structure = center_single_direction(structure, i, vac)
    return structure
Пример #23
0
    def get_band_structure(self):
        lattice = Lattice(self.header['cell'])
        structure = Structure(lattice,
                              species=self.header['symbols'],
                              coords=self.header['positions'])

        # I think this is right? Need to test somehow...
        mass_weights = 1 / np.sqrt(self.header['masses'])
        displacements = self.eigenvectors * mass_weights[np.newaxis,
                                                         np.newaxis, :,
                                                         np.newaxis]

        return PhononBandStructureSymmLine(self.qpts,
                                           self.frequencies,
                                           lattice.reciprocal_lattice,
                                           structure=structure,
                                           eigendisplacements=displacements,
                                           labels_dict=self.labels)
Пример #24
0
    def test_buckingham_potential(self):
        mgo_latt = [[4.212, 0, 0], [0, 4.212, 0], [0, 0, 4.212]]
        mgo_specie = ["Mg", 'O']*4
        mgo_frac_cord = [[0,0,0], [0.5,0,0], [0.5,0.5,0], [0,0.5,0],
                         [0.5,0,0.5], [0,0,0.5], [0,0.5,0.5], [0.5,0.5,0.5]]
        mgo_uc = Structure(mgo_latt, mgo_specie, mgo_frac_cord, True, True)
        gin = self.gio.buckingham_potential(mgo_uc)
        self.assertIn('specie', gin)
        self.assertIn('buck', gin)
        self.assertIn('spring', gin)
        self.assertIn('Mg core', gin)
        self.assertIn('O  core', gin)
        self.assertIn('O  shel', gin)

        gin = self.gio.buckingham_potential(self.structure)
        self.assertIn('specie', gin)
        self.assertIn('buck', gin)
        self.assertIn('spring', gin)
Пример #25
0
 def setUp(self):
     mgo_latt = [[4.212, 0, 0], [0, 4.212, 0], [0, 0, 4.212]]
     mgo_specie = ["Mg", "O"] * 4
     mgo_frac_cord = [
         [0, 0, 0],
         [0.5, 0, 0],
         [0.5, 0.5, 0],
         [0, 0.5, 0],
         [0.5, 0, 0.5],
         [0, 0, 0.5],
         [0, 0.5, 0.5],
         [0.5, 0.5, 0.5],
     ]
     self.mgo_uc = Structure(mgo_latt, mgo_specie, mgo_frac_cord, True, True)
     bv = BVAnalyzer()
     val = bv.get_valences(self.mgo_uc)
     el = [site.species_string for site in self.mgo_uc.sites]
     self.val_dict = dict(zip(el, val))
def test_oi_ti_bravais():
    structure = Structure(Lattice.orthorhombic(20, 8, 6),
                          species=["H"] * 2,
                          coords=[[0.0] * 3, [0.5] * 3])
    generator = StructureKpointsGenerator(structure,
                                          task=Task.structure_opt,
                                          kpt_density=5)
    generator.generate_input()

    primitive_structure = StructureSymmetrizer(structure).primitive

    expected_generator = StructureKpointsGenerator(primitive_structure,
                                                   task=Task.structure_opt,
                                                   kpt_density=5)
    expected_generator.generate_input()

    assert generator.num_kpts == expected_generator.num_kpts
    assert generator.kpoints.kpts_shift == expected_generator.kpoints.kpts_shift
def Struc_flip(struc):
    """
        Corrects the orientation of structures
    """
    struc_coords = struc.frac_coords
    z_frac_coords = struc_coords[:, 2]
    new_z_frac_coords = []
    for i in z_frac_coords:
        new_z_frac_coords.append(1 - i)

    struc_coords[:, 2] = new_z_frac_coords
    new_struc = Structure(struc.lattice.matrix,
                          species=struc.species,
                          coords=struc_coords)
    new_struc_space = SpacegroupAnalyzer(new_struc)
    new_struc_pri = new_struc_space.get_primitive_standard_structure()

    return new_struc_pri
Пример #28
0
    def test_get_vertices_dist_ang_indices(self):
        with ScratchDir("."):
            cubic_lattice = Lattice.cubic(10.0)
            species = ["Cu", "O", "O", "O", "O", "O", "O"]
            valences = "undefined"

            # First fake structure
            coords = [
                [5.0, 5.0, 5.0],
                [6.01, 5.0, 5.0],
                [5.0, 5.0, 3.96],
                [4.0, 5.0, 5.0],
                [5.0, 6.03, 5.0],
                [5.0, 3.98, 5.0],
                [5.0, 5.0, 6.05],
            ]
            fake_structure = Structure(cubic_lattice,
                                       species,
                                       coords,
                                       coords_are_cartesian=True)

            # First fake structure with a given normalized_distance_tolerance of 0.0100001
            detailed_voronoi_container = DetailedVoronoiContainer(
                structure=fake_structure,
                valences=valences,
                normalized_distance_tolerance=0.0100001,
                isites=[0],
            )
            fake_parameter_indices_list = []
            for ii in range(2, 5):
                for jj in range(7, 14):
                    fake_parameter_indices_list.append((ii, jj))
            for ii in range(5, 7):
                for jj in range(10, 14):
                    fake_parameter_indices_list.append((ii, jj))

            points = detailed_voronoi_container._get_vertices_dist_ang_indices(
                fake_parameter_indices_list)
            self.assertEqual(points[0], (2, 7))
            self.assertEqual(points[1], (4, 7))
            self.assertEqual(points[2], (4, 10))
            self.assertEqual(points[3], (6, 10))
            self.assertEqual(points[4], (6, 13))
            self.assertEqual(points[5], (2, 13))
Пример #29
0
    def test_filtering(self):
        coords = [[0, 0, 0], [0.75, 0.75, 0.75], [0.5, 0.5, 0.5],
                  [0.25, 0.25, 0.25]]
        lattice = Lattice([[3.0, 0.0, 0.0], [1.0, 3.0, 0.00],
                           [0.00, -2.0, 3.0]])
        s = Structure(lattice, [{
            "Si4+": 0.5,
            "O2-": 0.25,
            "P5+": 0.25
        }, {
            "Si4+": 0.5,
            "O2-": 0.25,
            "P5+": 0.25
        }, {
            "Si4+": 0.5,
            "O2-": 0.25,
            "P5+": 0.25
        }, {
            "Si4+": 0.5,
            "O2-": 0.25,
            "P5+": 0.25
        }], coords)

        species1 = [Specie('Si', 5), Specie('Mg', 2)]
        f1 = ContainsSpecieFilter(species1, strict_compare=True, AND=False)
        self.assertFalse(f1.test(s), 'Incorrect filter')
        f2 = ContainsSpecieFilter(species1, strict_compare=False, AND=False)
        self.assertTrue(f2.test(s), 'Incorrect filter')
        species2 = [Specie('Si', 4), Specie('Mg', 2)]
        f3 = ContainsSpecieFilter(species2, strict_compare=True, AND=False)
        self.assertTrue(f3.test(s), 'Incorrect filter')
        f4 = ContainsSpecieFilter(species2, strict_compare=False, AND=False)
        self.assertTrue(f4.test(s), 'Incorrect filter')

        species3 = [Specie('Si', 5), Specie('O', -2)]
        f5 = ContainsSpecieFilter(species3, strict_compare=True, AND=True)
        self.assertFalse(f5.test(s), 'Incorrect filter')
        f6 = ContainsSpecieFilter(species3, strict_compare=False, AND=True)
        self.assertTrue(f6.test(s), 'Incorrect filter')
        species4 = [Specie('Si', 4), Specie('Mg', 2)]
        f7 = ContainsSpecieFilter(species4, strict_compare=True, AND=True)
        self.assertFalse(f7.test(s), 'Incorrect filter')
        f8 = ContainsSpecieFilter(species4, strict_compare=False, AND=True)
        self.assertFalse(f8.test(s), 'Incorrect filter')
Пример #30
0
    def fit_anonymous_all_mapping(self, struct1, struct2):
        """
        Performs an anonymous fitting, which allows distinct species in one
        structure to map to another. Returns a dictionary of species
        substitutions that are within tolerance

        Args:
            struct1:
                1st structure
            struct2:
                2nd structure

        Returns:
            (mappings)
            mappings is a list of possible species mappings that
            would map struct1 to struct2.
        """
        sp1 = list(set(struct1.species_and_occu))
        sp2 = list(set(struct2.species_and_occu))

        if len(sp1) != len(sp2):
            return None

        latt1 = struct1.lattice
        fcoords1 = struct1.frac_coords
        mappings = []
        for perm in itertools.permutations(sp2):
            sp_mapping = dict(zip(sp1, perm))
            mapped_sp = [sp_mapping[site.species_and_occu] for site in struct1]
            transformed_structure = Structure(latt1, mapped_sp, fcoords1)
            rms = self.get_rms_dist(transformed_structure, struct2)
            if rms is not None:

                possible_mapping = {k: v for k, v in sp_mapping.items()}

                if rms[1] < self.stol:
                    #check if mapping already found
                    for k, v in possible_mapping.iteritems():
                        if {k: v} not in mappings:
                            mappings.append({k: v})
        if not mappings:
            return None
        else:
            return mappings