Пример #1
0
    def interpolate_poscar(self, fw_spec):
        # make folder for poscar interpolation start and end structure files.
        interpolate_folder = 'interpolate'
        if not os.path.exists(os.path.join(os.getcwd(), interpolate_folder)):
            os.makedirs(os.path.join(os.getcwd(), interpolate_folder))

        # use method of GrabFilesFromCalcLoc to grab files from previous locations.
        CopyFilesFromCalcLoc(calc_dir=None, calc_loc=self["start"],
                             filenames=["CONTCAR"],
                             name_prepend=interpolate_folder + os.sep,
                             name_append="_0").run_task(fw_spec=fw_spec)
        CopyFilesFromCalcLoc(calc_dir=None, calc_loc=self["end"],
                             filenames=["CONTCAR"],
                             name_prepend=interpolate_folder + os.sep,
                             name_append="_1").run_task(fw_spec=fw_spec)


        # assuming first calc_dir is polar structure for ferroelectric search
        s1 = Structure.from_file(os.path.join(interpolate_folder, "CONTCAR_0"))
        s2 = Structure.from_file(os.path.join(interpolate_folder, "CONTCAR_1"))

        structs = s1.interpolate(s2, self["nimages"], interpolate_lattices=True,
                                 autosort_tol=self.get("autosort_tol", 0.0))

        # save only the interpolation needed for this run

        i = self.get("this_image")
        return structs[i]
Пример #2
0
    def test_to_from_file_string(self):
        for fmt in ["cif", "json", "poscar", "cssr"]:
            s = self.struct.to(fmt=fmt)
            self.assertIsNotNone(s)
            ss = IStructure.from_str(s, fmt=fmt)
            self.assertArrayAlmostEqual(
                ss.lattice.lengths_and_angles,
                self.struct.lattice.lengths_and_angles, decimal=5)
            self.assertArrayAlmostEqual(ss.frac_coords, self.struct.frac_coords)
            self.assertIsInstance(ss, IStructure)

        self.struct.to(filename="POSCAR.testing")
        self.assertTrue(os.path.exists("POSCAR.testing"))
        os.remove("POSCAR.testing")

        self.struct.to(filename="Si_testing.yaml")
        self.assertTrue(os.path.exists("Si_testing.yaml"))
        s = Structure.from_file("Si_testing.yaml")
        self.assertEqual(s, self.struct)
        os.remove("Si_testing.yaml")

        self.struct.to(filename="POSCAR.testing.gz")
        s = Structure.from_file("POSCAR.testing.gz")
        self.assertEqual(s, self.struct)
        os.remove("POSCAR.testing.gz")
Пример #3
0
def relax(dim=2, submit=True, force_overwrite=False):
    """
    Writes input files and (optionally) submits a self-consistent
    relaxation. Should be run before pretty much anything else, in
    order to get the right energy and structure of the material.

    Args:
        dim (int): 2 for relaxing a 2D material, 3 for a 3D material.
        submit (bool): Whether or not to submit the job.
        force_overwrite (bool): Whether or not to overwrite files
            if an already converged vasprun.xml exists in the
            directory.
    """

    if force_overwrite or not utl.is_converged(os.getcwd()):
        directory = os.getcwd().split('/')[-1]

        # vdw_kernel.bindat file required for VDW calculations.
        if VDW_KERNEL:
            os.system('cp {} .'.format(VDW_KERNEL))
        # KPOINTS
        Kpoints.automatic_density(Structure.from_file('POSCAR'),
                                  1000).write_file('KPOINTS')

        # INCAR
        INCAR_DICT.update(
            {'MAGMOM': utl.get_magmom_string(Structure.from_file('POSCAR'))}
        )
        Incar.from_dict(INCAR_DICT).write_file('INCAR')
        # POTCAR
        utl.write_potcar()

        # Special tasks only performed for 2D materials.
        if dim == 2:
            # Ensure 20A interlayer vacuum
            utl.ensure_vacuum(Structure.from_file('POSCAR'), 20)
            # Remove all z k-points.
            kpts_lines = open('KPOINTS').readlines()
            with open('KPOINTS', 'w') as kpts:
                for line in kpts_lines[:3]:
                    kpts.write(line)
                kpts.write(kpts_lines[3].split()[0] + ' '
                           + kpts_lines[3].split()[1] + ' 1')

        # Submission script
        if dim == 2:
            binary = VASP_TWOD_BIN
        elif dim == 3:
            binary = VASP_STD_BIN
        if QUEUE_SYSTEM == 'pbs':
            utl.write_pbs_runjob(directory, 1, 16, '800mb', '6:00:00', binary)
            submission_command = 'qsub runjob'

        elif QUEUE_SYSTEM == 'slurm':
            utl.write_slurm_runjob(directory, 16, '800mb', '6:00:00', binary)
            submission_command = 'sbatch runjob'

        if submit:
            os.system(submission_command)
 def setUp(self):
     """Loading structures before tests"""
     #print "TestConnectivityMethods:setUp_"
     print "Loading structures from file"
     self.fe_structure = Structure.from_file('Fe.cif', True, True)
     self.caf2_structure = Structure.from_file('CaF2.cif', True, True)
     self.licoo2_structure = Structure.from_file('LiCoO2.cif', True, True)
     print "Structures from file loaded"
    def test_getinterpolatedposcar(self):
        nimages = 5
        this_image = 1
        autosort_tol = 0.5

        fw1 = Firework([CopyVaspOutputs(calc_dir=self.static_outdir,
                                        contcar_to_poscar=False,
                                        additional_files=["CONTCAR"]),
                        PassCalcLocs(name="fw1")], name="fw1")

        fw2 = Firework([CopyVaspOutputs(calc_dir=self.opt_outdir,
                                        contcar_to_poscar=False,
                                        additional_files=["CONTCAR"]),
                        PassCalcLocs(name="fw2")], name="fw2")

        fw3 = Firework([GetInterpolatedPOSCAR(start="fw1",
                                              end="fw2",
                                              this_image=this_image,
                                              nimages=nimages,
                                              autosort_tol=autosort_tol),
                        PassCalcLocs(name="fw3")],
                       name="fw3", parents=[fw1, fw2])
        fw4 = Firework([PassCalcLocs(name="fw4")], name="fw4", parents=fw3)

        wf = Workflow([fw1, fw2, fw3, fw4])
        self.lp.add_wf(wf)
        rapidfire(self.lp)

        fw4 = self.lp.get_fw_by_id(self.lp.get_fw_ids({"name": "fw4"})[0])

        calc_locs = fw4.spec["calc_locs"]
        self.assertTrue(os.path.exists(get_calc_loc("fw3", calc_locs)["path"] +
                                       "/POSCAR"))
        self.assertTrue(os.path.exists(get_calc_loc("fw3", calc_locs)["path"] +
                                       "/interpolate/CONTCAR_0"))
        self.assertTrue(os.path.exists(get_calc_loc("fw3", calc_locs)["path"] +
                                       "/interpolate/CONTCAR_1"))

        struct_start = Structure.from_file(get_calc_loc("fw3", calc_locs)["path"] +
                                          "/interpolate/CONTCAR_0")
        struct_end = Structure.from_file(get_calc_loc("fw3", calc_locs)["path"] +
                                         "/interpolate/CONTCAR_1")
        struct_inter = Structure.from_file(get_calc_loc("fw3", calc_locs)["path"] +
                                           "/POSCAR")

        structs = struct_start.interpolate(struct_end,
                                           nimages,
                                           interpolate_lattices=True,
                                           autosort_tol=autosort_tol)

        # Check x of 1st site.
        self.assertAlmostEqual(structs[this_image][1].coords[0],
                               struct_inter[1].coords[0])
        # Check c lattice parameter
        self.assertAlmostEqual(structs[this_image].lattice.abc[0],
                               struct_inter.lattice.abc[0])
Пример #6
0
    def setUp(self):
        self.cscl = self.get_structure("CsCl")
        self.lifepo4 = self.get_structure("LiFePO4")
        self.tei = Structure.from_file(get_path("icsd_TeI.cif"),
                                       primitive=False)
        self.LiCoO2 = Structure.from_file(get_path("icsd_LiCoO2.cif"),
                                          primitive=False)

        self.p1 = Structure(Lattice.from_parameters(3, 4, 5, 31, 43, 50),
                            ["H", "He"], [[0, 0, 0], [0.1, 0.2, 0.3]])
    def setUp(self):

        """Loading structures before tests"""
        print "Loading structures from file"
        self.fe_structure = Structure.from_file('Fe.cif', True, True)
        self.caf2_structure = Structure.from_file('CaF2.cif', True, True)
        self.licoo2_structure = Structure.from_file('LiCoO2.cif', True, True)
        self.fe_finder = econ.EffectiveCoordFinder(self.fe_structure)
        self.caf2_finder = econ.EffectiveCoordFinder(self.caf2_structure)
        self.licoo2_finder = econ.EffectiveCoordFinder(self.licoo2_structure)
        print "Structures from file loaded"
Пример #8
0
    def setUp(self):
        self.cscl = Structure.from_spacegroup(
            "Pm-3m", Lattice.cubic(4.2), ["Cs", "Cl"], [[0, 0, 0], [0.5, 0.5, 0.5]])

        self.lifepo4 = self.get_structure("LiFePO4")
        self.tei = Structure.from_file(get_path("icsd_TeI.cif"),
                                       primitive=False)
        self.LiCoO2 = Structure.from_file(get_path("icsd_LiCoO2.cif"),
                                          primitive=False)

        self.p1 = Structure(Lattice.from_parameters(3, 4, 5, 31, 43, 50),
                            ["H", "He"], [[0, 0, 0], [0.1, 0.2, 0.3]])
        self.graphite = self.get_structure("Graphite")
Пример #9
0
def get_competing_phases():
    """
    Collect the species to which the material might decompose to.

    Returns:
        A list of phases as tuples formatted as
        [(formula_1, Materials_Project_ID_1),
        (formula_2, Materials_Project_ID_2), ...]
    """

    composition = Structure.from_file('POSCAR').composition
    try:
        energy = Vasprun('vasprun.xml').final_energy
    except:
        energy = 100  # The function can work without a vasprun.xml
    entries = MPR.get_entries_in_chemsys([elt.symbol for elt in composition])
    my_entry = ComputedEntry(composition, energy)
    entries.append(my_entry)

    #pda = PDAnalyzer(PhaseDiagram(entries))
    pda = PhaseDiagram(entries)
    decomp = pda.get_decomp_and_e_above_hull(my_entry, allow_negative=True)
    competing_phases = [(entry.composition.reduced_formula, entry.entry_id)
                        for entry in decomp[0]]

    return competing_phases
Пример #10
0
    def test_substitute(self):
        structure = Structure.from_file(os.path.join(os.path.dirname(__file__),
                                                     "..", "..", "..",
                                                     "test_files", "Li2O.cif"))
        molecule = FunctionalGroups["methyl"]

        structure_copy = copy.deepcopy(structure)
        structure_copy_graph = copy.deepcopy(structure)

        sg = StructureGraph.with_local_env_strategy(structure, MinimumDistanceNN())
        sg_copy = copy.deepcopy(sg)

        # Ensure that strings and molecules lead to equivalent substitutions
        sg.substitute_group(1, molecule, MinimumDistanceNN)
        sg_copy.substitute_group(1, "methyl", MinimumDistanceNN)
        self.assertEqual(sg, sg_copy)

        # Ensure that the underlying structure has been modified as expected
        structure_copy.substitute(1, "methyl")
        self.assertEqual(structure_copy, sg.structure)

        # Test inclusion of graph dictionary
        graph_dict = {(0, 1): {"weight": 0.5},
                      (0, 2): {"weight": 0.5},
                      (0, 3): {"weight": 0.5},
                      }

        sg_with_graph = StructureGraph.with_local_env_strategy(structure_copy_graph,
                                                               MinimumDistanceNN())
        sg_with_graph.substitute_group(1, "methyl", MinimumDistanceNN,
                                       graph_dict=graph_dict)
        edge = sg_with_graph.graph.get_edge_data(11, 13)[0]
        self.assertEqual(edge["weight"], 0.5)
Пример #11
0
    def __init__(self, custom_interpreter=None, custom_test_structures=None):

        p = os.path.join(module_dir, "..", "test_structures", "human_interpreter.yaml")

        t = os.path.join(module_dir, "..", "test_structures")
        interpreter = custom_interpreter if custom_interpreter else p
        test_structures = custom_test_structures if custom_test_structures else t

        with open(interpreter) as f:
            hi = yaml.load(f)

        for k in hi.keys():

            hi[k].append(len(hi[k]))

            if custom_test_structures:
                find_structure = glob.glob(os.path.join(test_structures, k + "*"))
            else:
                find_structure = glob.glob(os.path.join(test_structures, "*", k+"*"))
            if len(find_structure)==0:
                continue

            s = Structure.from_file(find_structure[0])
            s.remove_oxidation_states()
            hi[k].append(s)

        super(HumanInterpreter, self).__init__(params=hi)
    def test_rocksalt(self):
        """Testing coordination and connectivity matrix for rock salt structure NaCl"""

        rocksalt_structure = Structure.from_file("test_structures/rocksalt.cif", True, True)

        cn_finder = EffectiveCoordFinder(rocksalt_structure)
        cns = cn_finder.get_avg_cn(radius=3.0, anions=["Cl"])
        for cation in cns:
            self.assertTrue(cation == "Na", "Na should be the only ions in rocksalt NaCl structure")
            if cation == "Na":
                self.assertEqual(round(cns[cation]), 6, "Na should be 6-fold coordinated")

        central_species = ["Na"]
        peripheral_species = ["Cl"]

        connectivity_matrix, connectivity_polyhedra = get_connectivity_matrix(
            rocksalt_structure, False, 3.0, peripheral_species, central_species
        )
        self.assertIn("Na", connectivity_matrix.keys(), "Na polyhedra not found in NaCl matrix")
        self.assertEqual(connectivity_matrix["Na"]["Na"]["point"], 6, "Na should not be point-sharing")
        self.assertEqual(connectivity_matrix["Na"]["Na"]["edge"], 12, "Na should be edge-sharing")
        self.assertEqual(connectivity_matrix["Na"]["Na"]["face"], 0, "Na should not be face-sharing")

        for poly in connectivity_polyhedra:
            self.assertIsInstance(poly, Polyhedra, "List of polyhedra includes a non-polyhedra element")
    def test_fluorite(self):
        """Testing coordination and connectivity matrix for fluorite structure CaF2"""

        caf2_structure = Structure.from_file('test_structures/fluorite.cif', True, True)

        cn_finder = EffectiveCoordFinder(caf2_structure)
        cns = cn_finder.get_avg_CN(radius=2.6, anions=['F'])
        for cation in cns:
            self.assertEqual(cation, "Ca", "Ca should be the only ions in CaF2 fluorite")
            if cation == 'Ca':
                self.assertEqual(round(cns[cation]), 8, "Ca should be 8-fold coordinated")

        central_species = ['Ca']
        peripheral_species = ['F']

        connectivity_matrix, connectivity_polyhedra = \
            get_connectivity_matrix(caf2_structure, False, 2.6, peripheral_species, central_species)

        self.assertIn('Ca', connectivity_matrix.keys(), "Ca polyhedra not found in CaF2 fluorite matrix")
        self.assertEqual(connectivity_matrix['Ca']['Ca']['point'], 0, "Ca should not be point-sharing")
        self.assertEqual(connectivity_matrix['Ca']['Ca']['edge'], 12, "Ca should be edge-sharing")
        self.assertEqual(connectivity_matrix['Ca']['Ca']['face'], 0, "Ca should not be face-sharing")

        for poly in connectivity_polyhedra:
            self.assertIsInstance(poly, Polyhedra, "List of polyhedra includes a non-polyhedra element")
Пример #14
0
    def test_kpath_generation(self):
        triclinic = [1, 2]
        monoclinic = range(3, 16)
        orthorhombic = range(16, 75)
        tetragonal = range(75, 143)
        rhombohedral = range(143, 168)
        hexagonal = range(168, 195)
        cubic = range(195, 231)
        
        species = ['K', 'La', 'Ti']
        coords = [[.345, 5, .77298], [.1345, 5.1, .77298], [.7, .8, .9]]
        for i in range(230):
            sg_num = i + 1
            if sg_num in triclinic:
                lattice = Lattice([[3.0233057319441246,0,0], [0,7.9850357844548681,0], [0,0,8.1136762279561818]])
            elif sg_num in monoclinic:
                lattice = Lattice.monoclinic(2, 9, 1, 99)
            elif sg_num in orthorhombic:
                lattice = Lattice.orthorhombic(2, 9, 1)
            elif sg_num in tetragonal:
                lattice = Lattice.tetragonal(2, 9)
            elif sg_num in rhombohedral:
                lattice = Lattice.hexagonal(2, 95)
            elif sg_num in hexagonal:
                lattice = Lattice.hexagonal(2, 9)
            elif sg_num in cubic:
                lattice = Lattice.cubic(2)
        
            struct = Structure.from_spacegroup(sg_num, lattice, species, coords)
            kpath = HighSymmKpath(struct) #Throws error if something doesn't work, causing test to fail.

        struct_file_path = os.path.join(test_dir_structs, 'ICSD_170.cif')
        struct = Structure.from_file(struct_file_path)
        hkp = HighSymmKpath(struct)
        self.assertEqual(hkp.name, 'MCLC5')
Пример #15
0
 def test_get_conversion_factor(self):
     filepath = os.path.join(test_dir, 'LiFePO4.cif')
     s = Structure.from_file(filepath)
     # large tolerance because scipy constants changed between 0.16.1 and 0.17
     self.assertAlmostEqual(41370704.343540139,
                            get_conversion_factor(s, "Li", 600),
                            delta=20)
Пример #16
0
    def test_get_slabs(self):
        gen = SlabGenerator(self.get_structure("CsCl"), [0, 0, 1], 10, 10)

        #Test orthogonality of some internal variables.
        a, b, c = gen.oriented_unit_cell.lattice.matrix
        self.assertAlmostEqual(np.dot(a, gen._normal), 0)
        self.assertAlmostEqual(np.dot(b, gen._normal), 0)

        self.assertEqual(len(gen.get_slabs()), 1)

        s = self.get_structure("LiFePO4")
        gen = SlabGenerator(s, [0, 0, 1], 10, 10)
        self.assertEqual(len(gen.get_slabs()), 5)

        self.assertEqual(len(gen.get_slabs(bonds={("P", "O"): 3})), 2)

        # There are no slabs in LFP that does not break either P-O or Fe-O
        # bonds for a miller index of [0, 0, 1].
        self.assertEqual(len(gen.get_slabs(
            bonds={("P", "O"): 3, ("Fe", "O"): 3})), 0)

        #If we allow some broken bonds, there are a few slabs.
        self.assertEqual(len(gen.get_slabs(
            bonds={("P", "O"): 3, ("Fe", "O"): 3},
            max_broken_bonds=2)), 2)

        # At this threshold, only the origin and center Li results in
        # clustering. All other sites are non-clustered. So the of
        # slabs is of sites in LiFePO4 unit cell - 2 + 1.
        self.assertEqual(len(gen.get_slabs(tol=1e-4)), 15)

        LiCoO2=Structure.from_file(get_path("icsd_LiCoO2.cif"),
                                          primitive=False)
        gen = SlabGenerator(LiCoO2, [0, 0, 1], 10, 10)
        lco = gen.get_slabs(bonds={("Co", "O"): 3})
        self.assertEqual(len(lco), 1)
        a, b, c = gen.oriented_unit_cell.lattice.matrix
        self.assertAlmostEqual(np.dot(a, gen._normal), 0)
        self.assertAlmostEqual(np.dot(b, gen._normal), 0)

        scc = Structure.from_spacegroup("Pm-3m", Lattice.cubic(3), ["Fe"],
                                        [[0, 0, 0]])
        gen = SlabGenerator(scc, [0, 0, 1], 10, 10)
        slabs = gen.get_slabs()
        self.assertEqual(len(slabs), 1)
        gen = SlabGenerator(scc, [1, 1, 1], 10, 10, max_normal_search=1)
        slabs = gen.get_slabs()
        self.assertEqual(len(slabs), 1)

        # Test whether using units of hkl planes instead of Angstroms for
        # min_slab_size and min_vac_size will give us the same number of atoms
        natoms = []
        for a in [1, 1.4, 2.5, 3.6]:
            s = Structure.from_spacegroup("Im-3m", Lattice.cubic(a), ["Fe"], [[0,0,0]])
            slabgen = SlabGenerator(s, (1,1,1), 10, 10, in_unit_planes=True,
                                    max_normal_search=2)
            natoms.append(len(slabgen.get_slab()))
        n = natoms[0]
        for i in natoms:
            self.assertEqual(n, i)
Пример #17
0
    def setUp(self):
        zno1 = Structure.from_file(get_path("ZnO-wz.cif"), primitive=False)
        zno55 = SlabGenerator(zno1, [1, 0, 0], 5, 5, lll_reduce=False,
                              center_slab=False).get_slab()

        Ti = Structure(Lattice.hexagonal(4.6, 2.82), ["Ti", "Ti", "Ti"],
                       [[0.000000, 0.000000, 0.000000],
                       [0.333333, 0.666667, 0.500000],
                       [0.666667, 0.333333, 0.500000]])

        Ag_fcc = Structure(Lattice.cubic(4.06), ["Ag", "Ag", "Ag", "Ag"],
                           [[0.000000, 0.000000, 0.000000],
                           [0.000000, 0.500000, 0.500000],
                           [0.500000, 0.000000, 0.500000],
                           [0.500000, 0.500000, 0.000000]])

        laue_groups = ["-1", "2/m", "mmm", "4/m",
                       "4/mmm", "-3", "-3m", "6/m",
                       "6/mmm", "m-3", "m-3m"]

        self.ti = Ti
        self.agfcc = Ag_fcc
        self.zno1 = zno1
        self.zno55 = zno55
        self.h = Structure(Lattice.cubic(3), ["H"],
                            [[0, 0, 0]])
        self.libcc = Structure(Lattice.cubic(3.51004), ["Li", "Li"],
                               [[0, 0, 0], [0.5, 0.5, 0.5]])
        self.laue_groups = laue_groups
Пример #18
0
def asabistructure(obj):
    """
    Convert obj into an AbiStructure object. Accepts:

        - AbiStructure instance
        - Subinstances of pymatgen.
        - File paths
    """
    if isinstance(obj, AbiStructure):
        return obj

    if isinstance(obj, Structure):
        # Promote
        return AbiStructure(obj)

    if is_string(obj):
        # Handle file paths.
        if os.path.isfile(obj):

            if obj.endswith(".nc"):
                structure = structure_from_etsf_file(obj)
            else:
                structure = Structure.from_file(obj)

            # Promote
            return AbiStructure(structure)

    raise ValueError("Don't know how to convert object %s to an AbiStructure structure" % str(obj))
Пример #19
0
    def test_previous_reconstructions(self):

        # Test to see if we generated all reconstruction
        # types correctly and nothing changes

        m = StructureMatcher()
        for n in self.rec_archive.keys():
            if "base_reconstruction" in self.rec_archive[n].keys():
                arch = self.rec_archive[
                    self.rec_archive[n]["base_reconstruction"]]
                sg = arch["spacegroup"]["symbol"]
            else:
                sg = self.rec_archive[n]["spacegroup"]["symbol"]
            if sg == "Fm-3m":
                rec = ReconstructionGenerator(self.Ni, 20, 20, n)
                el = self.Ni[0].species_string
            elif sg == "Im-3m":
                rec = ReconstructionGenerator(self.Fe, 20, 20, n)
                el = self.Fe[0].species_string
            elif sg == "Fd-3m":
                rec = ReconstructionGenerator(self.Si, 20, 20, n)
                el = self.Si[0].species_string

            slabs = rec.build_slabs()
            s = Structure.from_file(get_path(os.path.join("reconstructions",
                                                          el + "_" + n + ".cif")))
            self.assertTrue(any(
                [len(m.group_structures([s, slab])) == 1 for slab in slabs]))
    def test_sio2(self):
        """Testing coordination and connectivity matrix for SiO2 structure"""

        sio2_structure = Structure.from_file("test_structures/SiO2.cif", True, True)

        cn_finder = EffectiveCoordFinder(sio2_structure)
        cns = cn_finder.get_avg_cn(radius=2.6, anions=["O"])
        for cation in cns:
            self.assertTrue(cation == "Si", "Si should be the only ions in SiO2 structure")
            if cation == "Si":
                self.assertEqual(round(cns[cation]), 4, "Si should be 6-fold coordinated")

        central_species = ["Si"]
        peripheral_species = ["O"]

        connectivity_matrix, connectivity_polyhedra = get_connectivity_matrix(
            sio2_structure, False, 2.6, peripheral_species, central_species
        )
        self.assertIn("Si", connectivity_matrix.keys(), "Si polyhedra not found in SiO2 matrix")
        self.assertEqual(connectivity_matrix["Si"]["Si"]["point"], 4, "Si should not be point-sharing")
        self.assertEqual(connectivity_matrix["Si"]["Si"]["edge"], 0, "Si should be edge-sharing")
        self.assertEqual(connectivity_matrix["Si"]["Si"]["face"], 0, "Si should not be face-sharing")

        for poly in connectivity_polyhedra:
            self.assertIsInstance(poly, Polyhedra, "List of polyhedra includes a non-polyhedra element")
Пример #21
0
def get_convergence_data(jfile, params = ['ENCUT','KPOINTS']):
    """
    returns data dict in the following format
    {'Al':
          {'ENCUT': [ [500,1.232], [600,0.8798] ], 
            'KPOINTS':[ [], [] ]
          },
     'W': ...
    }

    Note: processes only INCAR parmaters and KPOINTS
    """
    cutoff_jobs = jobs_from_file(jfile)
    data = {}
    for j in cutoff_jobs:
        jdir = os.path.join(j.parent_job_dir, j.job_dir)
        poscar_file = os.path.join(jdir, 'POSCAR')
        struct_m = Structure.from_file(poscar_file)
        species = ''.join([tos.symbol for tos in struct_m.types_of_specie])
        if data.get(species):
            for p in params:
                if j.vis.incar.get(p):
                    data[species][p].append( [ j.vis.incar[p],
                                               j.final_energy/len(struct_m) ] )
                elif p == 'KPOINTS':
                    data[species]['KPOINTS'].append( [ j.vis.kpoints.kpts,
                                                       j.final_energy/len(struct_m) ] )
                else:
                    logger.warn('dont know how to parse the parameter {}'.format(p))
        else:
            data[species] = {}
            for p in params:
                data[species][p] = []
                data[species][p] = []
    return data    
    def test_corundum(self):
        """Testing coordination and connectivity matrix for corundum structure Cr2O3"""

        corundum_structure = Structure.from_file('test_structures/corundum.cif', True, True)

        cn_finder = EffectiveCoordFinder(corundum_structure)
        cns = cn_finder.get_avg_CN(radius=2.6, anions=['O'])
        for cation in cns:
            self.assertTrue(cation == "Cr", "Cr should be the only ions in corundum Cr2O3")
            if cation == 'Cr':
                self.assertEqual(round(cns[cation]), 6, "Cr should be 6-fold coordinated")

        central_species = ['Cr']
        peripheral_species = ['O']

        connectivity_matrix, connectivity_polyhedra = \
            get_connectivity_matrix(corundum_structure, False, 2.6, peripheral_species, central_species)

        self.assertIn('Cr', connectivity_matrix.keys(), "Cr polyhedra not found in corundum Cr2O3 matrix")
        self.assertEqual(connectivity_matrix['Cr']['Cr']['point'], 9, "Cr should be point-sharing")
        self.assertEqual(connectivity_matrix['Cr']['Cr']['edge'], 3, "Cr should be edge-sharing")
        self.assertEqual(connectivity_matrix['Cr']['Cr']['face'], 1, "Cr should be face-sharing")

        for poly in connectivity_polyhedra:
            self.assertIsInstance(poly, Polyhedra, "List of polyhedra includes a non-polyhedra element")
Пример #23
0
def get_spacing(filename='POSCAR', cut=0.9):
    """
    Returns the interlayer spacing for a 2D material.

    Args:
        filename (str): 'CONTCAR' or 'POSCAR', whichever file to
            check.
        cut (float): a fractional z-coordinate that must be within
            the vacuum region.

    Returns:
        float. Spacing in Angstroms.
    """

    structure = Structure.from_file('POSCAR')

    lines = open(filename).readlines()
    c_axis = lines[4].split()
    lattice_parameter = lines[1].split()
    split_coords = [line.split() for line in lines[8:8+structure.num_sites]]
    z_coords = list()
    for coord in split_coords:
        z_coord = float(coord[2])
        if z_coord > cut:
            z_coord -= 1
        z_coords.append(z_coord)
    max_height = max([z_height for z_height in z_coords])
    min_height = min([z_height for z_height in z_coords])
    spacing = ((1.0 + min_height) - max_height) * abs(float(c_axis[2]))\
        * float(lattice_parameter[0])

    return spacing
Пример #24
0
def get_convergence_data(jfile):
    """
    returns data dict in the following format
    {'Al':
          {'ENCUT': [ [500,1.232], [600,0.8798] ], 
            'KPOINTS':[ [], [] ]
          },
     'W': ...
    }

    Note: only ENCUT and KPOINTS
    """
    cutoff_jobs = jobs_from_file(jfile)
    data = {}
    for j in cutoff_jobs:
        jdir = os.path.join(j.parent_job_dir, j.job_dir)
        poscar_file = os.path.join(jdir, 'POSCAR')
        struct_m = Structure.from_file(poscar_file)
        species = ''.join([tos.symbol for tos in struct_m.types_of_specie])
        # energy / atom
        if data.get(species):
            data[species]['ENCUT'].append([j.vis.incar['ENCUT'],j.final_energy/len(struct_m)])
            data[species]['KPOINTS'].append([j.vis.kpoints.kpts,j.final_energy/len(struct_m)])
        else:
            data[species] = {}
            data[species]['ENCUT'] = []
            data[species]['KPOINTS'] = []
    return data    
Пример #25
0
def get_hull_distance(competing_phase_directory='../competing_phases'):
    """
    Calculate the material's distance to the thermodynamic hull,
    based on species in the Materials Project database.

    Args:
        competing_phase_directory (str): absolute or relative path
            to the location where your competing phases have been
            relaxed. The default expectation is that they are stored
            in a directory named 'competing_phases' at the same level
            as your material's relaxation directory.
    Returns:
        float. distance (eV/atom) between the material and the
            hull.
    """

    finished_competitors = {}
    original_directory = os.getcwd()
    # Determine which competing phases have been relaxed in the current
    # framework and store them in a dictionary ({formula: entry}).
    if os.path.isdir(competing_phase_directory):
        os.chdir(competing_phase_directory)
        for comp_dir in [
            dir for dir in os.listdir(os.getcwd()) if os.path.isdir(dir) and
            is_converged(dir)
                ]:
            vasprun = Vasprun('{}/vasprun.xml'.format(comp_dir))
            composition = vasprun.final_structure.composition
            energy = vasprun.final_energy
            finished_competitors[comp_dir] = ComputedEntry(composition, energy)
        os.chdir(original_directory)
    else:
        raise ValueError('Competing phase directory does not exist.')

    composition = Structure.from_file('POSCAR').composition
    try:
        energy = Vasprun('vasprun.xml').final_energy
    except:
        raise ValueError('This directory does not have a converged vasprun.xml')
    my_entry = ComputedEntry(composition, energy)  # 2D material
    entries = MPR.get_entries_in_chemsys(
        [elt.symbol for elt in composition]
        )

    # If the energies of competing phases have been calculated in
    # the current framework, put them in the phase diagram instead
    # of the MP energies.
    for i in range(len(entries)):
        formula = entries[i].composition.reduced_formula
        if formula in finished_competitors:
            entries[i] = finished_competitors[formula]
        else:
            entries[i] = ComputedEntry(entries[i].composition, 100)

    entries.append(my_entry)  # 2D material

    pda = PDAnalyzer(PhaseDiagram(entries))
    decomp = pda.get_decomp_and_e_above_hull(my_entry, allow_negative=True)

    return decomp[1]
Пример #26
0
    def find_structure(self, filename_or_structure):
        """
        Finds matching structures on the Materials Project site.

        Args:
            filename_or_structure: filename or Structure object

        Returns:
            A list of matching structures.

        Raises:
            MPRestError
        """
        try:
            if isinstance(filename_or_structure, string_types):
                s = Structure.from_file(filename_or_structure)
            elif isinstance(filename_or_structure, Structure):
                s = filename_or_structure
            else:
                raise MPRestError("Provide filename or Structure object.")
            payload = {'structure': json.dumps(s.as_dict(), cls=MontyEncoder)}
            response = self.session.post(
                '{}/find_structure'.format(self.preamble), data=payload
            )
            if response.status_code in [200, 400]:
                resp = json.loads(response.text, cls=MontyDecoder)
                if resp['valid_response']:
                    return resp['response']
                else:
                    raise MPRestError(resp["error"])
            raise MPRestError("REST error with status code {} and error {}"
                              .format(response.status_code, response.text))
        except Exception as ex:
            raise MPRestError(str(ex))
Пример #27
0
def plot_local_potential(axis=2, ylim=(-20, 0), fmt='pdf'):
    """
    Plot data from the LOCPOT file along any of the 3 primary axes.
    Useful for determining surface dipole moments and electric
    potentials on the interior of the material.

    Args:
        axis (int): 0 = x, 1 = y, 2 = z
        ylim (tuple): minimum and maximum potentials for the plot's y-axis.
        fmt (str): matplotlib format style. Check the matplotlib docs
            for options.
    """

    ax = plt.figure(figsize=(16, 10)).gca()

    locpot = Locpot.from_file('LOCPOT')
    structure = Structure.from_file('CONTCAR')
    vd = VolumetricData(structure, locpot.data)
    abs_potentials = vd.get_average_along_axis(axis)
    vacuum_level = max(abs_potentials)

    vasprun = Vasprun('vasprun.xml')
    bs = vasprun.get_band_structure()
    if not bs.is_metal():
        cbm = bs.get_cbm()['energy'] - vacuum_level
        vbm = bs.get_vbm()['energy'] - vacuum_level

    potentials = [potential - vacuum_level for potential in abs_potentials]
    axis_length = structure.lattice._lengths[axis]
    positions = np.arange(0, axis_length, axis_length / len(potentials))

    ax.plot(positions, potentials, linewidth=2, color='k')

    ax.set_xlim(0, axis_length)
    ax.set_ylim(ylim[0], ylim[1])

    ax.set_xticklabels(
        [r'$\mathrm{%s}$' % tick for tick in ax.get_xticks()], size=20)
    ax.set_yticklabels(
        [r'$\mathrm{%s}$' % tick for tick in ax.get_yticks()], size=20)
    ax.set_xlabel(r'$\mathrm{\AA}$', size=24)
    ax.set_ylabel(r'$\mathrm{V\/(eV)}$', size=24)

    if not bs.is_metal():
        ax.text(ax.get_xlim()[1], cbm, r'$\mathrm{CBM}$',
                horizontalalignment='right', verticalalignment='bottom',
                size=20)
        ax.text(ax.get_xlim()[1], vbm, r'$\mathrm{VBM}$',
                horizontalalignment='right', verticalalignment='top', size=20)
        ax.fill_between(ax.get_xlim(), cbm, ax.get_ylim()[1],
                        facecolor=plt.cm.jet(0.3), zorder=0, linewidth=0)
        ax.fill_between(ax.get_xlim(), ax.get_ylim()[0], vbm,
                        facecolor=plt.cm.jet(0.7), zorder=0, linewidth=0)

    if fmt == "None":
        return ax
    else:
        plt.savefig('locpot.{}'.format(fmt))
    plt.close()
Пример #28
0
 def setUp(self):
     # This is a CHGCAR_sum file with reduced grid size
     chgcar_path = os.path.join(test_dir, "CHGCAR.FePO4")
     chg_FePO4 = Chgcar.from_file(chgcar_path)
     self.chgcar_path = chgcar_path
     self.chg_FePO4 = chg_FePO4
     self.ca_FePO4 = ChargeDensityAnalyzer(chg_FePO4)
     self.s_LiFePO4 = Structure.from_file(os.path.join(test_dir, "LiFePO4.cif"))
Пример #29
0
 def test_calculate_vol(self):
     s = Structure.from_file(os.path.join(test_dir, "LiFePO4.cif"))
     a = TopographyAnalyzer(s, framework_ions=["O"],
                            cations=["P", "Fe"], check_volume=False)
     coords = [s[i].coords for i in [20, 23, 25, 17, 24, 19]]
     vol = calculate_vol(coords=coords)
     vol_expected = 12.8884  # LiO6 volume calculated by VESTA
     self.assertAlmostEqual(vol, vol_expected, 4)
Пример #30
0
 def test_get_orthogonal_c_slab(self):
     TeI = Structure.from_file(get_path("icsd_TeI.cif"),
                               primitive=False)
     trclnc_TeI = SlabGenerator(TeI, (0, 0, 1), 10, 10)
     TeI_slabs = trclnc_TeI.get_slabs()
     slab = TeI_slabs[0]
     norm_slab = slab.get_orthogonal_c_slab()
     self.assertAlmostEqual(norm_slab.lattice.angles[0], 90)
     self.assertAlmostEqual(norm_slab.lattice.angles[1], 90)
Пример #31
0
        def callback_update_structure(contents, filename, last_modified):

            if not contents:
                raise PreventUpdate

            # assume we only want the first input for now
            content_type, content_string = contents.split(",")
            decoded_contents = b64decode(content_string)

            error = None
            struct_or_mol = None

            # necessary to write to file so pymatgen's filetype detection can work
            with NamedTemporaryFile(suffix=filename) as tmp:
                tmp.write(decoded_contents)
                tmp.flush()
                try:
                    struct_or_mol = Structure.from_file(tmp.name)
                except:
                    try:
                        struct_or_mol = Molecule.from_file(tmp.name)
                    except:
                        try:
                            struct_or_mol = Chgcar.from_file(tmp.name)
                        except:
                            # TODO: fix these horrible try/excepts, loadfn may be dangerous
                            try:
                                struct_or_mol = loadfn(tmp.name)
                            except:
                                error = (
                                    "Could not parse uploaded file. "
                                    "If this seems like a bug, please report it. "
                                    "Crystal Toolkit understands all crystal "
                                    "structure file types and molecule file types "
                                    "supported by pymatgen.")

            return {"data": struct_or_mol, "error": error}
Пример #32
0
 def __getitem__(self, idx):
     cif_id, target = self.id_prop_data[idx]
     crystal = Structure.from_file(
         os.path.join(self.root_dir, cif_id + ".cif"))
     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, nbr_fea = [], []
     for nbr in all_nbrs:
         if len(nbr) < self.max_num_nbr:
             warnings.warn("{} not find enough neighbors to build graph. "
                           "If it happens frequently, consider increase "
                           "radius.".format(cif_id))
             nbr_fea_idx.append(
                 list(map(lambda x: x[2], nbr)) + [0] *
                 (self.max_num_nbr - len(nbr)))
             nbr_fea.append(
                 list(map(lambda x: x[1], nbr)) + [self.radius + 1.0] *
                 (self.max_num_nbr - len(nbr)))
             if self.store_bad_indices:
                 self.bad_indices.add(idx)
         else:
             nbr_fea_idx.append(
                 list(map(lambda x: x[2], nbr[:self.max_num_nbr])))
             nbr_fea.append(
                 list(map(lambda x: x[1], nbr[:self.max_num_nbr])))
     nbr_fea_idx, nbr_fea = np.array(nbr_fea_idx), np.array(nbr_fea)
     nbr_fea = self.gdf.expand(nbr_fea)
     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
Пример #33
0
def def_energy(vac=[]):
    """
    Calculation of vacancy formation energies

    Args:
        vac: list of Poscar vacancy structure objects
    Returns:
          def_list: list of defect energies
          def_header_list: list of defect names
    """

    def_list=[]
    header_list=[]
    fi=str('DEF.INFO')
    f=open(fi,'w')
    for v in vac:
        enp,contc=smart_converge(mat=v)
        #enp,contc=run_job(mat=v,incar=incar,kpoints=kpoints,jobname=str(v.comment))
        strt=Structure.from_file(contc)
        comm=str(v.comment)
        print ("running def_energy for =",comm)
        header_list.append(comm)
        if comm.split('@')[0]=='bulk':
           gs_energy=float(enp)*float(strt.composition.num_atoms)
           print ("in def_energy gs_energy for",comm, gs_energy)
        else:
           chem_pot=sum_chem_pot(strt)
           if comm.startswith("intl"):
              chem_pot=0.0-float(chem_pot)
           def_en=(float(enp)*float(strt.composition.num_atoms))-float(gs_energy)+chem_pot
           print ("in def_energy def_en for",comm, def_en,"chem_pot",chem_pot)
           def_list.append(def_en)
           print (v.comment,'=',def_en)
           line= str(v.comment)+str('=')+str(def_en)+'\n'
           f.write(line)
    f.close()
    return def_list,header_list
Пример #34
0
	def __getitem__(self, idx):
		data_row = self.id_prop_data[idx]
		cif_id = str(int(float(data_row.pop(0))))
		# At this point we have a list of strings each with some decimal value of a property or None.
		# To represent None in float datatype while converting we use float("inf")
		targets = [float(x) if x else float("inf") for x in data_row]
		crystal = Structure.from_file(os.path.join(self.root_dir,
												   cif_id+'.cif'))
		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, nbr_fea = [], []
		for nbr in all_nbrs:
			if len(nbr) < self.max_num_nbr:
				warnings.warn('{} not find enough neighbors to build graph. '
							  'If it happens frequently, consider increase '
							  'radius.'.format(cif_id))
				nbr_fea_idx.append(list(map(lambda x: x[2], nbr)) +
								   [0] * (self.max_num_nbr - len(nbr)))
				nbr_fea.append(list(map(lambda x: x[1], nbr)) +
							   [self.radius + 1.] * (self.max_num_nbr -
													 len(nbr)))
			else:
				nbr_fea_idx.append(list(map(lambda x: x[2],
											nbr[:self.max_num_nbr])))
				nbr_fea.append(list(map(lambda x: x[1],
										nbr[:self.max_num_nbr])))
		nbr_fea_idx, nbr_fea = np.array(nbr_fea_idx), np.array(nbr_fea)
		nbr_fea = self.gdf.expand(nbr_fea)
		atom_fea = torch.Tensor(atom_fea)
		nbr_fea = torch.Tensor(nbr_fea)
		nbr_fea_idx = torch.LongTensor(nbr_fea_idx)
		targets = torch.Tensor(targets)
		return (atom_fea, nbr_fea, nbr_fea_idx), targets, cif_id
Пример #35
0
def get_convergence_data(jfile, params=['ENCUT', 'KPOINTS']):
    """
    returns data dict in the following format
    {'Al':
          {'ENCUT': [ [500,1.232], [600,0.8798] ], 
            'KPOINTS':[ [], [] ]
          },
     'W': ...
    }

    Note: processes only INCAR parmaters and KPOINTS
    """
    cutoff_jobs = jobs_from_file(jfile)
    data = {}
    for j in cutoff_jobs:
        jdir = os.path.join(j.parent_job_dir, j.job_dir)
        poscar_file = os.path.join(jdir, 'POSCAR')
        struct_m = Structure.from_file(poscar_file)
        species = ''.join([tos.symbol for tos in struct_m.types_of_specie])
        if data.get(species):
            for p in params:
                if j.vis.incar.get(p):
                    data[species][p].append(
                        [j.vis.incar[p], j.final_energy / len(struct_m)])
                elif p == 'KPOINTS':
                    data[species]['KPOINTS'].append(
                        [j.vis.kpoints.kpts, j.final_energy / len(struct_m)])
                else:
                    logger.warn(
                        'dont know how to parse the parameter {}'.format(p))
        else:
            data[species] = {}
            for p in params:
                data[species][p] = []
                data[species][p] = []
    return data
Пример #36
0
    def setUp(self):
        zno1 = Structure.from_file(get_path("ZnO-wz.cif"), primitive=False)
        zno55 = SlabGenerator(zno1, [1, 0, 0], 5, 5, lll_reduce=False,
                              center_slab=False).get_slab()

        Ti = Structure(Lattice.hexagonal(4.6, 2.82), ["Ti", "Ti", "Ti"],
                       [[0.000000, 0.000000, 0.000000],
                        [0.333333, 0.666667, 0.500000],
                        [0.666667, 0.333333, 0.500000]])

        Ag_fcc = Structure(Lattice.cubic(4.06), ["Ag", "Ag", "Ag", "Ag"],
                           [[0.000000, 0.000000, 0.000000],
                            [0.000000, 0.500000, 0.500000],
                            [0.500000, 0.000000, 0.500000],
                            [0.500000, 0.500000, 0.000000]])

        self.ti = Ti
        self.agfcc = Ag_fcc
        self.zno1 = zno1
        self.zno55 = zno55
        self.h = Structure(Lattice.cubic(3), ["H"],
                           [[0, 0, 0]])
        self.libcc = Structure(Lattice.cubic(3.51004), ["Li", "Li"],
                               [[0, 0, 0], [0.5, 0.5, 0.5]])
Пример #37
0
 def write_INCAR(
     self,
     incar_input: str = "INCAR",
     incar_output: str = "INCAR.lobster",
     poscar_input: str = "POSCAR",
     isym: int = -1,
     further_settings: dict = None,
 ):
     """
     Will only make the run static, insert nbands, make ISYM=-1, set LWAVE=True and write a new INCAR.
     You have to check for the rest.
     Args:
         incar_input (str): path to input INCAR
         incar_output (str): path to output INCAR
         poscar_input (str): path to input POSCAR
         isym (int): isym equal to -1 or 0 are possible. Current Lobster version only allow -1.
         further_settings (dict): A dict can be used to include further settings, e.g. {"ISMEAR":-5}
     """
     # reads old incar from file, this one will be modified
     incar = Incar.from_file(incar_input)
     warnings.warn("Please check your incar_input before using it. This method only changes three settings!")
     if isym == -1:
         incar["ISYM"] = -1
     elif isym == 0:
         incar["ISYM"] = 0
     else:
         ValueError("isym has to be -1 or 0.")
     incar["NSW"] = 0
     incar["LWAVE"] = True
     # get nbands from _get_nbands (use basis set that is inserted)
     incar["NBANDS"] = self._get_nbands(Structure.from_file(poscar_input))
     if further_settings is not None:
         for key, item in further_settings.items():
             incar[key] = further_settings[key]
     # print it to file
     incar.write_file(incar_output)
Пример #38
0
    def test_znucl_typat(self):
        """Test the order of typat and znucl in the Abinit input and enforce_typat, enforce_znucl."""

        # Ga  Ga1  1  0.33333333333333  0.666666666666667  0.500880  1.0
        # Ga  Ga2  1  0.66666666666667  0.333333333333333  0.000880  1.0
        # N  N3  1  0.333333333333333  0.666666666666667  0.124120  1.0
        # N  N4  1  0.666666666666667  0.333333333333333  0.624120  1.0
        gan = Structure.from_file(
            os.path.join(PymatgenTest.TEST_FILES_DIR, "abinit", "gan.cif"))

        # By default, znucl is filled using the first new type found in sites.
        def_vars = structure_to_abivars(gan)
        def_znucl = def_vars["znucl"]
        self.assertArrayEqual(def_znucl, [31, 7])
        def_typat = def_vars["typat"]
        self.assertArrayEqual(def_typat, [1, 1, 2, 2])

        # But it's possible to enforce a particular value of typat and znucl.
        enforce_znucl = [7, 31]
        enforce_typat = [2, 2, 1, 1]
        enf_vars = structure_to_abivars(gan,
                                        enforce_znucl=enforce_znucl,
                                        enforce_typat=enforce_typat)
        self.assertArrayEqual(enf_vars["znucl"], enforce_znucl)
        self.assertArrayEqual(enf_vars["typat"], enforce_typat)
        self.assertArrayEqual(def_vars["xred"], enf_vars["xred"])

        assert [s.symbol for s in species_by_znucl(gan)] == ["Ga", "N"]

        for itype1, itype2 in zip(def_typat, enforce_typat):
            assert def_znucl[itype1 - 1] == enforce_znucl[itype2 - 1]

        with self.assertRaises(Exception):
            structure_to_abivars(gan,
                                 enforce_znucl=enforce_znucl,
                                 enforce_typat=None)
Пример #39
0
def surf_energy(surf=[]):
    """
    Helper function for surface energies

    Args:
        surf: list of Poscar surface objects
    Returns:
          surf_list: list of surface energies
          surf_header_list: list of surface names
          
    """

    surf_list = []
    surf_header_list = []
    fi = str('SURF.INFO')
    f = open(fi, 'w')
    for s in surf:
        enp, contc = smart_converge(mat=s)
        strt = Structure.from_file(contc)
        m = strt.lattice.matrix
        if s.comment.split('@')[0] == 'sbulk':

            gs_energy = enp
            print("in surf_energy gs_energy for", s.comment, gs_energy)
        else:
            surf_en = 16 * (
                float(enp) * (strt.composition.num_atoms) -
                float(strt.composition.num_atoms) * float(gs_energy)) / (
                    2 * np.linalg.norm(np.cross(m[0], m[1])))
            print("in surf_energy surf_en for", s.comment, surf_en)
            surf_list.append(surf_en)
            print(s.comment, '=', surf_en)
            line = str(s.comment) + str('=') + str(surf_en) + '\n'
            f.write(line)
    f.close()
    return surf_list, surf_header_list
Пример #40
0
    def run_task(self, fw_spec):

        potcar_spec = self.get("potcar_spec", False)
        vasp_input_set_params = self.get("vasp_input_set_params") or {}

        # update the bandgap based on output from the previous calculation,
        # unless the user specified a bandgap via vasp_input_set_params
        if vasp_input_set_params.get("bandgap") is None:
            # First look for the gga_bandgap key in the FW spec, to save parsing time
            if fw_spec.get("gga_bandgap") is not None:
                vasp_input_set_params["bandgap"] = fw_spec.get("gga_bandgap")
            # If not found, parse the files from the previous calc to find the bandgap
            else:
                parse_potcar_file = not potcar_spec
                vasprun = Vasprun("vasprun.xml", parse_potcar_file=parse_potcar_file)
                bandgap = vasprun.eigenvalue_band_properties[0]
                vasp_input_set_params["bandgap"] = bandgap

        # read the structure from the output of the previous calculation
        structure = Structure.from_file("POSCAR")

        vis = MPScanRelaxSet(structure, **vasp_input_set_params)

        vis.write_input(".", potcar_spec=potcar_spec)
Пример #41
0
def compare_structures(args):
    """
    Compare structures in files for similarity using structure matcher.

    Args:
        args (dict): Args from argparse.
    """
    filenames = args.filenames
    if len(filenames) < 2:
        print("You need more than one structure to compare!")
        sys.exit(-1)
    try:
        structures = [Structure.from_file(fn) for fn in filenames]
    except Exception as ex:
        print("Error converting file. Are they in the right format?")
        print(str(ex))
        sys.exit(-1)

    m = StructureMatcher() if args.group == "species" else StructureMatcher(comparator=ElementComparator())
    for i, grp in enumerate(m.group_structures(structures)):
        print(f"Group {i}: ")
        for s in grp:
            print(f"- {filenames[structures.index(s)]} ({s.formula})")
        print()
Пример #42
0
def get_structures_from_paths(paths_list):

    structures = []
    for path in paths_list:
        try:
            poscar_path = os.path.join(path, 'POSCAR.orig')
            incar_path = os.path.join(path, 'INCAR.orig')
            try:
                incar = Incar.from_file(incar_path)
                magmoms = incar.get('MAGMOM')
                undecorated_structure = Structure.from_file(poscar_path)

                structure = Structure(lattice=undecorated_structure.lattice,
                                      species=undecorated_structure.species,
                                      coords=undecorated_structure.frac_coords,
                                      site_properties={'magmom': magmoms})

                structures.append(structure)
            except:
                print('%s does not have a MAGMOM tag' % incar_path)
        except:
            print('%s does not contain a valid POSCAR or INCAR' % path)

    return structures
Пример #43
0
 def test_timeout(self):
     s = Structure.from_file(filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "garnet.cif"))
     a = SpacegroupAnalyzer(s, 0.1)
     s["Al3+"] = {"Al3+": 0.5, "Ga3+": 0.5}
     adaptor = EnumlibAdaptor(s, 1, 1, enum_precision_parameter=0.01, timeout=0.0000000000001)
     self.assertRaises(TimeoutError, adaptor._run_multienum)
Пример #44
0
    # putting the atom at a halfway distance between other atoms
    link = {'0': {}, '1': {}, '2': {'0': [6, 2, -1]}}

    # list of indices of atoms to be removed from each molecule
    remove = [[7], [7], []]

    # combined_mol = combine_mols(mols, cm_dist, angle, link=link, remove=remove)
    lead_acetate = Ligand(mols, cm_dist, angle=angle, link={}, remove=remove)
    lead_acetate.create_ligand()
    lead_acetate.to('xyz', 'lead_acetate.xyz')

    # put the ligand in a box
    boxed_lead_acetate = lead_acetate.get_boxed_structure(13, 13, 13)
    boxed_lead_acetate.to(fmt="poscar", filename="POSCAR_diacetate_boxed.vasp")
    # bulk PbS
    strt_pbs = Structure.from_file(
        os.path.join(PACKAGE_PATH, "test_files", "POSCAR_PbS"))

    # intital supercell, this wont be the final supercell if surface
    # coverage is specified
    supercell = [1, 1, 1]

    # miller index
    hkl = [1, 0, 0]

    # minimum slab thickness in Angstroms
    min_thick = 21

    # minimum vacuum thickness in Angstroms
    # the maximum distance in the lignad will be added to this value
    min_vac = 10
Пример #45
0
def vac_antisite_def_struct_gen(mpid, mapi_key, cellmax, struct_file=None):
    if not mpid and not struct_file:
        print ("============\nERROR: Provide an mpid\n============")
        return

    # Get primitive structure from the Materials Project DB
    if not struct_file:
        if not mapi_key:
            with MPRester() as mp:
                struct = mp.get_structure_by_material_id(mpid)
        else:
            with MPRester(mapi_key) as mp:
                struct = mp.get_structure_by_material_id(mpid)
    else:
        struct = Structure.from_file(struct_file)

    sga = SpacegroupAnalyzer(struct)
    prim_struct = sga.find_primitive()
    #prim_struct_sites = len(prim_struct.sites)
    #conv_struct = sga.get_conventional_standard_structure()
    #conv_struct_sites = len(conv_struct.sites)
    #conv_prim_ratio = int(conv_struct_sites / prim_struct_sites)

    # Default VASP settings
    def_vasp_incar_param = {'ISIF':2, 'EDIFF':1e-6, 'EDIFFG':0.001,}
    kpoint_den = 15000

    # Create bulk structure and associated VASP files
    sc_scale = get_sc_scale(inp_struct=prim_struct, final_site_no=cellmax)
    blk_sc = prim_struct.copy()
    blk_sc.make_supercell(scaling_matrix=sc_scale)
    site_no = blk_sc.num_sites

    # Rescale if needed
    while site_no > cellmax:
        max_sc_dim = max(sc_scale)
        i = sc_scale.index(max_sc_dim)
        sc_scale[i] -= 1
        blk_sc = prim_struct.copy()
        blk_sc.make_supercell(scaling_matrix=sc_scale)
        site_no = blk_sc.num_sites
    
    blk_str_sites = set(blk_sc.sites)
    custom_kpoints = Kpoints.automatic_density(blk_sc, kppa=kpoint_den)
    mpvis = MPMetalRelaxSet(blk_sc, user_incar_settings=def_vasp_incar_param,
                            user_kpoints_settings=custom_kpoints)

    if mpid:
        root_fldr = mpid
    else:
        root_fldr = struct.composition.reduced_formula

    fin_dir = os.path.join(root_fldr, 'bulk')
    mpvis.write_input(fin_dir)
    if not mpid:    # write the input structure if mpid is not used
        struct.to(fmt='poscar', filename=os.path.join(fin_dir, 'POSCAR.uc'))

    # Create each defect structure and associated VASP files
    # First find all unique defect sites
    periodic_struct = sga.get_symmetrized_structure()
    unique_sites = list(set([periodic_struct.find_equivalent_sites(site)[0] \
                             for site in periodic_struct.sites]))
    temp_struct = Structure.from_sites(sorted(unique_sites))
    prim_struct2 = SpacegroupAnalyzer(temp_struct).find_primitive()
    prim_struct2.lattice = prim_struct.lattice  # a little hacky
    for i, site in enumerate(prim_struct2.sites):
        vac = Vacancy(structure=prim_struct, defect_site=site)
        vac_sc = vac.generate_defect_structure(supercell=sc_scale)

        # Get vacancy site information
        vac_str_sites = set(vac_sc.sites)
        vac_sites = blk_str_sites - vac_str_sites
        vac_site = next(iter(vac_sites))
        site_mult = vac.get_multiplicity()
        vac_site_specie = vac_site.specie
        vac_symbol = vac_site_specie.symbol

        custom_kpoints = Kpoints.automatic_density(vac_sc, kppa=kpoint_den)
        mpvis = MPMetalRelaxSet(vac_sc,
                                user_incar_settings=def_vasp_incar_param,
                                user_kpoints_settings=custom_kpoints)
        vac_dir = 'vacancy_{}_mult-{}_sitespecie-{}'.format(
                    str(i+1), site_mult, vac_symbol)
        fin_dir = os.path.join(root_fldr, vac_dir)
        mpvis.write_input(fin_dir)

        # Antisites generation at the vacancy site
        struct_species = blk_sc.species
        for specie in set(struct_species) - set([vac_site_specie]):
            specie_symbol = specie.symbol
            anti_sc = vac_sc.copy()
            anti_sc.append(specie, vac_site.frac_coords)
            mpvis = MPMetalRelaxSet(anti_sc,
                                    user_incar_settings=def_vasp_incar_param,
                                    user_kpoints_settings=custom_kpoints)
            anti_dir = 'antisite_{}_mult-{}_sitespecie-{}_subspecie-{}'.format(
                        str(i+1), site_mult, vac_symbol, specie_symbol)
            fin_dir = os.path.join(root_fldr, anti_dir)
            mpvis.write_input(fin_dir)
Пример #46
0
 def setUp(self):
     feo4 = Structure.from_file(os.path.join(test_dir, "LiFePO4.cif"))
     feo4.remove_species(["Li"])
     feo4.remove_oxidation_states()
     self.feo4 = feo4
Пример #47
0
def make_deepmd_lammps (jdata, conf_dir) :
    deepmd_model_dir = jdata['deepmd_model_dir']
    deepmd_type_map = jdata['deepmd_type_map']
    ntypes = len(deepmd_type_map)    
    deepmd_model_dir = os.path.abspath(deepmd_model_dir)
    deepmd_models = glob.glob(os.path.join(deepmd_model_dir, '*pb'))
    deepmd_models_name = [os.path.basename(ii) for ii in deepmd_models]
    vol_start = jdata['vol_start']
    vol_end = jdata['vol_end']
    vol_step = jdata['vol_step']

    # # get equi props
    # equi_path = re.sub('confs', global_equi_name, conf_path)
    # equi_path = os.path.join(equi_path, 'lmp')
    # equi_log = os.path.join(equi_path, 'log.lammps')
    # if not os.path.isfile(equi_log) :
    #     raise RuntimeError("the system should be equilibriated first")
    # natoms, epa, vpa = lammps.get_nev(equi_log)
    # task path
    task_path = re.sub('confs', global_task_name, conf_dir)
    task_path = os.path.abspath(task_path)
    os.makedirs(task_path, exist_ok = True)
    cwd = os.getcwd()
    conf_path = os.path.abspath(conf_dir)
    from_poscar = os.path.join(conf_path, 'POSCAR')
    to_poscar = os.path.join(task_path, 'POSCAR')
    if os.path.exists(to_poscar) :
        assert(filecmp.cmp(from_poscar, to_poscar))
    else :
        os.chdir(task_path)
        os.symlink(os.path.relpath(from_poscar), 'POSCAR')
        os.chdir(cwd)
    volume = vasp.poscar_vol(to_poscar)
    natoms = vasp.poscar_natoms(to_poscar)
    vpa = volume / natoms
    # structrure
    ss = Structure.from_file(to_poscar)
    # lmp path
    lmp_path = os.path.join(task_path, 'deepmd')
    os.makedirs(lmp_path, exist_ok = True)
    # # lmp conf
    # conf_file = os.path.join(lmp_path, 'conf.lmp')
    # lammps.cvt_lammps_conf(to_poscar, conf_file)
    # ptypes = vasp.get_poscar_types(to_poscar)
    # lammps.apply_type_map(conf_file, deepmd_type_map, ptypes)
    os.chdir(lmp_path)
    for ii in deepmd_models_name :
        if os.path.exists(ii) :
            os.remove(ii)
    for (ii,jj) in zip(deepmd_models, deepmd_models_name) :
            os.symlink(os.path.relpath(ii), jj)
    share_models = glob.glob(os.path.join(lmp_path, '*pb'))

    for vol in np.arange(vol_start, vol_end, vol_step) :
        vol_path = os.path.join(lmp_path, 'vol-%.2f' % vol)        
        print('# generate %s' % (vol_path))
        os.makedirs(vol_path, exist_ok = True)
        os.chdir(vol_path)
        #print(vol_path)
        for ii in ['conf.lmp', 'conf.lmp'] + deepmd_models_name :
            if os.path.exists(ii) :
                os.remove(ii)                
        # # link conf
        # os.symlink(os.path.relpath(conf_file), 'conf.lmp')
        # make conf
        scale_ss = ss.copy()
        scale_ss.scale_lattice(vol * natoms)
        scale_ss.to('POSCAR', 'POSCAR')
        lammps.cvt_lammps_conf('POSCAR', 'conf.lmp')
        ptypes = vasp.get_poscar_types('POSCAR')
        lammps.apply_type_map('conf.lmp', deepmd_type_map, ptypes)
        # link models
        for (ii,jj) in zip(share_models, deepmd_models_name) :
            os.symlink(os.path.relpath(ii), jj)
        # make lammps input
        scale = (vol / vpa) ** (1./3.)
        fc = lammps.make_lammps_press_relax('conf.lmp', ntypes, scale,lammps.inter_deepmd, deepmd_models_name)
        with open(os.path.join(vol_path, 'lammps.in'), 'w') as fp :
            fp.write(fc)
        os.chdir(cwd)
Пример #48
0
def make_meam_lammps_fixv (jdata, conf_dir) :
    meam_potfile_dir = jdata['meam_potfile_dir']
    meam_potfile_dir = os.path.abspath(meam_potfile_dir)
    meam_potfile = jdata['meam_potfile']
    meam_potfile = [os.path.join(meam_potfile_dir,ii) for ii in meam_potfile]
    meam_potfile_name = jdata['meam_potfile']
    type_map = jdata['meam_type_map']
    ntypes = len(type_map)
    meam_param = {'meam_potfile' :      jdata['meam_potfile'],
                  'meam_type':          jdata['meam_param_type']}

    vol_start = jdata['vol_start']
    vol_end = jdata['vol_end']
    vol_step = jdata['vol_step']

    # get equi props
    equi_path = re.sub('confs', global_equi_name, conf_dir)
    task_path = re.sub('confs', global_task_name, conf_dir)
    equi_path = os.path.join(equi_path, 'meam')
    task_path = os.path.join(task_path, 'meam')
    equi_path = os.path.abspath(equi_path)
    task_path = os.path.abspath(task_path)
    equi_log = os.path.join(equi_path, 'log.lammps')
    equi_dump = os.path.join(equi_path, 'dump.relax')
    os.makedirs(task_path, exist_ok = True)
    task_poscar = os.path.join(task_path, 'POSCAR')
    lammps.poscar_from_last_dump(equi_dump, task_poscar, type_map)

    cwd = os.getcwd()
    volume = vasp.poscar_vol(task_poscar)
    natoms = vasp.poscar_natoms(task_poscar)
    vpa = volume / natoms
    # structrure
    ss = Structure.from_file(task_poscar)
    # make lammps.in
    fc = lammps.make_lammps_equi('conf.lmp', 
                                 ntypes, 
                                 lammps.inter_meam, 
                                 meam_param, 
                                 change_box = False)
    f_lammps_in = os.path.join(task_path, 'lammps.in')
    with open(f_lammps_in, 'w') as fp :
        fp.write(fc)
    # make vols
    for vol in np.arange(vol_start, vol_end, vol_step) :
        vol_path = os.path.join(task_path, 'vol-%.2f' % vol)        
        print('# generate %s' % (vol_path))
        os.makedirs(vol_path, exist_ok = True)
        os.chdir(vol_path)
        for ii in ['conf.lmp', 'conf.lmp', 'lammps.in'] + meam_potfile_name :
            if os.path.exists(ii) :
                os.remove(ii)                
        # make conf
        scale_ss = ss.copy()
        scale_ss.scale_lattice(vol * natoms)
        scale_ss.to('POSCAR', 'POSCAR')
        lammps.cvt_lammps_conf('POSCAR', 'conf.lmp')
        ptypes = vasp.get_poscar_types('POSCAR')
        lammps.apply_type_map('conf.lmp', type_map, ptypes)
        # link lammps.in
        os.symlink(os.path.relpath(f_lammps_in), 'lammps.in')
        # link models
        for (ii,jj) in zip(meam_potfile, meam_potfile_name) :
            os.symlink(os.path.relpath(ii), jj)
        # make lammps input
        os.chdir(cwd)
Пример #49
0
import unittest

import os
from pymatgen.analysis.ferroelectricity.polarization import *
from pymatgen.core.structure import Structure
from pymatgen.io.vasp.outputs import Outcar
from pymatgen.io.vasp.inputs import Potcar
from pymatgen.util.testing import PymatgenTest

test_dir = os.path.join(os.path.dirname(__file__), "..", "..", "..", "..",
                        'test_files/BTO_221_99_polarization')
bto_folders = ['nonpolar_polarization']
bto_folders += ['interpolation_{}_polarization'.format(str(i)) for i in range(1,9)][::-1]
bto_folders += ['polar_polarization']

structures = [Structure.from_file(test_dir+"/"+folder+"/POSCAR") for folder in bto_folders]

ions = np.matrix([[-44.363484, -44.363484, -44.79259988],
                  [-44.324764, -44.324764, -69.43452043],
                  [-44.286055, -44.286055, -69.8792077 ],
                  [-44.247335, -44.247335, -70.32475473],
                  [-44.208626, -44.208626, -70.77139856],
                  [-44.169906, -44.169906, -71.21889307],
                  [-44.131197, -44.131197, -71.66746921],
                  [-44.092477, -44.092477, -72.1168782 ],
                  [-44.053768, -44.053768, -72.56736141],
                  [-44.015048, -44.015048, -73.01874336]])


class UtilsTest(PymatgenTest):
    def setUp(self):
Пример #50
0
    def test_get_conventional_standard_structure(self):
        parser = CifParser(
            os.path.join(PymatgenTest.TEST_FILES_DIR, "bcc_1927.cif"))
        structure = parser.get_structures(False)[0]
        s = SpacegroupAnalyzer(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 90)
        self.assertAlmostEqual(conv.lattice.gamma, 90)
        self.assertAlmostEqual(conv.lattice.a, 9.1980270633769461)
        self.assertAlmostEqual(conv.lattice.b, 9.1980270633769461)
        self.assertAlmostEqual(conv.lattice.c, 9.1980270633769461)

        parser = CifParser(
            os.path.join(PymatgenTest.TEST_FILES_DIR, "btet_1915.cif"))
        structure = parser.get_structures(False)[0]
        s = SpacegroupAnalyzer(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 90)
        self.assertAlmostEqual(conv.lattice.gamma, 90)
        self.assertAlmostEqual(conv.lattice.a, 5.0615106678044235)
        self.assertAlmostEqual(conv.lattice.b, 5.0615106678044235)
        self.assertAlmostEqual(conv.lattice.c, 4.2327080177761687)

        parser = CifParser(
            os.path.join(PymatgenTest.TEST_FILES_DIR, "orci_1010.cif"))
        structure = parser.get_structures(False)[0]
        s = SpacegroupAnalyzer(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 90)
        self.assertAlmostEqual(conv.lattice.gamma, 90)
        self.assertAlmostEqual(conv.lattice.a, 2.9542233922299999)
        self.assertAlmostEqual(conv.lattice.b, 4.6330325651443296)
        self.assertAlmostEqual(conv.lattice.c, 5.373703587040775)

        parser = CifParser(
            os.path.join(PymatgenTest.TEST_FILES_DIR, "orcc_1003.cif"))
        structure = parser.get_structures(False)[0]
        s = SpacegroupAnalyzer(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 90)
        self.assertAlmostEqual(conv.lattice.gamma, 90)
        self.assertAlmostEqual(conv.lattice.a, 4.1430033493799998)
        self.assertAlmostEqual(conv.lattice.b, 31.437979757624728)
        self.assertAlmostEqual(conv.lattice.c, 3.99648651)

        parser = CifParser(
            os.path.join(PymatgenTest.TEST_FILES_DIR, "orac_632475.cif"))
        structure = parser.get_structures(False)[0]
        s = SpacegroupAnalyzer(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 90)
        self.assertAlmostEqual(conv.lattice.gamma, 90)
        self.assertAlmostEqual(conv.lattice.a, 3.1790663399999999)
        self.assertAlmostEqual(conv.lattice.b, 9.9032878699999998)
        self.assertAlmostEqual(conv.lattice.c, 3.5372412099999999)

        parser = CifParser(
            os.path.join(PymatgenTest.TEST_FILES_DIR, "monoc_1028.cif"))
        structure = parser.get_structures(False)[0]
        s = SpacegroupAnalyzer(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 117.53832420192903)
        self.assertAlmostEqual(conv.lattice.gamma, 90)
        self.assertAlmostEqual(conv.lattice.a, 14.033435583000625)
        self.assertAlmostEqual(conv.lattice.b, 3.96052850731)
        self.assertAlmostEqual(conv.lattice.c, 6.8743926325200002)
        parser = CifParser(
            os.path.join(PymatgenTest.TEST_FILES_DIR, "hex_1170.cif"))
        structure = parser.get_structures(False)[0]
        s = SpacegroupAnalyzer(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 90)
        self.assertAlmostEqual(conv.lattice.beta, 90)
        self.assertAlmostEqual(conv.lattice.gamma, 120)
        self.assertAlmostEqual(conv.lattice.a, 3.699919902005897)
        self.assertAlmostEqual(conv.lattice.b, 3.699919902005897)
        self.assertAlmostEqual(conv.lattice.c, 6.9779585500000003)

        structure = Structure.from_file(
            os.path.join(PymatgenTest.TEST_FILES_DIR, "tric_684654.json"))
        s = SpacegroupAnalyzer(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure()
        self.assertAlmostEqual(conv.lattice.alpha, 74.09581916308757)
        self.assertAlmostEqual(conv.lattice.beta, 75.72817279281173)
        self.assertAlmostEqual(conv.lattice.gamma, 63.63234318667333)
        self.assertAlmostEqual(conv.lattice.a, 3.741372924048738)
        self.assertAlmostEqual(conv.lattice.b, 3.9883228679270686)
        self.assertAlmostEqual(conv.lattice.c, 7.288495840048958)

        structure = Structure.from_file(
            os.path.join(PymatgenTest.TEST_FILES_DIR, "tric_684654.json"))
        structure.add_site_property("magmom", [1.0] * len(structure))
        s = SpacegroupAnalyzer(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure(keep_site_properties=True)
        self.assertEqual(conv.site_properties["magmom"], [1.0] * len(conv))

        structure = Structure.from_file(
            os.path.join(PymatgenTest.TEST_FILES_DIR, "tric_684654.json"))
        structure.add_site_property("magmom", [1.0] * len(structure))
        s = SpacegroupAnalyzer(structure, symprec=1e-2)
        conv = s.get_conventional_standard_structure(
            keep_site_properties=False)
        self.assertEqual(conv.site_properties.get("magmom", None), None)
Пример #51
0
    def test_get_slabs(self):
        gen = SlabGenerator(self.get_structure("CsCl"), [0, 0, 1], 10, 10)

        #Test orthogonality of some internal variables.
        a, b, c = gen.oriented_unit_cell.lattice.matrix
        self.assertAlmostEqual(np.dot(a, gen._normal), 0)
        self.assertAlmostEqual(np.dot(b, gen._normal), 0)

        self.assertEqual(len(gen.get_slabs()), 1)

        s = self.get_structure("LiFePO4")
        gen = SlabGenerator(s, [0, 0, 1], 10, 10)
        self.assertEqual(len(gen.get_slabs()), 5)

        self.assertEqual(len(gen.get_slabs(bonds={("P", "O"): 3})), 2)

        # There are no slabs in LFP that does not break either P-O or Fe-O
        # bonds for a miller index of [0, 0, 1].
        self.assertEqual(
            len(gen.get_slabs(bonds={
                ("P", "O"): 3,
                ("Fe", "O"): 3
            })), 0)

        #If we allow some broken bonds, there are a few slabs.
        self.assertEqual(
            len(
                gen.get_slabs(bonds={
                    ("P", "O"): 3,
                    ("Fe", "O"): 3
                },
                              max_broken_bonds=2)), 2)

        # At this threshold, only the origin and center Li results in
        # clustering. All other sites are non-clustered. So the of
        # slabs is of sites in LiFePO4 unit cell - 2 + 1.
        self.assertEqual(len(gen.get_slabs(tol=1e-4)), 15)

        LiCoO2 = Structure.from_file(get_path("icsd_LiCoO2.cif"),
                                     primitive=False)
        gen = SlabGenerator(LiCoO2, [0, 0, 1], 10, 10)
        lco = gen.get_slabs(bonds={("Co", "O"): 3})
        self.assertEqual(len(lco), 1)
        a, b, c = gen.oriented_unit_cell.lattice.matrix
        self.assertAlmostEqual(np.dot(a, gen._normal), 0)
        self.assertAlmostEqual(np.dot(b, gen._normal), 0)

        scc = Structure.from_spacegroup("Pm-3m", Lattice.cubic(3), ["Fe"],
                                        [[0, 0, 0]])
        gen = SlabGenerator(scc, [0, 0, 1], 10, 10)
        slabs = gen.get_slabs()
        self.assertEqual(len(slabs), 1)
        gen = SlabGenerator(scc, [1, 1, 1], 10, 10, max_normal_search=1)
        slabs = gen.get_slabs()
        self.assertEqual(len(slabs), 1)

        # Test whether using units of hkl planes instead of Angstroms for
        # min_slab_size and min_vac_size will give us the same number of atoms
        natoms = []
        for a in [1, 1.4, 2.5, 3.6]:
            s = Structure.from_spacegroup("Im-3m", Lattice.cubic(a), ["Fe"],
                                          [[0, 0, 0]])
            slabgen = SlabGenerator(s, (1, 1, 1),
                                    10,
                                    10,
                                    in_unit_planes=True,
                                    max_normal_search=2)
            natoms.append(len(slabgen.get_slab()))
        n = natoms[0]
        for i in natoms:
            self.assertEqual(n, i)
Пример #52
0
    def test_SiC_conv(self):
        """
        Testing a full convergence calculation cycle on SiC using precomupted data.
        """

        # the current version uses refence data from a run using the production version on zenobe
        # once all checks out the run should be done using the input generated using this version to replace the
        # reference

        wdir = tempfile.mkdtemp()
        os.chdir(wdir)

        temp_ABINIT_PS_EXT = os.environ.get('ABINIT_PS_EXT', None)
        temp_ABINIT_PS = os.environ.get('ABINIT_PS', None)

        os.environ['ABINIT_PS_EXT'] = '.psp8'
        os.environ['ABINIT_PS'] = wdir

        reference_dir = os.path.join(__reference_dir__, 'SiC_test_case')
        if not os.path.isdir(reference_dir): raise RuntimeError('py.test needs to be started in the HTGW root, '
                                                                '%s does not exist' % __reference_dir__)

        # copy input
        print(wdir)
        self.assertTrue(os.path.isdir(reference_dir))
        src_files = os.listdir(reference_dir)
        for file_name in src_files:
            full_file_name = os.path.join(reference_dir, file_name)
            if os.path.isfile(full_file_name):
                shutil.copy(full_file_name, wdir)
        self.assertEqual(len(os.listdir(wdir)), 6)

        print(os.listdir(wdir))
        structure = Structure.from_file('SiC.cif')
        structure.item = 'SiC.cif'

        print(' ==== generate flow ===  ')
        gwsetup(update=False)
        self.assertTrue(os.path.isdir(os.path.join(wdir, 'SiC_SiC.cif')))
        print(os.listdir(os.path.join(wdir)))
        print(os.listdir(os.path.join(wdir, 'SiC_SiC.cif')))
        self.assertTrue(os.path.isfile(os.path.join(wdir, 'SiC_SiC.cif', '__AbinitFlow__.pickle')))
        self.assertEqual(len(os.listdir(os.path.join(wdir, 'SiC_SiC.cif', 'w0'))), 48)

        print(' ==== copy reference results from first calculation ===  ')
        shutil.rmtree(os.path.join(wdir, 'SiC_SiC.cif'))
        shutil.copytree(os.path.join(reference_dir, 'ref_res', 'SiC_SiC.cif'), os.path.join(wdir, 'SiC_SiC.cif'))
        self.assertTrue(os.path.isdir(os.path.join(wdir, 'SiC_SiC.cif')))
        self.assertEqual(len(os.listdir(os.path.join(wdir, 'SiC_SiC.cif', 'w0'))), 68)

        print(' ==== process output ===  ')
        gwoutput()
        print(os.listdir('.'))
        self.assertTrue(os.path.isfile('plot-fits'))
        self.assertTrue(os.path.isfile('plots'))
        self.assertEqual(is_converged(hartree_parameters=True, structure=structure, return_values=True),
                         {u'ecut': 44.0, u'ecuteps': 4.0, u'gap': 6.816130591466406, u'nbands': 60})
        self.assertTrue(os.path.isfile('SiC_SiC.cif.full_res'))

        print(' ==== generate next flow ===  ')
        print('      version with bandstructure and dos  ')
        gwsetup(update=False)
        self.assertTrue(os.path.isdir('SiC_SiC.cif.conv'))
        print(os.listdir(os.path.join(wdir, 'SiC_SiC.cif.conv', 'w0')))
        self.assertEqual(len(os.listdir(os.path.join(wdir, 'SiC_SiC.cif.conv', 'w0'))), 15)

        print(' ==== copy reference from second flow ===  ')
        time.sleep(1)  # the .conv directory should be older than the first one
        shutil.rmtree(os.path.join(wdir, 'SiC_SiC.cif.conv'))
        shutil.copytree(os.path.join(reference_dir, 'ref_res', 'SiC_SiC.cif.conv'),
                        os.path.join(wdir, 'SiC_SiC.cif.conv'))
        self.assertTrue(os.path.isdir(os.path.join(wdir, 'SiC_SiC.cif.conv')))
        self.assertEqual(len(os.listdir(os.path.join(wdir, 'SiC_SiC.cif.conv', 'w0'))), 13)

        print(' ==== process output ===  ')
        backup = sys.stdout
        sys.stdout = StringIO()  # capture output
        gwoutput()
        out = sys.stdout.getvalue()  # release output
        sys.stdout.close()  # close the stream
        sys.stdout = backup  # restore original stdout

        print('=== *** ====\n'+out+'=== *** ====\n')
        gap = 0
        for l in out.split('\n'):
            if 'values' in l:
                gap = float(l.split(' ')[6])
        self.assertEqual(gap, 7.114950664158926)

        print(os.listdir('.'))
        print('processed')
        self.assertTrue(os.path.isfile('SiC_SiC.cif.full_res'))
        full_res = read_grid_from_file(s_name(structure)+'.full_res')
        self.assertEqual(full_res, {u'all_done': True, u'grid': 0})
        self.assertTrue(os.path.isdir(os.path.join(wdir, 'SiC_SiC.cif.res')))
        self.assertEqual(len(os.listdir(os.path.join(wdir, 'SiC_SiC.cif.res'))), 5)
        print(os.listdir(os.path.join(wdir, 'SiC_SiC.cif.res')))

        msrf = MySigResFile(os.path.join(wdir, 'SiC_SiC.cif.res', 'out_SIGRES.nc'))
        self.assertEqual(msrf.h**o, 6.6843830378711786)
        self.assertEqual(msrf.lumo, 8.0650328308487982)
        self.assertEqual(msrf.homo_gw, 6.2325949743130034)
        self.assertEqual(msrf.lumo_gw, 8.2504215095164763)
        self.assertEqual(msrf.fundamental_gap('ks'), msrf.lumo - msrf.h**o)
        self.assertEqual(msrf.fundamental_gap('gw'), msrf.lumo_gw - msrf.homo_gw)
        self.assertAlmostEqual(msrf.fundamental_gap('gamma'), gap, places=3)

        # since we now have a mysigresfile object we test the functionality

        msrf.get_scissor()
        # return self.qplist_spin[0].build_scissors(domains=[[-200, mid], [mid, 200]], k=1, plot=False)

        res = msrf.get_scissor_residues()
        self.assertEqual(res, [0.05322754684319431, 0.34320373172956475])
        # return sc.residues

        #msrf.plot_scissor(title='')

        #msrf.plot_qpe(title='')

        # to be continued

        if temp_ABINIT_PS is not None:
            os.environ['ABINIT_PS_EXT'] = temp_ABINIT_PS_EXT
            os.environ['ABINIT_PS'] = temp_ABINIT_PS
Пример #53
0
def plot_ion_hull_and_voltages(ion, fmt='pdf'):
    """
    Plots the phase diagram between the pure material and pure ion,
    Connecting the points on the convex hull of the phase diagram.

    Args:
        ion (str): name of atom that was intercalated, e.g. 'Li'.
        fmt (str): matplotlib format style. Check the matplotlib
            docs for options.
    """

    # Calculated with the relax() function in
    # mat2d.stability.startup. If you are using other input
    # parameters, you need to recalculate these values!
    ion_ev_fu = {'Li': -1.7540797, 'Mg': -1.31976062, 'Al': -3.19134607}

    energy = Vasprun('vasprun.xml').final_energy
    composition = Structure.from_file('POSCAR').composition

    # Get the formula (with single-digit integers preceded by a '_').
    twod_material = list(composition.reduced_formula)
    twod_formula = str()
    for i in range(len(twod_material)):
        try:
            int(twod_material[i])
            twod_formula += '_{}'.format(twod_material[i])
        except:
            twod_formula += twod_material[i]

    twod_ev_fu = energy / composition.get_reduced_composition_and_factor()[1]

    data = [(0, 0, 0, twod_ev_fu)]  # (at% ion, n_ions, E_F, abs_energy)
    dirs = [dir for dir in os.listdir(os.getcwd()) if os.path.isdir(dir)]
    for directory in dirs:
        if is_converged(directory):
            os.chdir(directory)
            energy = Vasprun('vasprun.xml').final_energy
            composition = Structure.from_file('POSCAR').composition
            ion_fraction = composition.get_atomic_fraction(ion)

            no_ion_comp_dict = composition.as_dict()
            no_ion_comp_dict.update({ion: 0})
            no_ion_comp = Composition.from_dict(no_ion_comp_dict)

            n_twod_fu = no_ion_comp.get_reduced_composition_and_factor()[1]
            n_ions = composition[ion] / n_twod_fu

            E_F = ((energy - composition[ion] * ion_ev_fu[ion] -
                    twod_ev_fu * n_twod_fu)/ composition.num_atoms)

            data.append((ion_fraction, n_ions, E_F, energy / n_twod_fu))

            os.chdir('../')
    data.append((1, 1, 0, ion_ev_fu[ion]))  # Pure ion

    sorted_data = sorted(data, key=operator.itemgetter(0))

    # Determine which compositions are on the convex hull.
    energy_profile = np.array([[item[0], item[2]] for item in sorted_data
                               if item[2] <= 0])
    hull = ConvexHull(energy_profile)
    convex_ion_fractions = [energy_profile[vertex, 0] for vertex in hull.vertices]
    convex_formation_energies = [energy_profile[vertex, 1] for vertex in hull.vertices]

    convex_ion_fractions.append(convex_ion_fractions.pop(0))
    convex_formation_energies.append(convex_formation_energies.pop(0))

    concave_ion_fractions = [pt[0] for pt in sorted_data
                             if pt[0] not in convex_ion_fractions]
    concave_formation_energies = [pt[2] for pt in sorted_data
                                  if pt[0] not in convex_ion_fractions]

    voltage_profile = []
    j = 0
    k = 0
    for i in range(1, len(sorted_data) - 1):
        if sorted_data[i][0] in convex_ion_fractions:
            voltage = -(((sorted_data[i][3] - sorted_data[k][3])-
                         (sorted_data[i][1] - sorted_data[k][1]) * ion_ev_fu[ion])
                        / (sorted_data[i][1] - sorted_data[k][1]))
            voltage_profile.append((sorted_data[k][0], voltage))
            voltage_profile.append((sorted_data[i][0], voltage))
            j += 1
            k = i

    voltage_profile.append((voltage_profile[-1][0], 0))
    voltage_profile.append((1, 0))

    voltage_profile_x = [tup[0] for tup in voltage_profile]
    voltage_profile_y = [tup[1] for tup in voltage_profile]

    ax = plt.figure(figsize=(14, 10)).gca()

    ax.plot([0, 1], [0, 0], 'k--')
    ax.plot(convex_ion_fractions, convex_formation_energies, 'b-', marker='o',
            markersize=12, markeredgecolor='none')
    ax.plot(concave_ion_fractions, concave_formation_energies, 'r', marker='o',
            linewidth=0, markersize=12, markeredgecolor='none')

    ax2 = ax.twinx()
    ax2.plot(voltage_profile_x, voltage_profile_y, 'k-', marker='o')

    ax.text(0, 0.002, r'$\mathrm{%s}$' % twod_formula, family='serif', size=24)
    ax.text(0.99, 0.002, r'$\mathrm{%s}$' % ion, family='serif', size=24,
            horizontalalignment='right')

    ax.set_xticklabels(ax.get_xticks(), family='serif', size=20)
    ax.set_yticklabels(ax.get_yticks(), family='serif', size=20)
    ax2.set_yticklabels(ax2.get_yticks(), family='serif', size=20)

    ax.set_xlabel('at% {}'.format(ion), family='serif', size=28)
    ax.set_ylabel(r'$\mathrm{E_F\/(eV/atom)}$', size=28)

    ax2.yaxis.set_label_position('right')
    if ion == 'Li':
        ax2.set_ylabel(r'$\mathrm{Potential\/vs.\/Li/Li^+\/(V)}$', size=28)
    elif ion == 'Mg':
        ax2.set_ylabel(r'$\mathrm{Potential\/vs.\/Mg/Mg^{2+}\/(V)}$', size=28)
    elif ion == 'Al':
        ax2.set_ylabel(r'$\mathrm{Potential\/vs.\/Al/Al^{3+}\/(V)}$', size=28)

    plt.savefig('{}_hull.{}'.format(ion, fmt), transparent=True)
Пример #54
0
    def setUp(self):

        self.maxDiff = None

        # trivial example, simple square lattice for testing
        structure = Structure(Lattice.tetragonal(5.0, 50.0), ['H'], [[0, 0, 0]])
        self.square_sg = StructureGraph.with_empty_graph(structure, edge_weight_name="", edge_weight_units="")
        self.square_sg.add_edge(0, 0, from_jimage=(0, 0, 0), to_jimage=(1, 0, 0))
        self.square_sg.add_edge(0, 0, from_jimage=(0, 0, 0), to_jimage=(-1, 0, 0))
        self.square_sg.add_edge(0, 0, from_jimage=(0, 0, 0), to_jimage=(0, 1, 0))
        self.square_sg.add_edge(0, 0, from_jimage=(0, 0, 0), to_jimage=(0, -1, 0))
        #TODO: decorating still fails because the structure graph gives a CN of 8 for this square lattice
        # self.square_sg.decorate_structure_with_ce_info()

        # body-centered square lattice for testing
        structure = Structure(Lattice.tetragonal(5.0, 50.0), ['H', 'He'], [[0, 0, 0], [0.5, 0.5, 0.5]])
        self.bc_square_sg = StructureGraph.with_empty_graph(structure, edge_weight_name="", edge_weight_units="")
        self.bc_square_sg.add_edge(0, 0, from_jimage=(0, 0, 0), to_jimage=(1, 0, 0))
        self.bc_square_sg.add_edge(0, 0, from_jimage=(0, 0, 0), to_jimage=(-1, 0, 0))
        self.bc_square_sg.add_edge(0, 0, from_jimage=(0, 0, 0), to_jimage=(0, 1, 0))
        self.bc_square_sg.add_edge(0, 0, from_jimage=(0, 0, 0), to_jimage=(0, -1, 0))
        self.bc_square_sg.add_edge(0, 1, from_jimage=(0, 0, 0), to_jimage=(0, 0, 0))
        self.bc_square_sg.add_edge(0, 1, from_jimage=(0, 0, 0), to_jimage=(-1, 0, 0))
        self.bc_square_sg.add_edge(0, 1, from_jimage=(0, 0, 0), to_jimage=(-1, -1, 0))
        self.bc_square_sg.add_edge(0, 1, from_jimage=(0, 0, 0), to_jimage=(0, -1, 0))

        # body-centered square lattice for testing
        # directions reversed, should be equivalent to as bc_square
        structure = Structure(Lattice.tetragonal(5.0, 50.0), ['H', 'He'], [[0, 0, 0], [0.5, 0.5, 0.5]])
        self.bc_square_sg_r = StructureGraph.with_empty_graph(structure, edge_weight_name="", edge_weight_units="")
        self.bc_square_sg_r.add_edge(0, 0, from_jimage=(0, 0, 0), to_jimage=(1, 0, 0))
        self.bc_square_sg_r.add_edge(0, 0, from_jimage=(0, 0, 0), to_jimage=(-1, 0, 0))
        self.bc_square_sg_r.add_edge(0, 0, from_jimage=(0, 0, 0), to_jimage=(0, 1, 0))
        self.bc_square_sg_r.add_edge(0, 0, from_jimage=(0, 0, 0), to_jimage=(0, -1, 0))
        self.bc_square_sg_r.add_edge(0, 1, from_jimage=(0, 0, 0), to_jimage=(0, 0, 0))
        self.bc_square_sg_r.add_edge(1, 0, from_jimage=(-1, 0, 0), to_jimage=(0, 0, 0))
        self.bc_square_sg_r.add_edge(1, 0, from_jimage=(-1, -1, 0), to_jimage=(0, 0, 0))
        self.bc_square_sg_r.add_edge(1, 0, from_jimage=(0, -1, 0), to_jimage=(0, 0, 0))

        # MoS2 example, structure graph obtained from critic2
        # (not ground state, from mp-1023924, single layer)
        stdout_file = os.path.join(os.path.dirname(__file__), "..", "..", "..",
                                   'test_files/critic2/MoS2_critic2_stdout.txt')
        with open(stdout_file, 'r') as f:
            reference_stdout = f.read()
        self.structure = Structure.from_file(os.path.join(os.path.dirname(__file__), "..", "..", "..",
                                             'test_files/critic2/MoS2.cif'))
        c2o = Critic2Output(self.structure, reference_stdout)
        self.mos2_sg = c2o.structure_graph(edge_weight="bond_length", edge_weight_units="Å")

        latt = Lattice.cubic(4.17)
        species = ["Ni", "O"]
        coords = [[0, 0, 0],
                  [0.5, 0.5, 0.5]]
        self.NiO = Structure.from_spacegroup(225, latt, species, coords).get_primitive_structure()

        # BCC example.
        self.bcc = Structure(Lattice.cubic(5.0), ['He', 'He'], [[0, 0, 0], [0.5, 0.5, 0.5]])


        warnings.simplefilter("ignore")
            # make new structure if not matched (not already existed)

            struc_matched = False

            find_comp = subs_db.find({
                "nspecies": nspecies,
                "species": species
            })
            for y in find_comp:
                basedir_comp = x["basedir"]
                positionfilename_comp = y["positionfile"]
                struc_comp = StructureNode(basedir_comp)
                current_dir_comp = struc_comp.get_currentdir()
                filename_comp = os.path.join(current_dir_comp,
                                             positionfilename_comp)
                struc_comp = Structure.from_file(filename_comp)
                struc_matcher = StructureMatcher()
                match = struc_matcher.fit(new_struc, struc_comp)
                if match:
                    struc_matched = True

            if not struc_matched:
                print("new_basedir", new_basedir)
                metadata = {
                    "purpose": "converged_ionic",
                    "achievement": "to_relax"
                }
                structurenode = StructureNode(new_basedir)
                structurenode.place_files(new_struc,
                                          source_uuid=source_uuid,
                                          metadata=metadata)
Пример #56
0
    def make_confs(self, path_to_work, path_to_equi, refine=False):
        path_to_work = os.path.abspath(path_to_work)
        if os.path.exists(path_to_work):
            dlog.warning('%s already exists' % path_to_work)
        else:
            os.makedirs(path_to_work)
        path_to_equi = os.path.abspath(path_to_equi)

        if 'start_confs_path' in self.parameter and os.path.exists(
                self.parameter['start_confs_path']):
            init_path_list = glob.glob(
                os.path.join(self.parameter['start_confs_path'], '*'))
            struct_init_name_list = []
            for ii in init_path_list:
                struct_init_name_list.append(ii.split('/')[-1])
            struct_output_name = path_to_work.split('/')[-2]
            assert struct_output_name in struct_init_name_list
            path_to_equi = os.path.abspath(
                os.path.join(self.parameter['start_confs_path'],
                             struct_output_name, 'relaxation', 'relax_task'))

        task_list = []
        cwd = os.getcwd()
        equi_contcar = os.path.join(path_to_equi, 'CONTCAR')

        os.chdir(path_to_work)
        if os.path.isfile('POSCAR'):
            os.remove('POSCAR')
        if os.path.islink('POSCAR'):
            os.remove('POSCAR')
        os.symlink(os.path.relpath(equi_contcar), 'POSCAR')
        #           task_poscar = os.path.join(output, 'POSCAR')

        # stress, deal with unsupported stress in dpdata
        #with open(os.path.join(path_to_equi, 'result.json')) as fin:
        #    equi_result = json.load(fin)
        #equi_stress = np.array(equi_result['stress']['data'])[-1]
        equi_result = loadfn(os.path.join(path_to_equi, 'result.json'))
        equi_stress = equi_result['stress'][-1]
        dumpfn(equi_stress, 'equi.stress.json', indent=4)
        os.chdir(cwd)

        if refine:
            print('elastic refine starts')
            task_list = make_refine(self.parameter['init_from_suffix'],
                                    self.parameter['output_suffix'],
                                    path_to_work)

            # record strain
            # df = Strain.from_deformation(dfm_ss.deformations[idid])
            # dumpfn(df.as_dict(), 'strain.json', indent=4)
            init_from_path = re.sub(self.parameter['output_suffix'][::-1],
                                    self.parameter['init_from_suffix'][::-1],
                                    path_to_work[::-1],
                                    count=1)[::-1]
            task_list_basename = list(map(os.path.basename, task_list))

            for ii in task_list_basename:
                init_from_task = os.path.join(init_from_path, ii)
                output_task = os.path.join(path_to_work, ii)
                os.chdir(output_task)
                if os.path.isfile('strain.json'):
                    os.remove('strain.json')
                copyfile(os.path.join(init_from_task, 'strain.json'),
                         'strain.json')
                #os.symlink(os.path.relpath(
                #    os.path.join((re.sub(self.parameter['output_suffix'], self.parameter['init_from_suffix'], ii)),
                #                 'strain.json')),
                #           'strain.json')
            os.chdir(cwd)
        else:
            norm_def = self.norm_deform
            shear_def = self.shear_deform
            norm_strains = [
                -norm_def, -0.5 * norm_def, 0.5 * norm_def, norm_def
            ]
            shear_strains = [
                -shear_def, -0.5 * shear_def, 0.5 * shear_def, shear_def
            ]

            if not os.path.exists(equi_contcar):
                raise RuntimeError("please do relaxation first")

            ss = Structure.from_file(equi_contcar)
            dfm_ss = DeformedStructureSet(ss,
                                          symmetry=False,
                                          norm_strains=norm_strains,
                                          shear_strains=shear_strains)
            n_dfm = len(dfm_ss)

            print('gen with norm ' + str(norm_strains))
            print('gen with shear ' + str(shear_strains))
            for ii in range(n_dfm):
                output_task = os.path.join(path_to_work, 'task.%06d' % ii)
                os.makedirs(output_task, exist_ok=True)
                os.chdir(output_task)
                for jj in [
                        'INCAR', 'POTCAR', 'POSCAR', 'conf.lmp', 'in.lammps'
                ]:
                    if os.path.exists(jj):
                        os.remove(jj)
                task_list.append(output_task)
                dfm_ss.deformed_structures[ii].to('POSCAR', 'POSCAR')
                # record strain
                df = Strain.from_deformation(dfm_ss.deformations[ii])
                dumpfn(df.as_dict(), 'strain.json', indent=4)
            os.chdir(cwd)
        return task_list
Пример #57
0
    def write_KPOINTS(
        POSCAR_input: str = "POSCAR",
        KPOINTS_output="KPOINTS.lobster",
        reciprocal_density: int = 100,
        isym: int = -1,
        from_grid: bool = False,
        input_grid: list = [5, 5, 5],
        line_mode: bool = True,
        kpoints_line_density: int = 20,
        symprec: float = 0.01,
    ):
        """
        writes a KPOINT file for lobster (only ISYM=-1 and ISYM=0 are possible), grids are gamma centered
        Args:
            POSCAR_input (str): path to POSCAR
            KPOINTS_output (str): path to output KPOINTS
            reciprocal_density (int): Grid density
            isym (int): either -1 or 0. Current Lobster versions only allow -1.
            from_grid (bool): If True KPOINTS will be generated with the help of a grid given in input_grid. Otherwise,
                they will be generated from the reciprocal_density
            input_grid (list): grid to generate the KPOINTS file
            line_mode (bool): If True, band structure will be generated
            kpoints_line_density (int): density of the lines in the band structure
            symprec (float): precision to determine symmetry
        """
        structure = Structure.from_file(POSCAR_input)
        if not from_grid:
            kpointgrid = Kpoints.automatic_density_by_vol(
                structure, reciprocal_density).kpts
            mesh = kpointgrid[0]
        else:
            mesh = input_grid

        # The following code is taken from: SpacegroupAnalyzer
        # we need to switch off symmetry here
        latt = structure.lattice.matrix
        positions = structure.frac_coords
        unique_species = []  # type: List[Any]
        zs = []
        magmoms = []

        for species, g in itertools.groupby(structure,
                                            key=lambda s: s.species):
            if species in unique_species:
                ind = unique_species.index(species)
                zs.extend([ind + 1] * len(tuple(g)))
            else:
                unique_species.append(species)
                zs.extend([len(unique_species)] * len(tuple(g)))

        for site in structure:
            if hasattr(site, "magmom"):
                magmoms.append(site.magmom)
            elif site.is_ordered and hasattr(site.specie, "spin"):
                magmoms.append(site.specie.spin)
            else:
                magmoms.append(0)

        # For now, we are setting magmom to zero. (Taken from INCAR class)
        cell = latt, positions, zs, magmoms
        # TODO: what about this shift?
        mapping, grid = spglib.get_ir_reciprocal_mesh(mesh,
                                                      cell,
                                                      is_shift=[0, 0, 0])

        # exit()
        # get the kpoints for the grid
        if isym == -1:
            kpts = []
            weights = []
            all_labels = []
            for gp in grid:
                kpts.append(gp.astype(float) / mesh)
                weights.append(float(1))
                all_labels.append("")
        elif isym == 0:
            # time reversal symmetry: k and -k are equivalent
            kpts = []
            weights = []
            all_labels = []
            newlist = [list(gp) for gp in list(grid)]
            mapping = []
            for gp in newlist:
                minus_gp = [-k for k in gp]
                if minus_gp in newlist and minus_gp not in [[0, 0, 0]]:
                    mapping.append(newlist.index(minus_gp))
                else:
                    mapping.append(newlist.index(gp))

            for igp, gp in enumerate(newlist):
                if mapping[igp] > igp:
                    kpts.append(np.array(gp).astype(float) / mesh)
                    weights.append(float(2))
                    all_labels.append("")
                elif mapping[igp] == igp:
                    kpts.append(np.array(gp).astype(float) / mesh)
                    weights.append(float(1))
                    all_labels.append("")

        else:
            ValueError("Only isym=-1 and isym=0 are allowed.")
        # line mode
        if line_mode:
            kpath = HighSymmKpath(structure, symprec=symprec)
            if not np.allclose(kpath.prim.lattice.matrix,
                               structure.lattice.matrix):
                raise ValueError(
                    "You are not using the standard primitive cell. The k-path is not correct. Please generate a "
                    "standard primitive cell first.")

            frac_k_points, labels = kpath.get_kpoints(
                line_density=kpoints_line_density, coords_are_cartesian=False)

            for k, f in enumerate(frac_k_points):
                kpts.append(f)
                weights.append(0.0)
                all_labels.append(labels[k])
        if isym == -1:
            comment = ("ISYM=-1, grid: " +
                       str(mesh) if not line_mode else "ISYM=-1, grid: " +
                       str(mesh) + " plus kpoint path")
        elif isym == 0:
            comment = ("ISYM=0, grid: " +
                       str(mesh) if not line_mode else "ISYM=0, grid: " +
                       str(mesh) + " plus kpoint path")

        KpointObject = Kpoints(
            comment=comment,
            style=Kpoints.supported_modes.Reciprocal,
            num_kpts=len(kpts),
            kpts=kpts,
            kpts_weights=weights,
            labels=all_labels,
        )

        KpointObject.write_file(filename=KPOINTS_output)
Пример #58
0
    def from_file(cls, fmt, filename=None,
                  structure_file=None, are_coops=False):
        """
        Creates a CompleteCohp object from an output file of a COHP
        calculation. Valid formats are either LMTO (for the Stuttgart
        LMTO-ASA code) or LOBSTER (for the LOBSTER code).

        Args:
            cohp_file: Name of the COHP output file. Defaults to COPL
                for LMTO and COHPCAR.lobster/COOPCAR.lobster for LOBSTER.

            are_coops: Indicates whether the populations are COOPs or
                COHPs. Defaults to False for COHPs.

            fmt: A string for the code that was used to calculate
                the COHPs so that the output file can be handled
                correctly. Can take the values "LMTO" or "LOBSTER".

            structure_file: Name of the file containing the structure.
                If no file name is given, use CTRL for LMTO and POSCAR
                for LOBSTER.

        Returns:
            A CompleteCohp object.
        """
        fmt = fmt.upper()
        if fmt == "LMTO":
            # LMTO COOPs and orbital-resolved COHP cannot be handled yet.
            are_coops = False
            orb_res_cohp = None
            if structure_file is None:
                structure_file = "CTRL"
            if filename is None:
                filename = "COPL"
            cohp_file = LMTOCopl(filename=filename, to_eV=True)
        elif fmt == "LOBSTER":
            if structure_file is None:
                structure_file = "POSCAR"
            if filename is None:
                filename = "COOPCAR.lobster" if are_coops \
                    else "COHPCAR.lobster"
            warnings.warn(
                "The bond labels are currently consistent with ICOHPLIST.lobster/ICOOPLIST.lobster, not with "
                "COHPCAR.lobster/COOPCAR.lobster. Please be aware!")
            cohp_file = Cohpcar(filename=filename, are_coops=are_coops)
            orb_res_cohp = cohp_file.orb_res_cohp
        else:
            raise ValueError("Unknown format %s. Valid formats are LMTO "
                             "and LOBSTER." % fmt)

        structure = Structure.from_file(structure_file)
        efermi = cohp_file.efermi
        cohp_data = cohp_file.cohp_data
        energies = cohp_file.energies

        # Lobster shifts the energies so that the Fermi energy is at zero.
        # Shifting should be done by the plotter object though.

        spins = [Spin.up, Spin.down] if cohp_file.is_spin_polarized \
            else [Spin.up]
        if fmt == "LOBSTER":
            energies += efermi

        if orb_res_cohp is not None:
            # If no total COHPs are present, calculate the total
            # COHPs from the single-orbital populations. Total COHPs
            # may not be present when the cohpgenerator keyword is used
            # in LOBSTER versions 2.2.0 and earlier.
            # TODO: Test this more extensively
            for label in orb_res_cohp:
                if cohp_file.cohp_data[label]["COHP"] is None:
                    # print(label)
                    cohp_data[label]["COHP"] = {
                        sp: np.sum([orb_res_cohp[label][orbs]["COHP"][sp] for orbs in orb_res_cohp[label]], axis=0)
                        for sp in spins}
                if cohp_file.cohp_data[label]["ICOHP"] is None:
                    cohp_data[label]["ICOHP"] = \
                        {sp: np.sum([orb_res_cohp[label][orbs]["ICOHP"][sp]
                                     for orbs in orb_res_cohp[label]],
                                    axis=0) for sp in spins}

        if fmt == "LMTO":
            # Calculate the average COHP for the LMTO file to be
            # consistent with LOBSTER output.
            avg_data = {"COHP": {}, "ICOHP": {}}
            for i in avg_data:
                for spin in spins:
                    rows = np.array([cohp_data[label][i][spin]
                                     for label in cohp_data])
                    avg = np.average(rows, axis=0)
                    # LMTO COHPs have 5 significant figures
                    avg_data[i].update({spin: np.array([round_to_sigfigs(a, 5)
                                        for a in avg], dtype=float)})
            avg_cohp = Cohp(efermi, energies,
                            avg_data["COHP"],
                            icohp=avg_data["ICOHP"])
        else:
            avg_cohp = Cohp(efermi, energies,
                            cohp_data["average"]["COHP"],
                            icohp=cohp_data["average"]["COHP"],
                            are_coops=are_coops)
            del cohp_data["average"]

        cohp_dict = {label: Cohp(efermi, energies,
                                 cohp_data[label]["COHP"],
                                 icohp=cohp_data[label]["ICOHP"],
                                 are_coops=are_coops)
                     for label in cohp_data}

        bond_dict = {label: {"length": cohp_data[label]["length"],
                             "sites": [structure.sites[site]
                                       for site in cohp_data[label]["sites"]]}
                     for label in cohp_data}

        return CompleteCohp(structure, avg_cohp, cohp_dict, bonds=bond_dict,
                            are_coops=are_coops, orb_res_cohp=orb_res_cohp)
Пример #59
0
    def test_writevaspfrominterpolatedposcar(self):
        nimages = 5
        this_image = 1
        autosort_tol = 0.5

        fw1 = Firework([
            CopyVaspOutputs(calc_dir=self.static_outdir,
                            contcar_to_poscar=False,
                            additional_files=["CONTCAR"]),
            PassCalcLocs(name="fw1")
        ],
                       name="fw1")

        fw2 = Firework([
            CopyVaspOutputs(calc_dir=self.opt_outdir,
                            contcar_to_poscar=False,
                            additional_files=["CONTCAR"]),
            PassCalcLocs(name="fw2")
        ],
                       name="fw2")

        fw3 = Firework([
            WriteVaspFromIOSetFromInterpolatedPOSCAR(
                start="fw1",
                end="fw2",
                this_image=this_image,
                nimages=nimages,
                autosort_tol=autosort_tol,
                vasp_input_set="MPStaticSet"),
            PassCalcLocs(name="fw3")
        ],
                       name="fw3",
                       parents=[fw1, fw2])

        fw4 = Firework([PassCalcLocs(name="fw4")], name="fw4", parents=fw3)

        wf = Workflow([fw1, fw2, fw3, fw4])
        self.lp.add_wf(wf)
        rapidfire(self.lp)

        fw4 = self.lp.get_fw_by_id(self.lp.get_fw_ids({"name": "fw4"})[0])

        calc_locs = fw4.spec["calc_locs"]

        print(get_calc_loc("fw3", calc_locs)["path"])

        # Check existence of structure files.
        self.assertTrue(
            os.path.exists(get_calc_loc("fw3", calc_locs)["path"] + "/POSCAR"))
        self.assertTrue(
            os.path.exists(
                get_calc_loc("fw3", calc_locs)["path"] +
                "/interpolate/CONTCAR_0"))
        self.assertTrue(
            os.path.exists(
                get_calc_loc("fw3", calc_locs)["path"] +
                "/interpolate/CONTCAR_1"))

        self.assertTrue(
            os.path.exists(get_calc_loc("fw3", calc_locs)["path"] + "/INCAR"))
        self.assertTrue(
            os.path.exists(
                get_calc_loc("fw3", calc_locs)["path"] + "/KPOINTS"))
        self.assertTrue(
            os.path.exists(get_calc_loc("fw3", calc_locs)["path"] + "/POTCAR"))

        # Check interpolation.
        struct_start = Structure.from_file(
            get_calc_loc("fw3", calc_locs)["path"] + "/interpolate/CONTCAR_0")
        struct_end = Structure.from_file(
            get_calc_loc("fw3", calc_locs)["path"] + "/interpolate/CONTCAR_1")
        struct_inter = Structure.from_file(
            get_calc_loc("fw3", calc_locs)["path"] + "/POSCAR")

        structs = struct_start.interpolate(struct_end,
                                           nimages,
                                           interpolate_lattices=True,
                                           autosort_tol=autosort_tol)

        # Check x of 1st site.
        self.assertAlmostEqual(structs[this_image][1].coords[0],
                               struct_inter[1].coords[0])
        # Check c lattice parameter
        self.assertAlmostEqual(structs[this_image].lattice.abc[0],
                               struct_inter.lattice.abc[0])
Пример #60
0
    def standard_calculations_from_vasp_files(
        cls,
        POSCAR_input: str = "POSCAR",
        INCAR_input: str = "INCAR",
        POTCAR_input: str | None = None,
        dict_for_basis: dict | None = None,
        option: str = "standard",
    ):
        """
        will generate Lobsterin with standard settings

        Args:
            POSCAR_input(str): path to POSCAR
            INCAR_input(str): path to INCAR
            POTCAR_input (str): path to POTCAR
            dict_for_basis (dict): can be provided: it should look the following:
                dict_for_basis={"Fe":'3p 3d 4s 4f', "C": '2s 2p'} and will overwrite all settings from POTCAR_input

            option (str): 'standard' will start a normal lobster run where COHPs, COOPs, DOS, CHARGE etc. will be
                calculated
                'standard_from_projection' will start a normal lobster run from a projection
                'standard_with_fatband' will do a fatband calculation, run over all orbitals
                'onlyprojection' will only do a projection
                'onlydos' will only calculate a projected dos
                'onlycohp' will only calculate cohp
                'onlycoop' will only calculate coop
                'onlycohpcoop' will only calculate cohp and coop

        Returns:
            Lobsterin Object with standard settings
        """
        warnings.warn(
            "Always check and test the provided basis functions. The spilling of your Lobster calculation might help"
        )
        # warn that fatband calc cannot be done with tetrahedron method at the moment
        if option not in [
                "standard",
                "standard_from_projection",
                "standard_with_fatband",
                "onlyprojection",
                "onlydos",
                "onlycohp",
                "onlycoop",
                "onlycobi",
                "onlycohpcoop",
                "onlycohpcoopcobi",
                "onlymadelung",
        ]:
            raise ValueError("The option is not valid!")

        Lobsterindict = {}  # type: Dict[Any,Any]
        # this basis set covers most elements
        Lobsterindict["basisSet"] = "pbeVaspFit2015"
        # energies around e-fermi
        Lobsterindict["COHPstartEnergy"] = -35.0
        Lobsterindict["COHPendEnergy"] = 5.0

        if option in [
                "standard",
                "onlycohp",
                "onlycoop",
                "onlycobi",
                "onlycohpcoop",
                "onlycohpcoopcobi",
                "standard_with_fatband",
        ]:
            # every interaction with a distance of 6.0 is checked
            Lobsterindict["cohpGenerator"] = "from 0.1 to 6.0 orbitalwise"
            # the projection is saved
            Lobsterindict["saveProjectionToFile"] = True

        if option == "standard_from_projection":
            Lobsterindict["cohpGenerator"] = "from 0.1 to 6.0 orbitalwise"
            Lobsterindict["loadProjectionFromFile"] = True

        # TODO: add cobi here! might be relevant lobster version
        if option == "onlycohp":
            Lobsterindict["skipdos"] = True
            Lobsterindict["skipcoop"] = True
            Lobsterindict["skipPopulationAnalysis"] = True
            Lobsterindict["skipGrossPopulation"] = True
            # lobster-4.1.0
            Lobsterindict["skipcobi"] = True
            Lobsterindict["skipMadelungEnergy"] = True

        if option == "onlycoop":
            Lobsterindict["skipdos"] = True
            Lobsterindict["skipcohp"] = True
            Lobsterindict["skipPopulationAnalysis"] = True
            Lobsterindict["skipGrossPopulation"] = True
            # lobster-4.1.0
            Lobsterindict["skipcobi"] = True
            Lobsterindict["skipMadelungEnergy"] = True

        if option == "onlycohpcoop":
            Lobsterindict["skipdos"] = True
            Lobsterindict["skipPopulationAnalysis"] = True
            Lobsterindict["skipGrossPopulation"] = True
            # lobster-4.1.0
            Lobsterindict["skipcobi"] = True
            Lobsterindict["skipMadelungEnergy"] = True

        if option == "onlycohpcoopcobi":
            Lobsterindict["skipdos"] = True
            Lobsterindict["skipPopulationAnalysis"] = True
            Lobsterindict["skipGrossPopulation"] = True
            Lobsterindict["skipMadelungEnergy"] = True

        if option == "onlydos":
            Lobsterindict["skipcohp"] = True
            Lobsterindict["skipcoop"] = True
            Lobsterindict["skipPopulationAnalysis"] = True
            Lobsterindict["skipGrossPopulation"] = True
            # lobster-4.1.0
            Lobsterindict["skipcobi"] = True
            Lobsterindict["skipMadelungEnergy"] = True

        if option == "onlyprojection":
            Lobsterindict["skipdos"] = True
            Lobsterindict["skipcohp"] = True
            Lobsterindict["skipcoop"] = True
            Lobsterindict["skipPopulationAnalysis"] = True
            Lobsterindict["skipGrossPopulation"] = True
            Lobsterindict["saveProjectionToFile"] = True
            # lobster-4.1.0
            Lobsterindict["skipcobi"] = True
            Lobsterindict["skipMadelungEnergy"] = True

        if option == "onlycobi":
            Lobsterindict["skipdos"] = True
            Lobsterindict["skipcohp"] = True
            Lobsterindict["skipPopulationAnalysis"] = True
            Lobsterindict["skipGrossPopulation"] = True
            # lobster-4.1.0
            Lobsterindict["skipcobi"] = True
            Lobsterindict["skipMadelungEnergy"] = True

        if option == "onlymadelung":
            Lobsterindict["skipdos"] = True
            Lobsterindict["skipcohp"] = True
            Lobsterindict["skipcoop"] = True
            Lobsterindict["skipPopulationAnalysis"] = True
            Lobsterindict["skipGrossPopulation"] = True
            Lobsterindict["saveProjectionToFile"] = True
            # lobster-4.1.0
            Lobsterindict["skipcobi"] = True

        incar = Incar.from_file(INCAR_input)
        if incar["ISMEAR"] == 0:
            Lobsterindict["gaussianSmearingWidth"] = incar["SIGMA"]
        if incar["ISMEAR"] != 0 and option == "standard_with_fatband":
            raise ValueError(
                "ISMEAR has to be 0 for a fatband calculation with Lobster")
        if dict_for_basis is not None:
            # dict_for_basis={"Fe":'3p 3d 4s 4f', "C": '2s 2p'}
            # will just insert this basis and not check with poscar
            basis = [
                key + " " + value for key, value in dict_for_basis.items()
            ]
        elif POTCAR_input is not None:
            # get basis from POTCAR
            potcar_names = Lobsterin._get_potcar_symbols(
                POTCAR_input=POTCAR_input)

            basis = Lobsterin.get_basis(
                structure=Structure.from_file(POSCAR_input),
                potcar_symbols=potcar_names)
        else:
            raise ValueError("basis cannot be generated")
        Lobsterindict["basisfunctions"] = basis
        if option == "standard_with_fatband":
            Lobsterindict["createFatband"] = basis

        return cls(Lobsterindict)