Ejemplo n.º 1
0
    def run_task(self, fw_spec):

        from pymatgen.analysis.eos import EOS

        tag = self["tag"]
        db_file = env_chk(self.get("db_file"), fw_spec)
        summary_dict = {"eos": self["eos"]}

        mmdb = MMVaspDb.from_db_file(db_file, admin=True)
        # get the optimized structure
        d = mmdb.collection.find_one({"task_label": "{} structure optimization".format(tag)})
        structure = Structure.from_dict(d["calcs_reversed"][-1]["output"]['structure'])
        summary_dict["structure"] = structure.as_dict()

        # get the data(energy, volume, force constant) from the deformation runs
        docs = mmdb.collection.find({"task_label": {"$regex": "{} bulk_modulus*".format(tag)},
                                     "formula_pretty": structure.composition.reduced_formula})
        energies = []
        volumes = []
        for d in docs:
            s = Structure.from_dict(d["calcs_reversed"][-1]["output"]['structure'])
            energies.append(d["calcs_reversed"][-1]["output"]['energy'])
            volumes.append(s.volume)
        summary_dict["energies"] = energies
        summary_dict["volumes"] = volumes

        # fit the equation of state
        eos = EOS(self["eos"])
        eos_fit = eos.fit(volumes, energies)
        summary_dict["results"] = dict(eos_fit.results)

        with open("bulk_modulus.json", "w") as f:
            f.write(json.dumps(summary_dict, default=DATETIME_HANDLER))

        logger.info("BULK MODULUS CALCULATION COMPLETE")
Ejemplo n.º 2
0
    def _match_material(self, doc):
        """
        Returns the material_id that has the same structure as this doc as
         determined by the structure matcher. Returns None if no match.

        Args:
            doc: a JSON-like document

        Returns:
            (int) matching material_id or None
        """
        formula = doc["formula_reduced_abc"]
        sgnum = doc["spacegroup"]["number"]

        for m in self._materials.find({"formula_reduced_abc": formula, "sg_number": sgnum},
                                      {"structure": 1, "material_id": 1}):

            m_struct = Structure.from_dict(m["structure"])
            t_struct = Structure.from_dict(doc["structure"])

            sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5,
                                  primitive_cell=True, scale=True,
                                  attempt_supercell=False, allow_subset=False,
                                  comparator=ElementComparator())

            if sm.fit(m_struct, t_struct):
                return m["material_id"]

        return None
Ejemplo n.º 3
0
    def test_ordering_enumeration(self):

        # simple afm
        structure = Structure.from_file(os.path.join(ref_dir, "ordering/LaMnO3.json"))
        wf = MagneticOrderingsWF(structure)
        self.assertEqual(wf.input_origin, "afm")

        # ferrimagnetic (Cr produces net spin)
        structure = Structure.from_file(os.path.join(ref_dir, "ordering/Cr2NiO4.json"))
        wf = MagneticOrderingsWF(structure)
        self.assertEqual(wf.input_origin, "ferri_by_Cr")

        # antiferromagnetic on single magnetic site
        structure = Structure.from_file(os.path.join(ref_dir, "ordering/Cr2WO6.json"))
        wf = MagneticOrderingsWF(structure)
        self.assertEqual(wf.input_origin, "afm_by_Cr")

        # afm requiring large cell size
        # (enable for further development of workflow, too slow for CI)

        # structure = Structure.from_file(os.path.join(ref_dir, "CuO.json"))
        # wf = MagneticOrderingsWF(structure, default_magmoms={'Cu': 1.73},
        #                         transformation_kwargs={'max_cell_size': 4})
        # self.assertEqual(wf.input_origin, "afm")

        # antiferromagnetic by structural motif
        structure = Structure.from_file(os.path.join(ref_dir, "ordering/Ca3Co2O6.json"))
        wf = MagneticOrderingsWF(
            structure,
            strategies=("antiferromagnetic_by_motif",),
            # this example just misses default cut-off, so do not truncate
            truncate_by_symmetry=False,
            transformation_kwargs={"max_cell_size": 2},
        )
        self.assertEqual(wf.input_origin, "afm_by_motif_2a")
Ejemplo n.º 4
0
 def test_unique_structure_substitutions( self ):
     # integration test
     # Create a pymatgen structure with 16 sites in a 4x4 square grid
     coords = np.array( [ [ 0.0, 0.0, 0.0 ],
                          [ 0.25, 0.0, 0.0 ],
                          [ 0.5, 0., 0.0 ],
                          [ 0.75, 0.0, 0.0 ],
                          [ 0.0, 0.25, 0.0 ],
                          [ 0.25, 0.25, 0.0 ],
                          [ 0.5, 0.25, 0.0 ],
                          [ 0.75, 0.25, 0.0 ],
                          [ 0.0, 0.5, 0.0 ],
                          [ 0.25, 0.5, 0.0 ],
                          [ 0.5, 0.5, 0.0 ],
                          [ 0.75, 0.5, 0.0 ],
                          [ 0.0, 0.75, 0.0 ],
                          [ 0.25, 0.75, 0.0 ],
                          [ 0.5, 0.75, 0.0 ],
                          [ 0.75, 0.75, 0.0 ] ] )
     atom_list = [ 'Li' ] * len( coords )
     lattice = Lattice.from_parameters( a = 3.0, b=3.0, c=3.0, alpha=90, beta=90, gamma=90 )
     parent_structure = Structure( lattice, atom_list, coords )
     parent_structure.replace( 0, 'O' ) # substitute one site with 'O'
     ns = unique_structure_substitutions( parent_structure, 'Li', { 'Na':1, 'Li':14 } )
     self.assertEqual( len( ns ), 5 )
     distances = np.array( sorted( [ s.get_distance( s.indices_from_symbol('O')[0], s.indices_from_symbol('Na')[0] ) for s in ns ] ) )
     np.testing.assert_array_almost_equal( distances, np.array( [ 0.75    ,  1.06066 ,  1.5     ,  1.677051,  2.12132 ] ) )
     np.testing.assert_array_equal( np.array( sorted( [ s.number_of_equivalent_configurations for s in ns ] ) ), np.array( [ 1, 2, 4, 4, 4 ] ) )
     np.testing.assert_array_equal( np.array( sorted( [ s.full_configuration_degeneracy for s in ns ] ) ), np.array( [ 1, 2, 4, 4, 4 ] ) )
Ejemplo n.º 5
0
    def setUp(self):

        with open(os.path.join(test_dir, 'LobsterCompleteDos_spin.json'), 'r') as f:
            data_spin = json.load(f)
        self.LobsterCompleteDOS_spin = LobsterCompleteDos.from_dict(data_spin)

        with open(os.path.join(test_dir, 'LobsterCompleteDos_nonspin.json'), 'r') as f:
            data_nonspin = json.load(f)
        self.LobsterCompleteDOS_nonspin = LobsterCompleteDos.from_dict(data_nonspin)

        with open(os.path.join(test_dir, 'structure_KF.json'), 'r') as f:
            data_structure = json.load(f)
        self.structure = Structure.from_dict(data_structure)

        with open(os.path.join(test_dir, 'LobsterCompleteDos_MnO.json'), 'r') as f:
            data_MnO = json.load(f)
        self.LobsterCompleteDOS_MnO = LobsterCompleteDos.from_dict(data_MnO)

        with open(os.path.join(test_dir, 'LobsterCompleteDos_MnO_nonspin.json'), 'r') as f:
            data_MnO_nonspin = json.load(f)
        self.LobsterCompleteDOS_MnO_nonspin = LobsterCompleteDos.from_dict(data_MnO_nonspin)

        with open(os.path.join(test_dir, 'structure_MnO.json'), 'r') as f:
            data_MnO = json.load(f)
        self.structure_MnO = Structure.from_dict(data_MnO)
Ejemplo n.º 6
0
    def _match_material(self, taskdoc):
        """
        Returns the material_id that has the same structure as this task as
         determined by the structure matcher. Returns None if no match.

        Args:
            taskdoc (dict): a JSON-like task document

        Returns:
            (int) matching material_id or None
        """
        formula = taskdoc["formula_reduced_abc"]

        if "parent_structure" in taskdoc:  # this is used to intentionally combine multiple data w/same formula but slightly different structure, e.g. from an ordering scheme
            t_struct = Structure.from_dict(taskdoc["parent_structure"]["structure"])
            q = {"formula_reduced_abc": formula, "parent_structure.spacegroup.number": taskdoc["parent_structure"]["spacegroup"]["number"]}
        else:
            sgnum = taskdoc["output"]["spacegroup"]["number"]
            t_struct = Structure.from_dict(taskdoc["output"]["structure"])
            q = {"formula_reduced_abc": formula, "sg_number": sgnum}

        for m in self._materials.find(q, {"parent_structure": 1, "structure": 1, "material_id": 1}):
            s_dict = m["parent_structure"]["structure"] if "parent_structure" in m else m["structure"]
            m_struct = Structure.from_dict(s_dict)
            sm = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5,
                                  primitive_cell=True, scale=True,
                                  attempt_supercell=False, allow_subset=False,
                                  comparator=ElementComparator())

            if sm.fit(m_struct, t_struct):
                return m["material_id"]

        return None
Ejemplo n.º 7
0
    def test_disordered_primitive_to_ordered_supercell(self):
        sm_atoms = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5,
                                    primitive_cell=False, scale=True,
                                    attempt_supercell=True,
                                    allow_subset=True,
                                    supercell_size='num_atoms',
                                    comparator=OrderDisorderElementComparator())
        sm_sites = StructureMatcher(ltol=0.2, stol=0.3, angle_tol=5,
                                    primitive_cell=False, scale=True,
                                    attempt_supercell=True,
                                    allow_subset=True,
                                    supercell_size='num_sites',
                                    comparator=OrderDisorderElementComparator())
        lp = Lattice.orthorhombic(10, 20, 30)
        pcoords = [[0, 0, 0],
                   [0.5, 0.5, 0.5]]
        ls = Lattice.orthorhombic(20, 20, 30)
        scoords = [[0, 0, 0],
                   [0.75, 0.5, 0.5]]
        prim = Structure(lp, [{'Na': 0.5}, {'Cl': 0.5}], pcoords)
        supercell = Structure(ls, ['Na', 'Cl'], scoords)
        supercell.make_supercell([[-1, 1, 0], [0, 1, 1], [1, 0, 0]])

        self.assertFalse(sm_sites.fit(prim, supercell))
        self.assertTrue(sm_atoms.fit(prim, supercell))

        self.assertRaises(ValueError, sm_atoms.get_s2_like_s1, prim, supercell)
        self.assertEqual(len(sm_atoms.get_s2_like_s1(supercell, prim)), 4)
Ejemplo n.º 8
0
def poscar_from_sitelist( configs, labels, sitelists, structure, subset = None ):
    """
    Uses pymatgen Structure.to() method to generates POSCAR files for a set of 
    configurations within a parent structure.
    Args:
        configs   (list):               site configurations
        labels    (list):               atom labels to output
        sitelist  (list):               list of sites in fractional coords
        structure (pymatgen Structure): Parent structure
        subset    (Optional [list]):    list of atom indices to output 
    """

    if subset:
        species_clean = [ spec for i,spec in enumerate( structure.species ) if i not in subset ]
        species_config = [ spec for i,spec in enumerate( structure.species ) if i in subset ]
        frac_coords_clean = [ coord for i, coord in enumerate( structure.frac_coords ) if i not in subset ]
        clean_structure = Structure( structure.lattice, species_clean, frac_coords_clean )

    else:
        clean_structure = Structure( structure.lattice, [], [] )
        species_config = structure.species

    for idx, config in enumerate( configs, start=1 ):
       structure_config = clean_structure.copy()
       for label in labels:
           for pos in config.position( label ):
               for sitelist in sitelists:
                   structure_config.append( species_config[ pos ], sitelist[ pos ] )
       structure_config.to( filename="POSCAR_{}.vasp".format( idx ) )
Ejemplo n.º 9
0
    def setUp(self):
        self.structure = Structure.from_spacegroup("Fm-3m", Lattice.cubic(3.5),
                                                   ["Ni"], [[0, 0, 0]])
        lattice = Lattice.cubic(3.010)
        frac_coords = [[0.00000, 0.00000, 0.00000],
                       [0.00000, 0.50000, 0.50000],
                       [0.50000, 0.00000, 0.50000],
                       [0.50000, 0.50000, 0.00000],
                       [0.50000, 0.00000, 0.00000],
                       [0.50000, 0.50000, 0.50000],
                       [0.00000, 0.00000, 0.50000],
                       [0.00000, 0.50000, 0.00000]]
        species = ['Mg', 'Mg', 'Mg', 'Mg', 'O', 'O', 'O', 'O']
        self.MgO = Structure(lattice, species, frac_coords)

        slabs = generate_all_slabs(self.structure, max_index=2,
                                   min_slab_size=6.0, min_vacuum_size=15.0,
                                   max_normal_search=1, center_slab=True)
        self.slab_dict = {''.join([str(i) for i in slab.miller_index]):
                              slab for slab in slabs}
        self.asf_211 = AdsorbateSiteFinder(self.slab_dict["211"])
        self.asf_100 = AdsorbateSiteFinder(self.slab_dict["100"])
        self.asf_111 = AdsorbateSiteFinder(self.slab_dict["111"])
        self.asf_110 = AdsorbateSiteFinder(self.slab_dict["110"])
        self.asf_struct = AdsorbateSiteFinder(
            Structure.from_sites(self.slab_dict["111"].sites))
Ejemplo n.º 10
0
    def run_task(self, fw_spec):

        prev_dir = fw_spec.get('PREV_DIR', None)
        self.custom_params = self.get('custom_params', None)   

        if isinstance(self["structure"], Structure):
            s = self["structure"]
        elif isinstance(self["structure"], dict):
            s = Structure.from_dict(self["structure"])
        else:
            s = Structure.from_file(os.path.join(prev_dir, self["structure"]))


        vis = load_class("pymatgen.io.vasp.sets", self["vasp_input_set"])(
                         **self.get("input_set_params", {}))
        vis.write_input(s, ".")


        # Write Custom KPOINTS settings if necessary
        ksettings = self.custom_params.get('user_kpts_settings', None) if isinstance(
                self.custom_params, dict) else None
        if ksettings:
            style = ksettings.get('kpts_style', 'Gamma')
            kpoints = ksettings.get('kpts', [16,16,16])
            shift = ksettings.get('kpts_shift', [0,0,0])
            k = Kpoints(kpts=[kpoints], kpts_shift=shift)
            k.style = style
            k.write_file("KPOINTS")
Ejemplo n.º 11
0
    def test_structure(self):
        quartz = self.quartz.structure
        np.testing.assert_array_equal(quartz.lattice.matrix,
                                      [[4.913400, 0, 0],
                                       [-2.456700, 4.255129, 0],
                                       [0, 0, 5.405200]])
        self.assertEqual(quartz.formula, "Si3 O6")
        self.assertNotIn("molecule-ID", self.quartz.atoms.columns)

        ethane = self.ethane.structure
        np.testing.assert_array_equal(ethane.lattice.matrix,
                                      np.diag([10.0] * 3))
        lbounds = np.array(self.ethane.box.bounds)[:, 0]
        coords = self.ethane.atoms[["x", "y", "z"]].values - lbounds
        np.testing.assert_array_equal(ethane.cart_coords, coords)
        np.testing.assert_array_equal(ethane.site_properties["charge"],
                                      self.ethane.atoms["q"])
        tatb = self.tatb.structure
        frac_coords = tatb.frac_coords[381]
        real_frac_coords = frac_coords - np.floor(frac_coords)
        np.testing.assert_array_almost_equal(real_frac_coords,
                                             [0.01553397,
                                              0.71487872,
                                              0.14134139])

        co = Structure.from_spacegroup(194,
                                       Lattice.hexagonal(2.50078, 4.03333),
                                       ["Co"], [[1/3, 2/3, 1/4]])
        ld_co = LammpsData.from_structure(co)
        self.assertEqual(ld_co.structure.composition.reduced_formula, "Co")
        ni = Structure.from_spacegroup(225, Lattice.cubic(3.50804),
                                       ["Ni"], [[0, 0, 0]])
        ld_ni = LammpsData.from_structure(ni)
        self.assertEqual(ld_ni.structure.composition.reduced_formula, "Ni")
Ejemplo n.º 12
0
    def run_task(self, fw_spec):

        tag = self["tag"]
        db_file = env_chk(self.get("db_file"), fw_spec)
        t_step = self.get("t_step", 10)
        t_min = self.get("t_min", 0)
        t_max = self.get("t_max", 1000)
        mesh = self.get("mesh", [20, 20, 20])
        eos = self.get("eos", "vinet")
        qha_type = self.get("qha_type", "debye_model")
        pressure = self.get("pressure", 0.0)
        gibbs_summary_dict = {}

        mmdb = MMVaspDb.from_db_file(db_file, admin=True)
        # get the optimized structure
        d = mmdb.collection.find_one({"task_label": "{} structure optimization".format(tag)})
        structure = Structure.from_dict(d["calcs_reversed"][-1]["output"]['structure'])
        gibbs_summary_dict["structure"] = structure.as_dict()

        # get the data(energy, volume, force constant) from the deformation runs
        docs = mmdb.collection.find({"task_label": {"$regex": "{} gibbs*".format(tag)},
                                     "formula_pretty": structure.composition.reduced_formula})
        energies = []
        volumes = []
        force_constants = []
        for d in docs:
            s = Structure.from_dict(d["calcs_reversed"][-1]["output"]['structure'])
            energies.append(d["calcs_reversed"][-1]["output"]['energy'])
            if qha_type not in ["debye_model"]:
                force_constants.append(d["calcs_reversed"][-1]["output"]['force_constants'])
            volumes.append(s.volume)
        gibbs_summary_dict["energies"] = energies
        gibbs_summary_dict["volumes"] = volumes
        if qha_type not in ["debye_model"]:
            gibbs_summary_dict["force_constants"] = force_constants

        G, T = None, None
        # use debye model
        if qha_type in ["debye_model"]:

            from atomate.tools.analysis import get_debye_model_gibbs

            G, T = get_debye_model_gibbs(energies, volumes, structure, t_min, t_step, t_max, eos,
                                         pressure)

        # use the phonopy interface
        else:

            from atomate.tools.analysis import get_phonopy_gibbs

            G, T = get_phonopy_gibbs(energies, volumes, force_constants, structure, t_min, t_step,
                                     t_max, mesh, eos, pressure)

        gibbs_summary_dict["G"] = G
        gibbs_summary_dict["T"] = T

        with open("gibbs.json", "w") as f:
            f.write(json.dumps(gibbs_summary_dict, default=DATETIME_HANDLER))
        logger.info("GIBBS FREE ENERGY CALCULATION COMPLETE")
Ejemplo n.º 13
0
    def run_task(self, fw_spec):

        from pymatgen.analysis.eos import EOS

        eos = self.get("eos", "vinet")
        tag = self["tag"]
        db_file = env_chk(self.get("db_file"), fw_spec)
        summary_dict = {"eos": eos}
        to_db = self.get("to_db", True)

        # collect and store task_id of all related tasks to make unique links with "tasks" collection
        all_task_ids = []

        mmdb = VaspCalcDb.from_db_file(db_file, admin=True)
        # get the optimized structure
        d = mmdb.collection.find_one({"task_label": "{} structure optimization".format(tag)})
        all_task_ids.append(d["task_id"])
        structure = Structure.from_dict(d["calcs_reversed"][-1]["output"]['structure'])
        summary_dict["structure"] = structure.as_dict()
        summary_dict["formula_pretty"] = structure.composition.reduced_formula

        # get the data(energy, volume, force constant) from the deformation runs
        docs = mmdb.collection.find({"task_label": {"$regex": "{} bulk_modulus*".format(tag)},
                                     "formula_pretty": structure.composition.reduced_formula})
        energies = []
        volumes = []
        for d in docs:
            s = Structure.from_dict(d["calcs_reversed"][-1]["output"]['structure'])
            energies.append(d["calcs_reversed"][-1]["output"]['energy'])
            volumes.append(s.volume)
            all_task_ids.append(d["task_id"])
        summary_dict["energies"] = energies
        summary_dict["volumes"] = volumes
        summary_dict["all_task_ids"] = all_task_ids

        # fit the equation of state
        eos = EOS(eos)
        eos_fit = eos.fit(volumes, energies)
        summary_dict["bulk_modulus"] = eos_fit.b0_GPa

        # TODO: find a better way for passing tags of the entire workflow to db - albalu
        if fw_spec.get("tags", None):
            summary_dict["tags"] = fw_spec["tags"]
        summary_dict["results"] = dict(eos_fit.results)
        summary_dict["created_at"] = datetime.utcnow()

        # db_file itself is required but the user can choose to pass the results to db or not
        if to_db:
            mmdb.collection = mmdb.db["eos"]
            mmdb.collection.insert_one(summary_dict)
        else:
            with open("bulk_modulus.json", "w") as f:
                f.write(json.dumps(summary_dict, default=DATETIME_HANDLER))

        # TODO: @matk86 - there needs to be a builder to put it into materials collection... -computron
        logger.info("Bulk modulus calculation complete.")
    def test_apply_transformation_mult(self):
        # Test returning multiple structures from each transformation.
        disord = Structure(np.eye(3) * 4.209, [{"Cs+": 0.5, "K+": 0.5}, "Cl-"], [[0, 0, 0], [0.5, 0.5, 0.5]])
        disord.make_supercell([2, 2, 1])

        tl = [EnumerateStructureTransformation(), OrderDisorderedStructureTransformation()]
        t = SuperTransformation(tl, nstructures_per_trans=10)
        self.assertEqual(len(t.apply_transformation(disord, return_ranked_list=20)), 8)
        t = SuperTransformation(tl)
        self.assertEqual(len(t.apply_transformation(disord, return_ranked_list=20)), 2)
Ejemplo n.º 15
0
 def setUp(self):
     c1 = [[0.5] * 3, [0.9] * 3]
     c2 = [[0.5] * 3, [0.9, 0.1, 0.1]]
     s1 = Structure(Lattice.cubic(5), ['Si', 'Si'], c1)
     s2 = Structure(Lattice.cubic(5), ['Si', 'Si'], c2)
     structs = []
     for s in s1.interpolate(s2, 3, pbc=True):
         structs.append(Structure.from_sites(s.sites, to_unit_cell=True))
     self.structures = structs
     self.vis = MITNEBSet(self.structures)
Ejemplo n.º 16
0
    def test_supercell_fit(self):
        sm = StructureMatcher(attempt_supercell=False)
        s1 = Structure.from_file(os.path.join(test_dir, "Al3F9.json"))
        s2 = Structure.from_file(os.path.join(test_dir, "Al3F9_distorted.json"))

        self.assertFalse(sm.fit(s1, s2))

        sm = StructureMatcher(attempt_supercell=True)

        self.assertTrue(sm.fit(s1, s2))
        self.assertTrue(sm.fit(s2, s1))
Ejemplo n.º 17
0
    def test_write_inputs(self):
        c1 = [[0.5] * 3, [0.9] * 3]
        c2 = [[0.5] * 3, [0.9, 0.1, 0.1]]
        s1 = Structure(Lattice.cubic(5), ['Si', 'Si'], c1)
        s2 = Structure(Lattice.cubic(5), ['Si', 'Si'], c2)
        structs = []
        for s in s1.interpolate(s2, 3, pbc=True):
            structs.append(Structure.from_sites(s.sites, to_unit_cell=True))

        fc = self.vis._process_structures(structs)[2].frac_coords
        self.assertTrue(np.allclose(fc, [[0.5]*3,[0.9, 1.033333, 1.0333333]]))
Ejemplo n.º 18
0
 def run(self):
     if os.path.exists("CONTCAR"):
         structure = Structure.from_file("CONTCAR")
     elif (not self.contcar_only) and os.path.exists("POSCAR"):
         structure = Structure.from_file("POSCAR")
     else:
         raise RuntimeError("No CONTCAR/POSCAR detected to generate input!")
     modname, classname = self.input_set.rsplit(".", 1)
     mod = __import__(modname, globals(), locals(), [classname], 0)
     vis = getattr(mod, classname)(structure, **self.kwargs)
     vis.write_input(".")
Ejemplo n.º 19
0
    def test_dict_to_object(self):
        coords = [[0, 0, 0], [0.75, 0.5, 0.75]]
        lattice = Lattice([[3.8401979337, 0.00, 0.00],
                           [1.9200989668, 3.3257101909, 0.00],
                           [0.00, -2.2171384943, 3.1355090603]])
        struct = Structure(lattice, ["Si"] * 2, coords)
        d = {'structure_dict': [struct.as_dict(), struct.as_dict()]}
        df = DataFrame(data=d)

        df["structure"] = dict_to_object(df["structure_dict"])
        self.assertEqual(df["structure"].tolist()[0], struct)
        self.assertEqual(df["structure"].tolist()[1], struct)
Ejemplo n.º 20
0
    def setUp(self):

        # 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))

        # 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()
Ejemplo n.º 21
0
    def run_task(self, fw_spec):

        from atomate.vasp.analysis.phonopy import get_phonopy_thermal_expansion

        tag = self["tag"]
        db_file = env_chk(self.get("db_file"), fw_spec)
        t_step = self.get("t_step", 10)
        t_min = self.get("t_min", 0)
        t_max = self.get("t_max", 1000)
        mesh = self.get("mesh", [20, 20, 20])
        eos = self.get("eos", "vinet")
        pressure = self.get("pressure", 0.0)
        summary_dict = {}

        mmdb = VaspCalcDb.from_db_file(db_file, admin=True)
        # get the optimized structure
        d = mmdb.collection.find_one({"task_label": "{} structure optimization".format(tag)})
        structure = Structure.from_dict(d["calcs_reversed"][-1]["output"]['structure'])
        summary_dict["structure"] = structure.as_dict()
        summary_dict["formula_pretty"] = structure.composition.reduced_formula

        # get the data(energy, volume, force constant) from the deformation runs
        docs = mmdb.collection.find({"task_label": {"$regex": "{} thermal_expansion*".format(tag)},
                                     "formula_pretty": structure.composition.reduced_formula})
        energies = []
        volumes = []
        force_constants = []
        for d in docs:
            s = Structure.from_dict(d["calcs_reversed"][-1]["output"]['structure'])
            energies.append(d["calcs_reversed"][-1]["output"]['energy'])
            volumes.append(s.volume)
            force_constants.append(d["calcs_reversed"][-1]["output"]['force_constants'])
        summary_dict["energies"] = energies
        summary_dict["volumes"] = volumes
        summary_dict["force_constants"] = force_constants

        alpha, T = get_phonopy_thermal_expansion(energies, volumes, force_constants, structure,
                                                 t_min, t_step, t_max, mesh, eos, pressure)

        summary_dict["alpha"] = alpha
        summary_dict["T"] = T

        with open("thermal_expansion.json", "w") as f:
            f.write(json.dumps(summary_dict, default=DATETIME_HANDLER))

        # TODO: @matk86 - there needs to be a way to insert this into a database! And also
        # a builder to put it into materials collection... -computron
        logger.info("Thermal expansion coefficient calculation complete.")
Ejemplo n.º 22
0
    def test_partial_disorder(self):
        s = Structure.from_file(filename=os.path.join(test_dir, "garnet.cif"))
        a = SpacegroupAnalyzer(s, 0.1)
        prim = a.find_primitive()
        s = prim.copy()
        s["Al3+"] = {"Al3+": 0.5, "Ga3+": 0.5}
        adaptor = EnumlibAdaptor(s, 1, 1, enum_precision_parameter=0.01)
        adaptor.run()
        structures = adaptor.structures
        self.assertEqual(len(structures), 7)
        for s in structures:
            self.assertEqual(s.formula, 'Ca12 Al4 Ga4 Si12 O48')
        s = prim.copy()
        s["Ca2+"] = {"Ca2+": 1/3, "Mg2+": 2/3}
        adaptor = EnumlibAdaptor(s, 1, 1, enum_precision_parameter=0.01)
        adaptor.run()
        structures = adaptor.structures
        self.assertEqual(len(structures), 20)
        for s in structures:
            self.assertEqual(s.formula, 'Ca4 Mg8 Al8 Si12 O48')

        s = prim.copy()
        s["Si4+"] = {"Si4+": 1/3, "Ge4+": 2/3}
        adaptor = EnumlibAdaptor(s, 1, 1, enum_precision_parameter=0.01)
        adaptor.run()
        structures = adaptor.structures
        self.assertEqual(len(structures), 18)
        for s in structures:
            self.assertEqual(s.formula, 'Ca12 Al8 Si4 Ge8 O48')
Ejemplo n.º 23
0
 def run_task(self, fw_spec):
     s = Structure.from_dict(self["structure"])
     mod = __import__("pymatgen.io.vaspio_set", globals(), locals(),
                      [self["vasp_input_set"]], -1)
     vis = load_class("pymatgen.io.vaspio_set", self["vasp_input_set"])(
         **self.get("input_set_params", {}))
     vis.write_input(s, ".")
Ejemplo n.º 24
0
 def test_timeout(self):
     s = Structure.from_file(filename=os.path.join(test_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)
Ejemplo n.º 25
0
def generate_diffraction_plot(args):
    s = Structure.from_file(args.filenames[0])
    c = XRDCalculator()
    if args.outfile:
        c.get_xrd_plot(s).savefig(args.outfile[0])
    else:
        c.show_xrd_plot(s)
Ejemplo n.º 26
0
    def _create_new_material(self, taskdoc):
        """
        Create a new material document.

        Args:
            taskdoc (dict): a JSON-like task document

        Returns:
            (int) - material_id of the new document
        """
        doc = {"created_at": datetime.utcnow()}
        doc["_tasksbuilder"] = {"all_task_ids": [], "prop_metadata":
            {"labels": {}, "task_ids": {}}, "updated_at": datetime.utcnow()}
        doc["spacegroup"] = taskdoc["output"]["spacegroup"]
        doc["sg_symbol"] = doc["spacegroup"]["symbol"]
        doc["sg_number"] = doc["spacegroup"]["number"]
        doc["structure"] = taskdoc["output"]["structure"]
        doc["material_id"] = self.mid_str(self._counter.find_one_and_update(
                        {"_id": "materialid"}, {"$inc": {"c": 1}}, return_document=ReturnDocument.AFTER)["c"])
        for x in ["formula_anonymous", "formula_pretty", "formula_reduced_abc",
                  "elements", "nelements", "chemsys"]:
            doc[x] = taskdoc[x]

        if "parent_structure" in taskdoc:
            doc["parent_structure"] = taskdoc["parent_structure"]
            t_struct = Structure.from_dict(taskdoc["parent_structure"]["structure"])
            doc["parent_structure"]["formula_reduced_abc"] = t_struct.composition.reduced_formula
        self._materials.insert_one(doc)

        return doc["material_id"]
Ejemplo n.º 27
0
    def run(self):
        print("MaterialsEhullBuilder starting...")
        self._build_indexes()

        q = {"thermo.energy": {"$exists": True}}
        if not self.update_all:
            q["stability"] = {"$exists": False}

        mats = [m for m in self._materials.find(q, {"calc_settings": 1, "structure": 1,
                                                    "thermo.energy": 1, "material_id": 1})]
        pbar = tqdm(mats)
        for m in pbar:
            pbar.set_description("Processing materials_id: {}".format(m['material_id']))
            try:
                params = {}
                for x in ["is_hubbard", "hubbards", "potcar_spec"]:
                    params[x] = m["calc_settings"][x]

                structure = Structure.from_dict(m["structure"])
                energy = m["thermo"]["energy"]
                my_entry = ComputedEntry(structure.composition, energy, parameters=params)
                self._materials.update_one({"material_id": m["material_id"]},
                                           {"$set": {"stability": self.mpr.get_stability([my_entry])[0]}})

                mpids = self.mpr.find_structure(structure)
                self._materials.update_one({"material_id": m["material_id"]}, {"$set": {"mpids": mpids}})

            except:
                import traceback
                print("<---")
                print("There was an error processing material_id: {}".format(m))
                traceback.print_exc()
                print("--->")

        print("MaterialsEhullBuilder finished processing.")
def create_df():
    newcoll = db['abc3']
    newcoll.drop()
    x = 0
    for doc in db['pauling_file_min_tags'].find().batch_size(75):
        x += 1
        if x % 1000 == 0:
            print x
        if doc['metadata']['_structure']['anonymized_formula'] == 'ABC3' and doc['is_ht'] in [True,False] \
                and 'TiO3' in doc['metadata']['_structure']['reduced_cell_formula']:
            newcoll.insert(doc)
    cursor = newcoll.find()
    df = pd.DataFrame(list(cursor))
    for i, row in df.iterrows():
        df.set_value(i, 'reduced_cell_formula', row['metadata']['_structure']['reduced_cell_formula'])
        try:
            df.set_value(i, 'space_group', int(row['metadata']['_Springer']['geninfo']['Space Group']))
        except:
            df.set_value(i, 'space_group', None)
        try:
            df.set_value(i, 'density', float(row['metadata']['_Springer']['geninfo']['Density'].split()[2]))
        except IndexError as e:
            df.set_value(i, 'density', None)
        structure = Structure.from_dict(row['structure'])
        num_density = (structure.num_sites/structure.volume)
        no_of_atoms = Composition(structure.composition).num_atoms
        num_vol = (structure.volume/no_of_atoms)
        df.set_value(i, 'number_density', num_density)
        df.set_value(i, 'number_volume', num_vol)
        if row['metadata']['_structure']['is_ordered']:
            df.set_value(i, 'is_ordered', 1)
        else:
            df.set_value(i, 'is_ordered', 0)
    df.to_pickle('abc3.pkl')
Ejemplo n.º 29
0
 def setUp(self):
     with open(os.path.join(test_dir, "TiO2_entries.json"), 'r') as fp:
         entries = json.load(fp, cls=MontyDecoder)
     self.struct_list = [e.structure for e in entries]
     self.oxi_structs = [self.get_structure("Li2O"),
                         Structure.from_file(os.path.join(
                             test_dir, "POSCAR.Li2O"))]
Ejemplo n.º 30
0
 def get(self, cid, name):
     """Retrieve structure for contribution in CIF format.
     ---
     operationId: get_cif
     parameters:
         - name: cid
           in: path
           type: string
           pattern: '^[a-f0-9]{24}$'
           required: true
           description: contribution ID (ObjectId)
         - name: name
           in: path
           type: string
           required: true
           description: name of structure
     responses:
         200:
             description: structure in CIF format
             schema:
                 type: string
     """
     mask = [f'content.structures.{name}']
     entry = Contributions.objects.only(*mask).get(id=cid)
     structure = Structure.from_dict(entry.content.structures.get(name))
     if structure:
         return CifWriter(structure, symprec=1e-10).__str__()
     return f"Structure with name {name} not found for {cid}!" # TODO raise 404?
Ejemplo n.º 31
0
 def substrate(self):
     """
     Return the substrate (Structure) of the interface.
     """
     return Structure.from_sites(self.substrate_sites)
Ejemplo n.º 32
0
 def setUp(self):
     self.single_bond = Structure(
         Lattice.cubic(10),
         ["H", "H", "H"], [[1, 0, 0], [0, 0, 0], [6, 0, 0]],
         validate_proximity=False,
         to_unit_cell=False, coords_are_cartesian=True,
         site_properties=None)
     self.linear = Structure(
         Lattice.cubic(10),
         ["H", "H", "H"], [[1, 0, 0], [0, 0, 0], [2, 0, 0]],
         validate_proximity=False,
         to_unit_cell=False, coords_are_cartesian=True,
         site_properties=None)
     self.bent45 = Structure(
         Lattice.cubic(10), ["H", "H", "H"],
         [[0, 0, 0], [0.707, 0.707, 0], [0.707, 0, 0]],
         validate_proximity=False,
         to_unit_cell=False, coords_are_cartesian=True,
         site_properties=None)
     self.cubic = Structure(
         Lattice.cubic(1),
         ["H"], [[0, 0, 0]], validate_proximity=False,
         to_unit_cell=False, coords_are_cartesian=False,
         site_properties=None)
     self.bcc = Structure(
         Lattice.cubic(1),
         ["H", "H"], [[0, 0, 0], [0.5, 0.5, 0.5]],
         validate_proximity=False, to_unit_cell=False,
         coords_are_cartesian=False, site_properties=None)
     self.fcc = Structure(
         Lattice.cubic(1), ["H", "H", "H", "H"],
         [[0, 0, 0], [0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]],
         validate_proximity=False, to_unit_cell=False,
         coords_are_cartesian=False, site_properties=None)
     self.hcp = Structure(
         Lattice.hexagonal(1, 1.633),
         ["H", "H"],
         [[0.3333, 0.6667, 0.25], [0.6667, 0.3333, 0.75]],
         validate_proximity=False, to_unit_cell=False,
         coords_are_cartesian=False, site_properties=None)
     self.diamond = Structure(
         Lattice.cubic(1), ["H", "H", "H", "H", "H", "H", "H", "H"],
         [[0, 0, 0.5], [0.75, 0.75, 0.75], [0, 0.5, 0], [0.75, 0.25, 0.25],
          [0.5, 0, 0], [0.25, 0.75, 0.25], [0.5, 0.5, 0.5],
          [0.25, 0.25, 0.75]], validate_proximity=False, to_unit_cell=False,
         coords_are_cartesian=False, site_properties=None)
     self.trigonal_off_plane = Structure(
         Lattice.cubic(100),
         ["H", "H", "H", "H"],
         [[0.50, 0.50, 0.50], [0.25, 0.75, 0.25],
          [0.25, 0.25, 0.75], [0.75, 0.25, 0.25]],
         validate_proximity=False, to_unit_cell=False,
         coords_are_cartesian=True, site_properties=None)
     self.regular_triangle = Structure(
         Lattice.cubic(30), ["H", "H", "H", "H"],
         [[15, 15.28867, 15.65], [14.5, 15, 15], [15.5, 15, 15],
          [15, 15.866, 15]], validate_proximity=False, to_unit_cell=False,
         coords_are_cartesian=True, site_properties=None)
     self.trigonal_planar = Structure(
         Lattice.cubic(30), ["H", "H", "H", "H"],
         [[15, 15.28867, 15], [14.5, 15, 15], [15.5, 15, 15],
          [15, 15.866, 15]], validate_proximity=False, to_unit_cell=False,
         coords_are_cartesian=True, site_properties=None)
     self.square_planar = Structure(
         Lattice.cubic(30), ["H", "H", "H", "H", "H"],
         [[15, 15, 15], [14.75, 14.75, 15], [14.75, 15.25, 15],
          [15.25, 14.75, 15], [15.25, 15.25, 15]],
         validate_proximity=False, to_unit_cell=False,
         coords_are_cartesian=True, site_properties=None)
     self.square = Structure(
         Lattice.cubic(30), ["H", "H", "H", "H", "H"],
         [[15, 15, 15.707], [14.75, 14.75, 15], [14.75, 15.25, 15],
          [15.25, 14.75, 15], [15.25, 15.25, 15]],
         validate_proximity=False, to_unit_cell=False,
         coords_are_cartesian=True, site_properties=None)
     self.T_shape = Structure(
         Lattice.cubic(30), ["H", "H", "H", "H"],
         [[15, 15, 15], [15, 15, 15.5], [15, 15.5, 15],
          [15, 14.5, 15]],
         validate_proximity=False, to_unit_cell=False,
         coords_are_cartesian=True, site_properties=None)
     self.square_pyramid = Structure(
         Lattice.cubic(30), ["H", "H", "H", "H", "H", "H"],
         [[15, 15, 15], [15, 15, 15.3535], [14.75, 14.75, 15],
          [14.75, 15.25, 15], [15.25, 14.75, 15], [15.25, 15.25, 15]],
         validate_proximity=False, to_unit_cell=False,
         coords_are_cartesian=True, site_properties=None)
     self.pentagonal_planar = Structure(
         Lattice.cubic(30), ["Xe", "F", "F", "F", "F", "F"],
         [[0, -1.6237, 0], [1.17969, 0, 0], [-1.17969, 0, 0],
          [1.90877, -2.24389, 0], [-1.90877, -2.24389, 0], [0, -3.6307, 0]],
         validate_proximity=False, to_unit_cell=False,
         coords_are_cartesian=True, site_properties=None)
     self.pentagonal_pyramid = Structure(
         Lattice.cubic(30), ["Xe", "F", "F", "F", "F", "F", "F"],
         [[0, -1.6237, 0], [0, -1.6237, 1.17969], [1.17969, 0, 0],
          [-1.17969, 0, 0], [1.90877, -2.24389, 0],
          [-1.90877, -2.24389, 0], [0, -3.6307, 0]],
         validate_proximity=False, to_unit_cell=False,
         coords_are_cartesian=True, site_properties=None)
     self.pentagonal_bipyramid = Structure(
         Lattice.cubic(30),
         ["Xe", "F", "F", "F", "F", "F", "F", "F"],
         [[0, -1.6237, 0], [0, -1.6237, -1.17969],
          [0, -1.6237, 1.17969], [1.17969, 0, 0],
          [-1.17969, 0, 0], [1.90877, -2.24389, 0],
          [-1.90877, -2.24389, 0], [0, -3.6307, 0]],
         validate_proximity=False, to_unit_cell=False,
         coords_are_cartesian=True, site_properties=None)
     self.hexagonal_planar = Structure(
         Lattice.cubic(30),
         ["H", "C", "C", "C", "C", "C", "C"],
         [[0, 0, 0], [0.71, 1.2298, 0],
          [-0.71, 1.2298, 0], [0.71, -1.2298, 0], [-0.71, -1.2298, 0],
          [1.4199, 0, 0], [-1.4199, 0, 0]],
         validate_proximity=False, to_unit_cell=False,
         coords_are_cartesian=True, site_properties=None)
     self.hexagonal_pyramid = Structure(
         Lattice.cubic(30),
         ["H", "Li", "C", "C", "C", "C", "C", "C"],
         [[0, 0, 0], [0, 0, 1.675], [0.71, 1.2298, 0],
          [-0.71, 1.2298, 0], [0.71, -1.2298, 0], [-0.71, -1.2298, 0],
          [1.4199, 0, 0], [-1.4199, 0, 0]],
         validate_proximity=False, to_unit_cell=False,
         coords_are_cartesian=True, site_properties=None)
     self.hexagonal_bipyramid = Structure(
         Lattice.cubic(30),
         ["H", "Li", "Li", "C", "C", "C", "C", "C", "C"],
         [[0, 0, 0], [0, 0, 1.675], [0, 0, -1.675],
          [0.71, 1.2298, 0], [-0.71, 1.2298, 0],
          [0.71, -1.2298, 0], [-0.71, -1.2298, 0],
          [1.4199, 0, 0], [-1.4199, 0, 0]],
         validate_proximity=False, to_unit_cell=False,
         coords_are_cartesian=True, site_properties=None)
     self.trigonal_pyramid = Structure(
         Lattice.cubic(30),
         ["P", "Cl", "Cl", "Cl", "Cl"],
         [[0, 0, 0], [0, 0, 2.14], [0, 2.02, 0],
          [1.74937, -1.01, 0], [-1.74937, -1.01, 0]],
         validate_proximity=False, to_unit_cell=False,
         coords_are_cartesian=True, site_properties=None)
     self.trigonal_bipyramidal = Structure(
         Lattice.cubic(30), ["P", "Cl", "Cl", "Cl", "Cl", "Cl"],
         [[0, 0, 0], [0, 0, 2.14], [0, 2.02, 0],
          [1.74937, -1.01, 0], [-1.74937, -1.01, 0], [0, 0, -2.14]],
         validate_proximity=False, to_unit_cell=False,
         coords_are_cartesian=True, site_properties=None)
     self.cuboctahedron = Structure(
         Lattice.cubic(30),
         ["H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H"],
         [[15, 15, 15], [15, 14.5, 14.5], [15, 14.5, 15.5],
          [15, 15.5, 14.5], [15, 15.5, 15.5],
          [14.5, 15, 14.5], [14.5, 15, 15.5], [15.5, 15, 14.5], [15.5, 15, 15.5],
          [14.5, 14.5, 15], [14.5, 15.5, 15], [15.5, 14.5, 15], [15.5, 15.5, 15]],
         validate_proximity=False, to_unit_cell=False,
         coords_are_cartesian=True, site_properties=None)
     self.see_saw_rect = Structure(
         Lattice.cubic(30),
         ["H", "H", "H", "H", "H"],
         [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, -1.0, 0.0],
          [0.0, 0.0, -1.0], [-1.0, 0.0, 0.0]],
         validate_proximity=False, to_unit_cell=False,
         coords_are_cartesian=True, site_properties=None)
     self.sq_face_capped_trig_pris = Structure(
         Lattice.cubic(30),
         ["H", "H", "H", "H", "H", "H", "H", "H"],
         [[0, 0, 0], [-0.6546536707079771, -0.37796447300922725, 0.6546536707079771],
          [0.6546536707079771, -0.37796447300922725, 0.6546536707079771],
          [0.0, 0.7559289460184545, 0.6546536707079771],
          [-0.6546536707079771, -0.37796447300922725, -0.6546536707079771],
          [0.6546536707079771, -0.37796447300922725, -0.6546536707079771],
          [0.0, 0.7559289460184545, -0.6546536707079771], [0.0, -1.0, 0.0]],
         validate_proximity=False, to_unit_cell=False,
         coords_are_cartesian=True, site_properties=None)
Ejemplo n.º 33
0
 def setUp(self):
     self.diamond = Structure(
         Lattice([[2.189, 0, 1.264], [0.73, 2.064, 1.264], [0, 0, 2.528]]),
         ["C", "C"], [[2.554, 1.806, 4.423], [0.365, 0.258, 0.632]],
         coords_are_cartesian=True
     )
Ejemplo n.º 34
0
    def test_oxide_type(self):
        el_li = Element("Li")
        el_o = Element("O")
        latt = Lattice([[3.985034, 0.0, 0.0], [0.0, 4.881506, 0.0],
                        [0.0, 0.0, 2.959824]])
        elts = [el_li, el_li, el_o, el_o, el_o, el_o]
        coords = list()
        coords.append([0.500000, 0.500000, 0.500000])
        coords.append([0.0, 0.0, 0.0])
        coords.append([0.632568, 0.085090, 0.500000])
        coords.append([0.367432, 0.914910, 0.500000])
        coords.append([0.132568, 0.414910, 0.000000])
        coords.append([0.867432, 0.585090, 0.000000])
        struct = Structure(latt, elts, coords)
        self.assertEqual(oxide_type(struct, 1.1), "superoxide")

        el_li = Element("Li")
        el_o = Element("O")
        elts = [el_li, el_o, el_o, el_o]
        latt = Lattice.from_parameters(3.999911, 3.999911, 3.999911,
                                       133.847504, 102.228244, 95.477342)
        coords = [[0.513004, 0.513004,
                   1.000000], [0.017616, 0.017616, 0.000000],
                  [0.649993, 0.874790, 0.775203],
                  [0.099587, 0.874790, 0.224797]]
        struct = Structure(latt, elts, coords)
        self.assertEqual(oxide_type(struct, 1.1), "ozonide")

        latt = Lattice.from_parameters(3.159597, 3.159572, 7.685205, 89.999884,
                                       89.999674, 60.000510)
        el_li = Element("Li")
        el_o = Element("O")
        elts = [el_li, el_li, el_li, el_li, el_o, el_o, el_o, el_o]
        coords = [[0.666656, 0.666705,
                   0.750001], [0.333342, 0.333378, 0.250001],
                  [0.000001, 0.000041,
                   0.500001], [0.000001, 0.000021, 0.000001],
                  [0.333347, 0.333332,
                   0.649191], [0.333322, 0.333353, 0.850803],
                  [0.666666, 0.666686, 0.350813],
                  [0.666665, 0.666684, 0.149189]]
        struct = Structure(latt, elts, coords)
        self.assertEqual(oxide_type(struct, 1.1), "peroxide")

        el_li = Element("Li")
        el_o = Element("O")
        el_h = Element("H")
        latt = Lattice.from_parameters(3.565276, 3.565276, 4.384277, 90.000000,
                                       90.000000, 90.000000)
        elts = [el_h, el_h, el_li, el_li, el_o, el_o]
        coords = [[0.000000, 0.500000,
                   0.413969], [0.500000, 0.000000, 0.586031],
                  [0.000000, 0.000000,
                   0.000000], [0.500000, 0.500000, 0.000000],
                  [0.000000, 0.500000, 0.192672],
                  [0.500000, 0.000000, 0.807328]]
        struct = Structure(latt, elts, coords)
        self.assertEqual(oxide_type(struct, 1.1), "hydroxide")

        el_li = Element("Li")
        el_n = Element("N")
        el_h = Element("H")
        latt = Lattice.from_parameters(3.565276, 3.565276, 4.384277, 90.000000,
                                       90.000000, 90.000000)
        elts = [el_h, el_h, el_li, el_li, el_n, el_n]
        coords = [[0.000000, 0.500000,
                   0.413969], [0.500000, 0.000000, 0.586031],
                  [0.000000, 0.000000,
                   0.000000], [0.500000, 0.500000, 0.000000],
                  [0.000000, 0.500000, 0.192672],
                  [0.500000, 0.000000, 0.807328]]
        struct = Structure(latt, elts, coords)
        self.assertEqual(oxide_type(struct, 1.1), "None")

        el_o = Element("O")
        latt = Lattice.from_parameters(4.389828, 5.369789, 5.369789, 70.786622,
                                       69.244828, 69.244828)
        elts = [el_o, el_o, el_o, el_o, el_o, el_o, el_o, el_o]
        coords = [[0.844609, 0.273459,
                   0.786089], [0.155391, 0.213911, 0.726541],
                  [0.155391, 0.726541,
                   0.213911], [0.844609, 0.786089, 0.273459],
                  [0.821680, 0.207748,
                   0.207748], [0.178320, 0.792252, 0.792252],
                  [0.132641, 0.148222, 0.148222],
                  [0.867359, 0.851778, 0.851778]]
        struct = Structure(latt, elts, coords)
        self.assertEqual(oxide_type(struct, 1.1), "None")
Ejemplo n.º 35
0
    def run_task(self, fw_spec):

        gibbs_dict = {}

        tag = self["tag"]
        t_step = self.get("t_step", 10)
        t_min = self.get("t_min", 0)
        t_max = self.get("t_max", 1000)
        mesh = self.get("mesh", [20, 20, 20])
        eos = self.get("eos", "vinet")
        qha_type = self.get("qha_type", "debye_model")
        pressure = self.get("pressure", 0.0)
        poisson = self.get("poisson", 0.25)
        anharmonic_contribution = self.get("anharmonic_contribution", False)
        gibbs_dict["metadata"] = self.get("metadata", {})

        db_file = env_chk(self.get("db_file"), fw_spec)
        mmdb = VaspCalcDb.from_db_file(db_file, admin=True)
        # get the optimized structure
        d = mmdb.collection.find_one(
            {"task_label": "{} structure optimization".format(tag)},
            {"calcs_reversed": 1})
        structure = Structure.from_dict(
            d["calcs_reversed"][-1]["output"]['structure'])
        gibbs_dict["structure"] = structure.as_dict()
        gibbs_dict["formula_pretty"] = structure.composition.reduced_formula

        # get the data(energy, volume, force constant) from the deformation runs
        docs = mmdb.collection.find(
            {
                "task_label": {
                    "$regex": "{} gibbs*".format(tag)
                },
                "formula_pretty": structure.composition.reduced_formula
            }, {"calcs_reversed": 1})
        energies = []
        volumes = []
        force_constants = []
        for d in docs:
            s = Structure.from_dict(
                d["calcs_reversed"][-1]["output"]['structure'])
            energies.append(d["calcs_reversed"][-1]["output"]['energy'])
            if qha_type not in ["debye_model"]:
                force_constants.append(
                    d["calcs_reversed"][-1]["output"]['force_constants'])
            volumes.append(s.volume)
        gibbs_dict["energies"] = energies
        gibbs_dict["volumes"] = volumes
        if qha_type not in ["debye_model"]:
            gibbs_dict["force_constants"] = force_constants

        try:
            # use quasi-harmonic debye approximation
            if qha_type in ["debye_model"]:

                from pymatgen.analysis.quasiharmonic import QuasiharmonicDebyeApprox

                qhda = QuasiharmonicDebyeApprox(
                    energies,
                    volumes,
                    structure,
                    t_min,
                    t_step,
                    t_max,
                    eos,
                    pressure=pressure,
                    poisson=poisson,
                    anharmonic_contribution=anharmonic_contribution)
                gibbs_dict.update(qhda.get_summary_dict())
                gibbs_dict["anharmonic_contribution"] = anharmonic_contribution
                gibbs_dict["success"] = True

            # use the phonopy interface
            else:

                from atomate.vasp.analysis.phonopy import get_phonopy_gibbs

                G, T = get_phonopy_gibbs(energies, volumes, force_constants,
                                         structure, t_min, t_step, t_max, mesh,
                                         eos, pressure)
                gibbs_dict["gibbs_free_energy"] = G
                gibbs_dict["temperatures"] = T
                gibbs_dict["success"] = True

        # quasi-harmonic analysis failed, set the flag to false
        except:
            import traceback

            logger.warn("Quasi-harmonic analysis failed!")
            gibbs_dict["success"] = False
            gibbs_dict["traceback"] = traceback.format_exc()
            gibbs_dict['metadata'].update({"task_label_tag": tag})
            gibbs_dict["created_at"] = datetime.utcnow()

        gibbs_dict = jsanitize(gibbs_dict)

        # TODO: @matk86: add a list of task_ids that were used to construct the analysis to DB?
        # -computron
        if not db_file:
            dump_file = "gibbs.json"
            logger.info("Dumping the analysis summary to {}".format(dump_file))
            with open(dump_file, "w") as f:
                f.write(json.dumps(gibbs_dict, default=DATETIME_HANDLER))
        else:
            coll = mmdb.db["gibbs_tasks"]
            coll.insert_one(gibbs_dict)

        logger.info("Gibbs free energy calculation complete.")

        if not gibbs_dict["success"]:
            return FWAction(defuse_children=True)
Ejemplo n.º 36
0
 def test_ensure_vacuum_for_SiP(self):
     # Compound test for add_vacuum and get_spacing.
     os.chdir(ROOT)
     structure = Structure.from_file('POSCAR_SiP')
     structure = ensure_vacuum(structure, vacuum=15)
     self.assertAlmostEqual(get_spacing(structure), 15.0)
Ejemplo n.º 37
0
 def get_structure(self, sid):
     """Convenience function to get pymatgen structure."""
     return Structure.from_dict(
         self.structures.get_entry(pk=sid,
                                   _fields=["lattice", "sites",
                                            "charge"]).result())
Ejemplo n.º 38
0
    [['Fe', 'Y'], [u'sandbox-mvc-819'], [u'sandbox-mvc-1830']],
    [['Co', 'Y'], [u'sandbox-mvc-1596'], []],
    [['Ni', 'Y'], [u'mp-25595'], [u'sandbox-mvc-1778']]
]

batt_list = []

for result in results:
    if [] not in result:
        id_charge = result[1][0]
        id_discharge = result[2][0]

        dict_charge = materials.find({"task_id": id_charge})[0]
        dict_discharge = materials.find({"task_id": id_discharge})[0]

        charge_struc = Structure.from_dict(dict_charge["structure"])
        charge_energy = dict_charge["final_energy"]
        entry_charge = ComputedStructureEntry(charge_struc, charge_energy)
        charge_ehull = dict_charge["e_above_hull"]

        discharge_struc = Structure.from_dict(dict_discharge["structure"])
        discharge_energy = dict_discharge["final_energy"]
        entry_discharge = ComputedStructureEntry(discharge_struc,
                                                 discharge_energy)
        discharge_ehull = dict_discharge["e_above_hull"]

        mpr = MPRester(api_key=API_KEY, host="www.materialsproject.org")
        entries = mpr.get_entries(result[0][1], inc_structure="final")

        counter = 0
        energies = []
Ejemplo n.º 39
0
def main():
    """
    logicMain function. Does the cli
    """

    options = docopt(__doc__)

    poscar_path = options['<poscar>']
    if not exists(poscar_path):
        raise IOError('POSCAR file "{0}" does not exist.'.format(poscar_path))
    else:
        try:
            structure = Poscar.from_file(poscar_path).structure
            species = set(
                map_structure(structure, apply=lambda s: s.specie.symbol))
        except:
            raise IOError(
                'Could not parse POSCAR file "{0}"'.format(poscar_path))

    if options['--incar']:
        incar_path = options['--incar']
        if not exists(incar_path):
            raise IOError(
                'INCAR file "{0}" does not exist.'.format(incar_path))
        else:
            try:
                incar = Incar.from_file(incar_path)
            except:
                raise IOError(
                    'Could not parse INCAR file "{0}"'.format(incar_path))

    if options['supercell']:
        try:
            sx, sy, sz = [int(options['<s{0}>'.format(k)]) for k in 'xyz']
        except:
            raise ValueError('Could not parse supercell parameters')
        else:
            structure.make_supercell([sx, sy, sz])

    if options['direction']:
        try:
            dx, dy, dz = [int(options['<d{0}>'.format(k)]) for k in 'xyz']
        except:
            raise ValueError('Could not parse direction')
        else:
            cl_direction = unit_vector(np.array([dx, dy, dz]))
    else:
        cl_direction = unit_vector(np.array([1.0, 0.0, 0.0]))

    lengths = parse_lengths(options['<lengths>'])
    if not all([k in species for k in lengths.keys()]):
        missing_elements = set(lengths.keys()) - species
        raise ValueError(
            'The following element{0} {1} not specified in "{2}": {3}'.format(
                's' if len(missing_elements) > 1 else '',
                'are' if len(missing_elements) > 1 else 'is', poscar_path,
                ', '.join(list(missing_elements))))
    for missing_element in species - set(lengths.keys()):
        lengths[missing_element] = 0.0

    if options['ncl']:
        magmoms = generate_spins_vecs_ncl(structure, lengths)
        # Check if net magnetic moment is really zero
        sum_vec = np.array([array for _, v in magmoms.items() for array in v])
        assert np.isclose(np.sum(sum_vec, axis=0), np.zeros((3, ))).all()

    if options['cl']:
        if options['--imbalanced']:
            balanced = False
        else:
            balanced = True
        magmoms = generate_spins_vecs_cl(structure,
                                         lengths,
                                         direction=cl_direction,
                                         balanced=balanced)
        # Check if net magnetic moment is really zero
        sum_vec = np.array([array for _, v in magmoms.items() for array in v])
        assert np.isclose(np.sum(sum_vec, axis=0), np.zeros((3, ))).all()

    if options['fm']:
        magmoms = generate_spins_vecs_fm(structure,
                                         lengths,
                                         direction=cl_direction)

    frac_coords_list = []
    species_list = []
    magmom_str = []
    magmoms_site_property = {'magmom': []}
    for spec, magm in magmoms.items():
        # Assemble the species list and the fractional coords in the same order as the generated magnetic moments
        current_frac_coords = map_structure(
            structure,
            predicate=lambda site: site.specie.symbol == spec,
            apply=lambda site: site.frac_coords)
        species_list.extend([spec] * len(current_frac_coords))
        frac_coords_list.extend(current_frac_coords)
        # If direction is given calculate the projection of the moment onto the direction which gives length and
        # orientation
        if options['direction'] or options['ncl']:
            magmom_str.extend([
                ' '.join([make_format_crumb(i)
                          for i in range(3)]).format(mag_x, mag_y, mag_z)
                for mag_x, mag_y, mag_z in magm
            ])

            magmoms_site_property['magmom'].extend(
                [mag_x, mag_y, mag_z] for mag_x, mag_y, mag_z in magm)
        else:
            magmom_str.extend([
                make_format_crumb(0).format(
                    np.dot(cl_direction, np.array([mag_x, mag_y, mag_z])))
                for mag_x, mag_y, mag_z in magm
            ])
            magmoms_site_property['magmom'].extend([
                np.dot(cl_direction, np.array([mag_x, mag_y, mag_z]))
                for mag_x, mag_y, mag_z in magm
            ])

    # Create the new structure
    new_structure = Structure(structure.lattice,
                              species_list,
                              frac_coords_list,
                              site_properties=magmoms_site_property)
    magmom_str = '  '.join(magmom_str)

    # Write the new Posar file
    Poscar(new_structure).write_file(
        file_exists('{0}{1}'.format(poscar_path, OUTPUT_SUFFIX)))
    if options['--incar']:
        incar['MAGMOM'] = magmom_str
        incar.write_file(file_exists('INCAR{0}'.format(OUTPUT_SUFFIX)))
    else:
        # Print the magnetic moment vector to the terminal
        print('MAGMOM = {0}'.format(magmom_str))

    if options['--plot']:
        plot_magmoms(magmoms)

    if options['--cif']:
        cif_writer = CifWriter(new_structure, write_magmoms=True)
        cif_writer.write_file(
            file_exists('{0}{1}.cif'.format(poscar_path, OUTPUT_SUFFIX)))
Ejemplo n.º 40
0
    def test_calculate(self):
        s1 = Structure.from_spacegroup(227, Lattice.cubic(5.46873),
                                       ['Si'],
                                       [[0, 0, 0]])
        profile1 = dict(Si=dict(r=0.5, w=1.9), C=dict(r=0.5, w=2.55))
        diag1 = np.random.randint(4)
        tjm1 = np.random.randint(1, 11)
        calculator1 = SpectralNeighborAnalysis(rcutfac=5, twojmax=tjm1,
                                               element_profile=profile1,
                                               quadratic=False,
                                               diagonalstyle=diag1)
        sna1, snad1, snav1, elem1 = calculator1.calculate([s1])[0]
        n1 = calculator1.n_bs
        self.assertAlmostEqual(sna1[0][0], 585.920)
        self.assertEqual(sna1.shape, (len(s1), n1))
        self.assertEqual(snad1.shape, (len(s1), n1 * 3 * len(profile1)))
        self.assertEqual(snav1.shape, (len(s1), n1 * 6 * len(profile1)))
        self.assertEqual(len(np.unique(elem1)), 1)

        calculator4 = SpectralNeighborAnalysis(rcutfac=5, twojmax=tjm1,
                                               element_profile=profile1,
                                               quadratic=True,
                                               diagonalstyle=diag1)
        sna4, snad4, snav4, elem4 = calculator4.calculate([s1])[0]
        n4 = calculator4.n_bs
        n4 += int((1 + n4) * n4 / 2)
        self.assertAlmostEqual(sna4[0][0], 585.920)
        self.assertEqual(sna4.shape, (len(s1), n4))
        self.assertEqual(snad4.shape, (len(s1), n4 * 3 * len(profile1)))
        self.assertEqual(snav4.shape, (len(s1), n4 * 6 * len(profile1)))
        self.assertEqual(len(np.unique(elem4)), 1)

        s2 = Structure.from_spacegroup(225, Lattice.cubic(5.69169),
                                       ['Na', 'Cl'],
                                       [[0, 0, 0], [0, 0, 0.5]])
        profile2 = dict(Na=dict(r=0.3, w=0.9),
                        Cl=dict(r=0.7, w=3.0))
        diag2 = np.random.randint(4)
        tjm2 = np.random.randint(1, 11)
        calculator2 = SpectralNeighborAnalysis(rcutfac=5, twojmax=tjm2,
                                               element_profile=profile2,
                                               quadratic=False,
                                               diagonalstyle=diag2)
        sna2, snad2, snav2, elem2 = calculator2.calculate([s2])[0]
        n2 = calculator2.n_bs
        self.assertAlmostEqual(sna2[0][0], 525.858)
        self.assertEqual(sna2.shape, (len(s2), n2))
        self.assertEqual(snad2.shape, (len(s2), n2 * 3 * len(profile2)))
        self.assertEqual(snav2.shape, (len(s2), n2 * 6 * len(profile2)))
        self.assertEqual(len(np.unique(elem2)), len(profile2))

        calculator5 = SpectralNeighborAnalysis(rcutfac=5, twojmax=tjm2,
                                               element_profile=profile2,
                                               quadratic=True,
                                               diagonalstyle=diag2)
        sna5, snad5, snav5, elem5 = calculator5.calculate([s2])[0]
        n5 = calculator5.n_bs
        n5 += int((1 + n5) * n5 / 2)
        self.assertAlmostEqual(sna5[0][0], 525.858)
        self.assertEqual(sna5.shape, (len(s2), n5))
        self.assertEqual(snad5.shape, (len(s2), n5 * 3 * len(profile2)))
        self.assertEqual(snav5.shape, (len(s2), n5 * 6 * len(profile2)))
        self.assertEqual(len(np.unique(elem5)), len(profile2))

        s3 = Structure.from_spacegroup(221, Lattice.cubic(3.88947),
                                       ['Ca', 'Ti', 'O'],
                                       [[0.5, 0.5, 0.5],
                                        [0, 0, 0],
                                        [0, 0, 0.5]])
        profile3 = dict(Ca=dict(r=0.4, w=1.0),
                        Ti=dict(r=0.3, w=1.5),
                        O=dict(r=0.75, w=3.5))
        diag3 = np.random.randint(4)
        tjm3 = np.random.randint(1, 11)
        calculator3 = SpectralNeighborAnalysis(rcutfac=5, twojmax=tjm3,
                                               element_profile=profile3,
                                               quadratic=False,
                                               diagonalstyle=diag3)
        sna3, snad3, snav3, elem3 = calculator3.calculate([s3])[0]
        n3 = calculator3.n_bs
        self.assertAlmostEqual(sna3[0][0], 25506.3)
        self.assertEqual(sna3.shape, (len(s3), n3))
        self.assertEqual(snad3.shape, (len(s3), n3 * 3 * len(profile3)))
        self.assertEqual(snav3.shape, (len(s3), n3 * 6 * len(profile3)))
        self.assertEqual(len(np.unique(elem3)), len(profile3))

        calculator6 = SpectralNeighborAnalysis(rcutfac=5, twojmax=tjm3,
                                               element_profile=profile3,
                                               quadratic=True,
                                               diagonalstyle=diag3)
        sna6, snad6, snav6, elem6 = calculator6.calculate([s3])[0]
        n6 = calculator6.n_bs
        n6 += int((1 + n6) * n6 / 2)
        self.assertAlmostEqual(sna6[0][0], 25506.3)
        self.assertEqual(sna6.shape, (len(s3), n6))
        self.assertEqual(snad6.shape, (len(s3), n6 * 3 * len(profile3)))
        self.assertEqual(snav6.shape, (len(s3), n6 * 6 * len(profile3)))
        self.assertEqual(len(np.unique(elem6)), len(profile3))
Ejemplo n.º 41
0
    def test_symmetrized(self):
        filepath = os.path.join(test_dir, 'POSCAR')
        poscar = Poscar.from_file(filepath)
        writer = CifWriter(poscar.structure, symprec=0.1)
        ans = """# generated using pymatgen
data_FePO4
_symmetry_space_group_name_H-M   Pnma
_cell_length_a   10.41176687
_cell_length_b   6.06717188
_cell_length_c   4.75948954
_cell_angle_alpha   90.00000000
_cell_angle_beta   90.00000000
_cell_angle_gamma   90.00000000
_symmetry_Int_Tables_number   62
_chemical_formula_structural   FePO4
_chemical_formula_sum   'Fe4 P4 O16'
_cell_volume   300.65685512
_cell_formula_units_Z   4
loop_
 _symmetry_equiv_pos_site_id
 _symmetry_equiv_pos_as_xyz
  1  'x, y, z'
  2  '-x, -y, -z'
  3  '-x+1/2, -y, z+1/2'
  4  'x+1/2, y, -z+1/2'
  5  'x+1/2, -y+1/2, -z+1/2'
  6  '-x+1/2, y+1/2, z+1/2'
  7  '-x, y+1/2, -z'
  8  'x, -y+1/2, z'
loop_
 _atom_site_type_symbol
 _atom_site_label
 _atom_site_symmetry_multiplicity
 _atom_site_fract_x
 _atom_site_fract_y
 _atom_site_fract_z
 _atom_site_occupancy
  Fe  Fe1  4  0.218728  0.250000  0.525133  1
  P  P2  4  0.094613  0.750000  0.581757  1
  O  O3  8  0.165710  0.546072  0.714616  1
  O  O4  4  0.043372  0.250000  0.292862  1
  O  O5  4  0.096642  0.750000  0.258680  1"""
        for l1, l2 in zip(str(writer).split("\n"), ans.split("\n")):
            self.assertEqual(l1.strip(), l2.strip())

        ans = """# generated using pymatgen
data_LiFePO4
_symmetry_space_group_name_H-M   Pnma
_cell_length_a   10.41037000
_cell_length_b   6.06577000
_cell_length_c   4.74480000
_cell_angle_alpha   90.00000000
_cell_angle_beta   90.00000000
_cell_angle_gamma   90.00000000
_symmetry_Int_Tables_number   62
_chemical_formula_structural   LiFePO4
_chemical_formula_sum   'Li4 Fe4 P4 O16'
_cell_volume   299.619458734
_cell_formula_units_Z   4
loop_
 _symmetry_equiv_pos_site_id
 _symmetry_equiv_pos_as_xyz
  1  'x, y, z'
  2  '-x, -y, -z'
  3  '-x+1/2, -y, z+1/2'
  4  'x+1/2, y, -z+1/2'
  5  'x+1/2, -y+1/2, -z+1/2'
  6  '-x+1/2, y+1/2, z+1/2'
  7  '-x, y+1/2, -z'
  8  'x, -y+1/2, z'
loop_
 _atom_site_type_symbol
 _atom_site_label
 _atom_site_symmetry_multiplicity
 _atom_site_fract_x
 _atom_site_fract_y
 _atom_site_fract_z
 _atom_site_occupancy
  Li  Li1  4  0.000000  0.000000  0.000000  1.0
  Fe  Fe2  4  0.218845  0.750000  0.474910  1.0
  P  P3  4  0.094445  0.250000  0.417920  1.0
  O  O4  8  0.165815  0.044060  0.286540  1.0
  O  O5  4  0.043155  0.750000  0.708460  1.0
  O  O6  4  0.096215  0.250000  0.741480  1.0
"""
        s = Structure.from_file(os.path.join(test_dir, 'LiFePO4.cif'))
        writer = CifWriter(s, symprec=0.1)
        s2 = CifParser.from_string(str(writer)).get_structures()[0]
        m = StructureMatcher()
        self.assertTrue(m.fit(s, s2))

        s = self.get_structure("Li2O")
        writer = CifWriter(s, symprec=0.1)
        ans = """# generated using pymatgen
data_Li2O
_symmetry_space_group_name_H-M   Fm-3m
_cell_length_a   4.61000000
_cell_length_b   4.61000000
_cell_length_c   4.61000000
_cell_angle_alpha   90.00000000
_cell_angle_beta   90.00000000
_cell_angle_gamma   90.00000000
_symmetry_Int_Tables_number   225
_chemical_formula_structural   Li2O
_chemical_formula_sum   'Li8 O4'
_cell_volume   97.972181
_cell_formula_units_Z   4
loop_
 _symmetry_equiv_pos_site_id
 _symmetry_equiv_pos_as_xyz
  1  'x, y, z'
  2  '-x, -y, -z'
  3  'z, y, -x'
  4  '-z, -y, x'
  5  '-x, y, -z'
  6  'x, -y, z'
  7  '-z, y, x'
  8  'z, -y, -x'
  9  'x, -y, -z'
  10  '-x, y, z'
  11  'z, -y, x'
  12  '-z, y, -x'
  13  '-x, -y, z'
  14  'x, y, -z'
  15  '-z, -y, -x'
  16  'z, y, x'
  17  'y, -z, -x'
  18  '-y, z, x'
  19  'y, x, -z'
  20  '-y, -x, z'
  21  'y, z, x'
  22  '-y, -z, -x'
  23  'y, -x, z'
  24  '-y, x, -z'
  25  '-y, z, -x'
  26  'y, -z, x'
  27  '-y, -x, -z'
  28  'y, x, z'
  29  '-y, -z, x'
  30  'y, z, -x'
  31  '-y, x, z'
  32  'y, -x, -z'
  33  '-z, x, -y'
  34  'z, -x, y'
  35  'x, z, -y'
  36  '-x, -z, y'
  37  'z, -x, -y'
  38  '-z, x, y'
  39  '-x, -z, -y'
  40  'x, z, y'
  41  'z, x, y'
  42  '-z, -x, -y'
  43  '-x, z, y'
  44  'x, -z, -y'
  45  '-z, -x, y'
  46  'z, x, -y'
  47  'x, -z, y'
  48  '-x, z, -y'
  49  'x+1/2, y+1/2, z'
  50  '-x+1/2, -y+1/2, -z'
  51  'z+1/2, y+1/2, -x'
  52  '-z+1/2, -y+1/2, x'
  53  '-x+1/2, y+1/2, -z'
  54  'x+1/2, -y+1/2, z'
  55  '-z+1/2, y+1/2, x'
  56  'z+1/2, -y+1/2, -x'
  57  'x+1/2, -y+1/2, -z'
  58  '-x+1/2, y+1/2, z'
  59  'z+1/2, -y+1/2, x'
  60  '-z+1/2, y+1/2, -x'
  61  '-x+1/2, -y+1/2, z'
  62  'x+1/2, y+1/2, -z'
  63  '-z+1/2, -y+1/2, -x'
  64  'z+1/2, y+1/2, x'
  65  'y+1/2, -z+1/2, -x'
  66  '-y+1/2, z+1/2, x'
  67  'y+1/2, x+1/2, -z'
  68  '-y+1/2, -x+1/2, z'
  69  'y+1/2, z+1/2, x'
  70  '-y+1/2, -z+1/2, -x'
  71  'y+1/2, -x+1/2, z'
  72  '-y+1/2, x+1/2, -z'
  73  '-y+1/2, z+1/2, -x'
  74  'y+1/2, -z+1/2, x'
  75  '-y+1/2, -x+1/2, -z'
  76  'y+1/2, x+1/2, z'
  77  '-y+1/2, -z+1/2, x'
  78  'y+1/2, z+1/2, -x'
  79  '-y+1/2, x+1/2, z'
  80  'y+1/2, -x+1/2, -z'
  81  '-z+1/2, x+1/2, -y'
  82  'z+1/2, -x+1/2, y'
  83  'x+1/2, z+1/2, -y'
  84  '-x+1/2, -z+1/2, y'
  85  'z+1/2, -x+1/2, -y'
  86  '-z+1/2, x+1/2, y'
  87  '-x+1/2, -z+1/2, -y'
  88  'x+1/2, z+1/2, y'
  89  'z+1/2, x+1/2, y'
  90  '-z+1/2, -x+1/2, -y'
  91  '-x+1/2, z+1/2, y'
  92  'x+1/2, -z+1/2, -y'
  93  '-z+1/2, -x+1/2, y'
  94  'z+1/2, x+1/2, -y'
  95  'x+1/2, -z+1/2, y'
  96  '-x+1/2, z+1/2, -y'
  97  'x+1/2, y, z+1/2'
  98  '-x+1/2, -y, -z+1/2'
  99  'z+1/2, y, -x+1/2'
  100  '-z+1/2, -y, x+1/2'
  101  '-x+1/2, y, -z+1/2'
  102  'x+1/2, -y, z+1/2'
  103  '-z+1/2, y, x+1/2'
  104  'z+1/2, -y, -x+1/2'
  105  'x+1/2, -y, -z+1/2'
  106  '-x+1/2, y, z+1/2'
  107  'z+1/2, -y, x+1/2'
  108  '-z+1/2, y, -x+1/2'
  109  '-x+1/2, -y, z+1/2'
  110  'x+1/2, y, -z+1/2'
  111  '-z+1/2, -y, -x+1/2'
  112  'z+1/2, y, x+1/2'
  113  'y+1/2, -z, -x+1/2'
  114  '-y+1/2, z, x+1/2'
  115  'y+1/2, x, -z+1/2'
  116  '-y+1/2, -x, z+1/2'
  117  'y+1/2, z, x+1/2'
  118  '-y+1/2, -z, -x+1/2'
  119  'y+1/2, -x, z+1/2'
  120  '-y+1/2, x, -z+1/2'
  121  '-y+1/2, z, -x+1/2'
  122  'y+1/2, -z, x+1/2'
  123  '-y+1/2, -x, -z+1/2'
  124  'y+1/2, x, z+1/2'
  125  '-y+1/2, -z, x+1/2'
  126  'y+1/2, z, -x+1/2'
  127  '-y+1/2, x, z+1/2'
  128  'y+1/2, -x, -z+1/2'
  129  '-z+1/2, x, -y+1/2'
  130  'z+1/2, -x, y+1/2'
  131  'x+1/2, z, -y+1/2'
  132  '-x+1/2, -z, y+1/2'
  133  'z+1/2, -x, -y+1/2'
  134  '-z+1/2, x, y+1/2'
  135  '-x+1/2, -z, -y+1/2'
  136  'x+1/2, z, y+1/2'
  137  'z+1/2, x, y+1/2'
  138  '-z+1/2, -x, -y+1/2'
  139  '-x+1/2, z, y+1/2'
  140  'x+1/2, -z, -y+1/2'
  141  '-z+1/2, -x, y+1/2'
  142  'z+1/2, x, -y+1/2'
  143  'x+1/2, -z, y+1/2'
  144  '-x+1/2, z, -y+1/2'
  145  'x, y+1/2, z+1/2'
  146  '-x, -y+1/2, -z+1/2'
  147  'z, y+1/2, -x+1/2'
  148  '-z, -y+1/2, x+1/2'
  149  '-x, y+1/2, -z+1/2'
  150  'x, -y+1/2, z+1/2'
  151  '-z, y+1/2, x+1/2'
  152  'z, -y+1/2, -x+1/2'
  153  'x, -y+1/2, -z+1/2'
  154  '-x, y+1/2, z+1/2'
  155  'z, -y+1/2, x+1/2'
  156  '-z, y+1/2, -x+1/2'
  157  '-x, -y+1/2, z+1/2'
  158  'x, y+1/2, -z+1/2'
  159  '-z, -y+1/2, -x+1/2'
  160  'z, y+1/2, x+1/2'
  161  'y, -z+1/2, -x+1/2'
  162  '-y, z+1/2, x+1/2'
  163  'y, x+1/2, -z+1/2'
  164  '-y, -x+1/2, z+1/2'
  165  'y, z+1/2, x+1/2'
  166  '-y, -z+1/2, -x+1/2'
  167  'y, -x+1/2, z+1/2'
  168  '-y, x+1/2, -z+1/2'
  169  '-y, z+1/2, -x+1/2'
  170  'y, -z+1/2, x+1/2'
  171  '-y, -x+1/2, -z+1/2'
  172  'y, x+1/2, z+1/2'
  173  '-y, -z+1/2, x+1/2'
  174  'y, z+1/2, -x+1/2'
  175  '-y, x+1/2, z+1/2'
  176  'y, -x+1/2, -z+1/2'
  177  '-z, x+1/2, -y+1/2'
  178  'z, -x+1/2, y+1/2'
  179  'x, z+1/2, -y+1/2'
  180  '-x, -z+1/2, y+1/2'
  181  'z, -x+1/2, -y+1/2'
  182  '-z, x+1/2, y+1/2'
  183  '-x, -z+1/2, -y+1/2'
  184  'x, z+1/2, y+1/2'
  185  'z, x+1/2, y+1/2'
  186  '-z, -x+1/2, -y+1/2'
  187  '-x, z+1/2, y+1/2'
  188  'x, -z+1/2, -y+1/2'
  189  '-z, -x+1/2, y+1/2'
  190  'z, x+1/2, -y+1/2'
  191  'x, -z+1/2, y+1/2'
  192  '-x, z+1/2, -y+1/2'
loop_
 _atom_type_symbol
 _atom_type_oxidation_number
  Li+  1.0
  O2-  -2.0
loop_
 _atom_site_type_symbol
 _atom_site_label
 _atom_site_symmetry_multiplicity
 _atom_site_fract_x
 _atom_site_fract_y
 _atom_site_fract_z
 _atom_site_occupancy
  Li+  Li1  8  0.250000  0.250000  0.250000  1.0
  O2-  O2  4  0.000000  0.000000  0.000000  1.0"""

        for l1, l2 in zip(str(writer).split("\n"), ans.split("\n")):
            self.assertEqual(l1.strip(), l2.strip())
Ejemplo n.º 42
0
from pymatgen import Structure
from pymatgen.symmetry.analyzer import SpacegroupAnalyzer
from pymatgen.transformations.advanced_transformations import EnumerateStructureTransformation
from pymatgen.io.vasp.sets import batch_write_input, MPRelaxSet
structure = Structure.from_file(
    "D:/Program Files (x86)/python2/file/EntryWithCollCode418490.cif")
# (获取文件 当在自己电脑中调试的时候需要将相关的路径统一一下)
print(structure)
# loop over all sites in the structure
for i, site in enumerate(structure):
    # (enumerate 为枚举类型)
    # change the occupancy of Li+ disordered sites to 0.5
    if not site.is_ordered:
        structure[i] = {"Li+": 0.5}
print("The composition after adjustments is %s." %
      structure.composition.reduced_formula)
analyzer = SpacegroupAnalyzer(structure)
#   SpacegroupAnalyzer为空间群分析  晶体内部结构中全部对称要素的集合称为 “空间群” 。
#   一切晶体结构中总共只能有230种不同的对称要素组合方式,即230个空间群所谓点空间群,
#   是由一个平移群和一个点群对称操作组合而成的,它的一般对称操作可以写成(R | t (αβγ)),其中R表示点群对称操作,t(αβγ)表示平移操作
#   为了保持可排序的顺序,我们只在原始单元上执行枚举。原始单元可以使用*空间群分析器*获得
prim_cell = analyzer.find_primitive()
print(prim_cell)
enum = EnumerateStructureTransformation()  # 变换枚举结构
enumerated = enum.apply_transformation(prim_cell, 90)  # 在这需要限制返回结构的数量
structures = [d["structure"] for d in enumerated]
print("%d structures returned." % len(structures))
Ejemplo n.º 43
0
 def test_get_structure_type_for_conventional_material(self):
     os.chdir(ROOT)
     structure = Structure.from_file('POSCAR_Fe')
     test_type = get_structure_type(structure)
     self.assertEqual(test_type, 'conventional')
Ejemplo n.º 44
0
 def film(self):
     """
     Return the film (Structure) of the interface.
     """
     return Structure.from_sites(self.film_sites)
Ejemplo n.º 45
0
def get_wf_surface(slabs,
                   molecules=[],
                   bulk_structure=None,
                   slab_gen_params=None,
                   vasp_cmd="vasp",
                   db_file=None,
                   ads_structures_params={},
                   add_molecules_in_box=False):
    """

    Args:
        slabs (list of Slabs or Structures): slabs to calculate
        molecules (list of Molecules): molecules to place as adsorbates
        bulk_structure (Structure): bulk structure from which generate slabs
            after reoptimization.  If supplied, workflow will begin with
            bulk structure optimization.
        slab_gen_params (dict): dictionary of slab generation parameters
            used to generate the slab, necessary to get the slab
            that corresponds to the bulk structure if in that mode
        ads_structures_params (dict): parameters to be supplied as
            kwargs to AdsorbateSiteFinder.generate_adsorption_structures
        add_molecules_in_box (boolean): flag to add calculation of molecule
            energies to the workflow
        db_file (string): path to database file
        vasp_cmd (string): vasp command

    Returns:
        Workflow
    """
    fws, parents = [], []

    if bulk_structure:
        vis = MVLSlabSet(bulk_structure, bulk=True)
        fws.append(
            OptimizeFW(structure=bulk_structure,
                       vasp_input_set=vis,
                       vasp_cmd="vasp",
                       db_file=db_file))
        parents = fws[0]

    for slab in slabs:
        name = slab.composition.reduced_formula
        if getattr(slab, "miller_index", None):
            name += "_{}".format(slab.miller_index)
        fws.append(
            get_slab_fw(slab,
                        bulk_structure,
                        slab_gen_params,
                        db_file=db_file,
                        vasp_cmd=vasp_cmd,
                        parents=parents,
                        name=name + " slab optimization"))
        for molecule in molecules:
            ads_slabs = AdsorbateSiteFinder(
                slab).generate_adsorption_structures(molecule,
                                                     **ads_structures_params)
            for n, ads_slab in enumerate(ads_slabs):
                ads_name = "{}-{} adsorbate optimization {}".format(
                    molecule.composition.formula, name, n)
                fws.append(
                    get_slab_fw(ads_slab,
                                bulk_structure,
                                slab_gen_params,
                                db_file=db_file,
                                vasp_cmd=vasp_cmd,
                                parents=parents,
                                name=ads_name))
    if add_molecules_in_box:
        for molecule in molecules:
            # molecule in box
            m_struct = Structure(Lattice.cubic(10),
                                 molecule.species_and_occu,
                                 molecule.cart_coords,
                                 coords_are_cartesian=True)
            m_struct.translate_sites(
                list(range(len(m_struct))),
                np.array([0.5] * 3) - np.average(m_struct.frac_coords, axis=0))
            vis = MVLSlabSet(m_struct)
            fws.append(
                OptimizeFW(structure=molecule,
                           job_type="normal",
                           vasp_input_set=vis,
                           db_file=db_file,
                           vasp_cmd=vasp_cmd))
    # TODO: add analysis framework
    return Workflow(fws,
                    name="{} surfaces wf, e.g., {}".format(
                        len(fws), fws[0].name))
Ejemplo n.º 46
0
import itertools
import json
import os
import collections
from collections import Counter
import numpy as np
from pymatgen import Structure
from statistics import mode
import shutil

# Step 1: #
## Open a folder and determine the 'cheapest' method of calculating simularities

p = Structure.from_file(filename='/Users/budmacaulay/Desktop/newruns/0' + '/POSCAR')
# Pretty sure it's more light weight to use dicts and such but im a terrible coder and honestly im painfully lazy

c = collections.Counter(p.species)
leastcom = []
for site in p:
    if site.specie.name == c.most_common()[-1][0].name:
        leastcom.append(site)

checkele = c.most_common()[-2][0].name

# # # - - - Checking first 100 desired sites are in correct position - - - # # #
thecount = 0
for folder in range(1, 100):
    # 1 Open poscar
    comped = Structure.from_file(filename='/Users/budmacaulay/Desktop/newtestssss/' + str(folder) + '/POSCAR')
    # 2 Check if it compares
    i = 0
Ejemplo n.º 47
0
import math

from pymatgen import Structure, Element
import os
import numpy as np
s = Structure.from_file('CONTCAR')
sr = []
ti = []
z = []
for i in s.sites:
    if i.specie == Element.O:
        z.append(i.z)
    elif i.specie == Element.Ti or i.specie == Element.Ti:
        ti.append(i.z)
    elif i.specie is Element.Ba or i.specie == Element.Ba:
        sr.append(i.z)

arr_Sr = [(x, x - y) for x,y in zip(sorted(sr), sorted(z)[2::3])]
arr_Ti = [(x, x - y) for x,y in zip(sorted(ti), sorted(z)[1::3])]
print(arr_Sr)
print(arr_Ti)
np.savetxt('sr.dat', arr_Sr, delimiter='\t')
np.savetxt('ti.dat', arr_Ti, delimiter='\t')
Ejemplo n.º 48
0
def add_magnetism(mat):
    mag_types = {"NM": "Non-magnetic", "FiM": "Ferri", "AFM": "AFM", "FM": "FM"}

    struc = Structure.from_dict(mat["structure"])
    msa = CollinearMagneticStructureAnalyzer(struc)
    mat["magnetic_type"] = mag_types[msa.ordering.value]
Ejemplo n.º 49
0
 def test_get_magmom_string_for_FeCl2(self):
     os.chdir(ROOT)
     structure = Structure.from_file('POSCAR_FeCl2')
     test_string = get_magmom_string(structure)
     self.assertEqual(test_string, u'1.0*6.0 2.0*0.5')
Ejemplo n.º 50
0
    def run_task(self, fw_spec):
        ref_struct = self['structure']
        d = {"analysis": {}, "initial_structure": self['structure'].as_dict()}

        # Get optimized structure
        calc_locs_opt = [
            cl for cl in fw_spec.get('calc_locs', [])
            if 'optimiz' in cl['name']
        ]
        if calc_locs_opt:
            optimize_loc = calc_locs_opt[-1]['path']
            logger.info("Parsing initial optimization directory: {}".format(
                optimize_loc))
            drone = VaspDrone()
            optimize_doc = drone.assimilate(optimize_loc)
            opt_struct = Structure.from_dict(
                optimize_doc["calcs_reversed"][0]["output"]["structure"])
            d.update({"optimized_structure": opt_struct.as_dict()})
            ref_struct = opt_struct
            eq_stress = -0.1 * Stress(optimize_doc["calcs_reversed"][0]
                                      ["output"]["ionic_steps"][-1]["stress"])
        else:
            eq_stress = None

        if self.get("fw_spec_field"):
            d.update({
                self.get("fw_spec_field"):
                fw_spec.get(self.get("fw_spec_field"))
            })

        # Get the stresses, strains, deformations from deformation tasks
        defo_dicts = fw_spec["deformation_tasks"].values()
        stresses, strains, deformations = [], [], []
        for defo_dict in defo_dicts:
            stresses.append(Stress(defo_dict["stress"]))
            strains.append(Strain(defo_dict["strain"]))
            deformations.append(Deformation(defo_dict["deformation_matrix"]))
            # Add derived stresses and strains if symmops is present
            for symmop in defo_dict.get("symmops", []):
                stresses.append(Stress(defo_dict["stress"]).transform(symmop))
                strains.append(Strain(defo_dict["strain"]).transform(symmop))
                deformations.append(
                    Deformation(
                        defo_dict["deformation_matrix"]).transform(symmop))

        stresses = [-0.1 * s for s in stresses]
        pk_stresses = [
            stress.piola_kirchoff_2(deformation)
            for stress, deformation in zip(stresses, deformations)
        ]

        d['fitting_data'] = {
            'cauchy_stresses': stresses,
            'eq_stress': eq_stress,
            'strains': strains,
            'pk_stresses': pk_stresses,
            'deformations': deformations
        }

        logger.info("Analyzing stress/strain data")
        # TODO: @montoyjh: what if it's a cubic system? don't need 6. -computron
        # TODO: Can add population method but want to think about how it should
        #           be done. -montoyjh
        order = self.get('order', 2)
        if order > 2:
            method = 'finite_difference'
        else:
            method = self.get('fitting_method', 'finite_difference')

        if method == 'finite_difference':
            result = ElasticTensorExpansion.from_diff_fit(strains,
                                                          pk_stresses,
                                                          eq_stress=eq_stress,
                                                          order=order)
            if order == 2:
                result = ElasticTensor(result[0])
        elif method == 'pseudoinverse':
            result = ElasticTensor.from_pseudoinverse(strains, pk_stresses)
        elif method == 'independent':
            result = ElasticTensor.from_independent_strains(
                strains, pk_stresses, eq_stress=eq_stress)
        else:
            raise ValueError(
                "Unsupported method, method must be finite_difference, "
                "pseudoinverse, or independent")

        ieee = result.convert_to_ieee(ref_struct)
        d.update({
            "elastic_tensor": {
                "raw": result.voigt,
                "ieee_format": ieee.voigt
            }
        })
        if order == 2:
            d.update({
                "derived_properties":
                ieee.get_structure_property_dict(ref_struct)
            })
        else:
            soec = ElasticTensor(ieee[0])
            d.update({
                "derived_properties":
                soec.get_structure_property_dict(ref_struct)
            })

        d["formula_pretty"] = ref_struct.composition.reduced_formula
        d["fitting_method"] = method
        d["order"] = order

        d = jsanitize(d)

        # Save analysis results in json or db
        db_file = env_chk(self.get('db_file'), fw_spec)
        if not db_file:
            with open("elasticity.json", "w") as f:
                f.write(json.dumps(d, default=DATETIME_HANDLER))
        else:
            db = VaspCalcDb.from_db_file(db_file, admin=True)
            db.collection = db.db["elasticity"]
            db.collection.insert_one(d)
            logger.info("Elastic analysis complete.")

        return FWAction()
Ejemplo n.º 51
0
    def run_task(self, fw_spec):

        wfid = list(filter(lambda x: 'wfid' in x, fw_spec['tags'])).pop()
        db_file = env_chk(self.get("db_file"), fw_spec)
        vaspdb = VaspCalcDb.from_db_file(db_file, admin=True)

        # ferroelectric workflow groups calculations by generated wfid tag
        polarization_tasks = vaspdb.collection.find({
            "tags": wfid,
            "task_label": {
                "$regex": ".*polarization"
            }
        })

        tasks = []
        outcars = []
        structure_dicts = []
        sort_weight = []
        energies_per_atom = []
        energies = []
        zval_dicts = []

        for p in polarization_tasks:
            # Grab data from each polarization task
            energies_per_atom.append(
                p['calcs_reversed'][0]['output']['energy_per_atom'])
            energies.append(p['calcs_reversed'][0]['output']['energy'])
            tasks.append(p['task_label'])
            outcars.append(p['calcs_reversed'][0]['output']['outcar'])
            structure_dicts.append(
                p['calcs_reversed'][0]['input']['structure'])
            zval_dicts.append(
                p['calcs_reversed'][0]['output']['outcar']['zval_dict'])

            # Add weight for sorting
            # Want polarization calculations in order of nonpolar to polar for Polarization object

            # This number needs to be bigger than the number of calculations
            max_sort_weight = 1000000

            if 'nonpolar_polarization' in p['task_label']:
                sort_weight.append(0)
            elif "polar_polarization" in p['task_label']:
                sort_weight.append(max_sort_weight)
            elif "interpolation_" in p['task_label']:
                num = 0
                part = re.findall(r'interpolation_[0-9]+_polarization',
                                  p['task_label'])
                if part != []:
                    part2 = re.findall(r'[0-9]+', part.pop())
                    if part2 != []:
                        num = part2.pop()
                sort_weight.append(max_sort_weight - int(num))

        # Sort polarization tasks
        # nonpolar -> interpolation_n -> interpolation_n-1 -> ...  -> interpolation_1 -> polar
        data = zip(tasks, structure_dicts, outcars, energies_per_atom,
                   energies, sort_weight)
        data = sorted(data, key=lambda x: x[-1])

        # Get the tasks, structures, etc in sorted order from the zipped data.
        tasks, structure_dicts, outcars, energies_per_atom, energies, sort_weight = zip(
            *data)

        structures = [
            Structure.from_dict(structure) for structure in structure_dicts
        ]

        # If LCALCPOL = True then Outcar will parse and store the pseudopotential zvals.
        zval_dict = zval_dicts.pop()

        # Assumes that we want to calculate the ionic contribution to the dipole moment.
        # VASP's ionic contribution is sometimes strange.
        # See pymatgen.analysis.ferroelectricity.polarization.Polarization for details.
        p_elecs = [outcar['p_elec'] for outcar in outcars]
        p_ions = [
            get_total_ionic_dipole(structure, zval_dict)
            for structure in structures
        ]

        polarization = Polarization(p_elecs, p_ions, structures)

        p_change = polarization.get_polarization_change().A1.tolist()
        p_norm = polarization.get_polarization_change_norm()
        polarization_max_spline_jumps = polarization.max_spline_jumps()
        same_branch = polarization.get_same_branch_polarization_data(
            convert_to_muC_per_cm2=True)
        raw_elecs, raw_ions = polarization.get_pelecs_and_pions()
        quanta = polarization.get_lattice_quanta(convert_to_muC_per_cm2=True)

        energy_trend = EnergyTrend(energies_per_atom)
        energy_max_spline_jumps = energy_trend.max_spline_jump()

        polarization_dict = {}

        def split_abc(var, var_name):
            d = {}
            for i, j in enumerate('abc'):
                d.update({var_name + "_{}".format(j): var[:, i].A1.tolist()})
            return d

        # Add some sort of id for the structures? Like cid but more general?
        # polarization_dict.update({'cid': cid})

        # General information
        polarization_dict.update(
            {'pretty_formula': structures[0].composition.reduced_formula})
        polarization_dict.update({'wfid': wfid})
        polarization_dict.update({'task_label_order': tasks})

        # Polarization information
        polarization_dict.update({'polarization_change': p_change})
        polarization_dict.update({'polarization_change_norm': p_norm})
        polarization_dict.update(
            {'polarization_max_spline_jumps': polarization_max_spline_jumps})
        polarization_dict.update(
            split_abc(same_branch, "same_branch_polarization"))
        polarization_dict.update(
            split_abc(raw_elecs, "raw_electron_polarization"))
        polarization_dict.update(
            split_abc(raw_ions, "raw_electron_polarization"))
        polarization_dict.update(split_abc(quanta, "polarization_quanta"))
        polarization_dict.update({"zval_dict": zval_dict})

        # Energy information
        polarization_dict.update(
            {'energy_per_atom_max_spline_jumps': energy_max_spline_jumps})
        polarization_dict.update({"energies": energies})
        polarization_dict.update({"energies_per_atom": energies_per_atom})
        polarization_dict.update({'outcars': outcars})
        polarization_dict.update({"structures": structure_dicts})

        # Write all the info to db.
        coll = vaspdb.db["polarization_tasks"]
        coll.insert_one(polarization_dict)
Ejemplo n.º 52
0
 def test_get_structure_type_for_0D_material(self):
     os.chdir(ROOT)
     structure = Structure.from_file('POSCAR_O2')
     test_type = get_structure_type(structure)
     self.assertEqual(test_type, 'molecular')
Ejemplo n.º 53
0
    def run_task(self, fw_spec):

        from pymatgen.analysis.eos import EOS

        eos = self.get("eos", "vinet")
        tag = self["tag"]
        db_file = env_chk(self.get("db_file"), fw_spec)
        summary_dict = {"eos": eos}
        to_db = self.get("to_db", True)

        # collect and store task_id of all related tasks to make unique links with "tasks" collection
        all_task_ids = []

        mmdb = VaspCalcDb.from_db_file(db_file, admin=True)
        # get the optimized structure
        d = mmdb.collection.find_one(
            {"task_label": "{} structure optimization".format(tag)})
        all_task_ids.append(d["task_id"])
        structure = Structure.from_dict(
            d["calcs_reversed"][-1]["output"]['structure'])
        summary_dict["structure"] = structure.as_dict()
        summary_dict["formula_pretty"] = structure.composition.reduced_formula

        # get the data(energy, volume, force constant) from the deformation runs
        docs = mmdb.collection.find({
            "task_label": {
                "$regex": "{} bulk_modulus*".format(tag)
            },
            "formula_pretty":
            structure.composition.reduced_formula
        })
        energies = []
        volumes = []
        for d in docs:
            s = Structure.from_dict(
                d["calcs_reversed"][-1]["output"]['structure'])
            energies.append(d["calcs_reversed"][-1]["output"]['energy'])
            volumes.append(s.volume)
            all_task_ids.append(d["task_id"])
        summary_dict["energies"] = energies
        summary_dict["volumes"] = volumes
        summary_dict["all_task_ids"] = all_task_ids

        # fit the equation of state
        eos = EOS(eos)
        eos_fit = eos.fit(volumes, energies)
        summary_dict["bulk_modulus"] = eos_fit.b0_GPa

        # TODO: find a better way for passing tags of the entire workflow to db - albalu
        if fw_spec.get("tags", None):
            summary_dict["tags"] = fw_spec["tags"]
        summary_dict["results"] = dict(eos_fit.results)
        summary_dict["created_at"] = datetime.utcnow()

        # db_file itself is required but the user can choose to pass the results to db or not
        if to_db:
            mmdb.collection = mmdb.db["eos"]
            mmdb.collection.insert_one(summary_dict)
        else:
            with open("bulk_modulus.json", "w") as f:
                f.write(json.dumps(summary_dict, default=DATETIME_HANDLER))

        # TODO: @matk86 - there needs to be a builder to put it into materials collection... -computron
        logger.info("Bulk modulus calculation complete.")
Ejemplo n.º 54
0
 def test_get_structure_type_for_layered_material(self):
     os.chdir(ROOT)
     structure = Structure.from_file('POSCAR_FeCl2')
     test_type = get_structure_type(structure)
     self.assertEqual(test_type, 'layered')
Ejemplo n.º 55
0
from pymatgen import Structure
from pymatgen.core.surface import SlabGenerator

structure = Structure.from_file('POSCAR_conv')

structure.add_oxidation_state_by_element({"Ca": 2, "Bi": -3, "O": -2})
#structure.add_oxidation_state_by_guess()

# These are distances in Angstroms
dist = [10, 15, 20, 25, 30]
# We iterate through the distances twice, once for vac, once for slab
for vac in dist:
    for thickness in dist:
        slabgen = SlabGenerator(structure,
                                miller_index=(0, 0, 1),
                                min_slab_size=thickness,
                                min_vacuum_size=vac,
                                lll_reduce=True)
        slabs = slabgen.get_slabs()

        dipole_free_slabs = []
        for slab in slabs:
            if not slab.is_polar():
                dipole_free_slabs.append(slab)

        slab = dipole_free_slabs[0]  # <-- put a number in here!
        slab.to(fmt='poscar',
                filename='slab_{}_{}.vasp'.format(thickness, vac))
Ejemplo n.º 56
0
def get_elastic_analysis(opt_task, defo_tasks):
    """
    Performs the analysis of opt_tasks and defo_tasks necessary for
    an elastic analysis

    Args:
        opt_task: task doc corresponding to optimization
        defo_tasks: task_doc corresponding to deformations

    Returns:
        elastic document with fitted elastic tensor and analysis

    """
    elastic_doc = {"warnings": []}
    opt_struct = Structure.from_dict(opt_task['output']['structure'])
    d_structs = [
        Structure.from_dict(d['output']['structure']) for d in defo_tasks
    ]
    defos = [
        calculate_deformation(opt_struct, def_structure)
        for def_structure in d_structs
    ]

    # Warning if deformation is not equivalent to stored deformation
    stored_defos = [d['transmuter']['transformation_params'][0]\
                     ['deformation'] for d in defo_tasks]
    if not np.allclose(defos, stored_defos, atol=1e-5):
        wmsg = "Inequivalent stored and calc. deformations."
        logger.warning(wmsg)
        elastic_doc["warnings"].append(wmsg)

    # Collect all fitting data and task ids
    defos = [Deformation(d) for d in defos]
    strains = [d.green_lagrange_strain for d in defos]
    vasp_stresses = [d['output']['stress'] for d in defo_tasks]
    cauchy_stresses = [-0.1 * Stress(s) for s in vasp_stresses]
    pk_stresses = [
        Stress(s.piola_kirchoff_2(d)) for s, d in zip(cauchy_stresses, defos)
    ]
    defo_task_ids = [d['task_id'] for d in defo_tasks]

    # Determine whether data is sufficient to fit tensor
    # If raw data is insufficient but can be symmetrically transformed
    # to provide a sufficient set, use the expanded set with appropriate
    # symmetry transformations, fstresses/strains are "fitting
    # strains" below.
    vstrains = [s.voigt for s in strains]
    if np.linalg.matrix_rank(vstrains) < 6:
        symmops = SpacegroupAnalyzer(opt_struct).get_symmetry_operations()
        fstrains = [[s.transform(symmop) for symmop in symmops]
                    for s in strains]
        fstrains = list(chain.from_iterable(fstrains))
        vfstrains = [s.voigt for s in fstrains]
        if not np.linalg.matrix_rank(vfstrains) == 6:
            logger.warning("Insufficient data to form SOEC")
            elastic_doc['warnings'].append("insufficient strains")
            return None
        else:
            fstresses = [[s.transform(symmop) for symmop in symmops]
                         for s in pk_stresses]
            fstresses = list(chain.from_iterable(fstresses))
    else:
        fstrains = strains
        fstresses = pk_stresses

    with warnings.catch_warnings():
        warnings.simplefilter('ignore')
        if len(cauchy_stresses) == 24:
            elastic_doc['legacy_fit'] = legacy_fit(strains, cauchy_stresses)
        et_raw = ElasticTensor.from_pseudoinverse(fstrains, fstresses)
        et = et_raw.voigt_symmetrized.convert_to_ieee(opt_struct)
        defo_tasks = sorted(defo_tasks, key=lambda x: x['completed_at'])
        vasp_input = opt_task['input']
        vasp_input.pop('structure')

        elastic_doc.update({
            "deformation_task_ids": defo_task_ids,
            "optimization_task_id": opt_task['task_id'],
            "pk_stresses": pk_stresses,
            "cauchy_stresses": cauchy_stresses,
            "strains": strains,
            "deformations": defos,
            "elastic_tensor": et.voigt,
            "elastic_tensor_raw": et_raw.voigt,
            "optimized_structure": opt_struct,
            "completed_at": defo_tasks[-1]['completed_at'],
            "optimization_input": vasp_input
        })

    # Process input
    elastic_doc['warnings'] = get_warnings(et, opt_struct) or None
    #TODO: process MPWorks metadata?
    #TODO: higher order
    #TODO: add some of the relevant DFT params, kpoints
    elastic_doc['state'] = "filter_failed" if elastic_doc['warnings']\
        else "successful"
    return elastic_doc
Ejemplo n.º 57
0
    def run_task(self, fw_spec):
        # handle arguments and database setup
        db_file = env_chk(self.get("db_file"), fw_spec)
        tag = self["tag"]

        vasp_db = VaspCalcDb.from_db_file(db_file, admin=True)

        # get the energies, volumes and DOS objects by searching for the tag
        static_calculations = vasp_db.collection.find(
            {'$and': [{
                'metadata.tag': tag
            }, {
                'adopted': True
            }]})

        energies = []
        volumes = []
        dos_objs = []  # pymatgen.electronic_structure.dos.Dos objects
        structure = None  # single Structure for QHA calculation
        for calc in static_calculations:
            energies.append(calc['output']['energy'])
            volumes.append(calc['output']['structure']['lattice']['volume'])
            dos_objs.append(vasp_db.get_dos(calc['task_id']))
            # get a Structure. We only need one for the masses and number of atoms in the unit cell.
            if structure is None:
                structure = Structure.from_dict(calc['output']['structure'])

        # sort everything in volume order
        # note that we are doing volume last because it is the thing we are sorting by!

        energies = sort_x_by_y(energies, volumes)
        dos_objs = sort_x_by_y(dos_objs, volumes)
        volumes = sorted(volumes)

        qha_result = {}
        qha_result['structure'] = structure.as_dict()
        qha_result['formula_pretty'] = structure.composition.reduced_formula
        qha_result['elements'] = sorted(
            [el.name for el in structure.composition.elements])
        qha_result['metadata'] = self.get('metadata', {})
        qha_result['has_phonon'] = self['phonon']

        poisson = self.get('poisson', 0.363615)
        bp2gru = self.get('bp2gru', 1)

        # phonon properties
        if self['phonon']:
            # get the vibrational properties from the FW spec
            phonon_calculations = list(vasp_db.db['phonon'].find(
                {'$and': [{
                    'metadata.tag': tag
                }, {
                    'adopted': True
                }]}))
            vol_vol = [
                calc['volume'] for calc in phonon_calculations
            ]  # these are just used for sorting and will be thrown away
            vol_f_vib = [calc['F_vib'] for calc in phonon_calculations]
            # sort them order of the unit cell volumes
            vol_f_vib = sort_x_by_y(vol_f_vib, vol_vol)
            f_vib = np.vstack(vol_f_vib)
            qha = Quasiharmonic(energies,
                                volumes,
                                structure,
                                dos_objects=dos_objs,
                                F_vib=f_vib,
                                t_min=self['t_min'],
                                t_max=self['t_max'],
                                t_step=self['t_step'],
                                poisson=poisson,
                                bp2gru=bp2gru)
            qha_result['phonon'] = qha.get_summary_dict()
            qha_result['phonon']['temperatures'] = qha_result['phonon'][
                'temperatures'].tolist()

        # calculate the Debye model results no matter what
        qha_debye = Quasiharmonic(energies,
                                  volumes,
                                  structure,
                                  dos_objects=dos_objs,
                                  F_vib=None,
                                  t_min=self['t_min'],
                                  t_max=self['t_max'],
                                  t_step=self['t_step'],
                                  poisson=poisson,
                                  bp2gru=bp2gru)

        # fit 0 K EOS for good measure
        eos = Vinet(volumes, energies)
        eos.fit()
        errors = eos.func(volumes) - energies
        sum_square_error = float(np.sum(np.square(errors)))
        eos_res = {}
        eos_res['b0_GPa'] = float(eos.b0_GPa)
        eos_res['b0'] = float(eos.b0)
        eos_res['b1'] = float(eos.b1)
        eos_res['eq_volume'] = float(eos.v0)
        eos_res['eq_energy'] = float(eos.e0)
        eos_res['energies'] = energies
        eos_res['volumes'] = volumes
        eos_res['name'] = 'Vinet'
        eos_res['error'] = {}
        eos_res['error']['difference'] = errors.tolist(
        )  # volume by volume differences
        eos_res['error']['sum_square_error'] = sum_square_error
        qha_result['eos'] = eos_res

        qha_result['debye'] = qha_debye.get_summary_dict()
        qha_result['debye']['poisson'] = poisson
        qha_result['debye']['bp2gru'] = bp2gru
        qha_result['debye']['temperatures'] = qha_result['debye'][
            'temperatures'].tolist()

        qha_result['version_atomate'] = atomate_ver
        qha_result['version_dfttk'] = dfttk_ver
        volumes_false = []
        energies_false = []
        static_falses = vasp_db.collection.find(
            {'$and': [{
                'metadata.tag': tag
            }, {
                'adopted': False
            }]})
        for static_false in static_falses:
            volumes_false.append(
                static_false['output']['structure']['lattice']['volume'])
            energies_false.append(static_false['output']['energy'])
        qha_result['Volumes_fitting_false'] = volumes_false
        qha_result['Energies_fitting_false'] = energies_false
        print('Volumes_fitting_false : %s' % volumes_false)
        print('Energies_fitting_false: %s' % energies_false)

        # write to JSON for debugging purposes
        import json
        with open('qha_summary.json', 'w') as fp:
            json.dump(qha_result, fp)

        if self['phonon']:
            vasp_db.db['qha_phonon'].insert_one(qha_result)
        else:
            vasp_db.db['qha'].insert_one(qha_result)
Ejemplo n.º 58
0
    def run_task(self, fw_spec):
        additional_fields = self.get("additional_fields", {})

        # pass the additional_fields first to avoid overriding BoltztrapAnalyzer items
        d = additional_fields.copy()

        btrap_dir = os.path.join(os.getcwd(), "boltztrap")
        d["boltztrap_dir"] = btrap_dir

        bta = BoltztrapAnalyzer.from_files(btrap_dir)
        d.update(bta.as_dict())
        d["scissor"] = bta.intrans["scissor"]

        # trim the output
        for x in [
                'cond', 'seebeck', 'kappa', 'hall', 'mu_steps', 'mu_doping',
                'carrier_conc'
        ]:
            del d[x]

        if not self.get("hall_doping"):
            del d["hall_doping"]

        bandstructure_dir = os.getcwd()
        d["bandstructure_dir"] = bandstructure_dir

        # add the structure
        v, o = get_vasprun_outcar(bandstructure_dir,
                                  parse_eigen=False,
                                  parse_dos=False)
        structure = v.final_structure
        d["structure"] = structure.as_dict()
        d["formula_pretty"] = structure.composition.reduced_formula
        d.update(get_meta_from_structure(structure))

        # add the spacegroup
        sg = SpacegroupAnalyzer(Structure.from_dict(d["structure"]), 0.1)
        d["spacegroup"] = {
            "symbol": sg.get_space_group_symbol(),
            "number": sg.get_space_group_number(),
            "point_group": sg.get_point_group_symbol(),
            "source": "spglib",
            "crystal_system": sg.get_crystal_system(),
            "hall": sg.get_hall()
        }

        d["created_at"] = datetime.utcnow()

        db_file = env_chk(self.get('db_file'), fw_spec)

        if not db_file:
            del d["dos"]
            with open(os.path.join(btrap_dir, "boltztrap.json"), "w") as f:
                f.write(json.dumps(d, default=DATETIME_HANDLER))
        else:
            mmdb = VaspCalcDb.from_db_file(db_file, admin=True)

            # dos gets inserted into GridFS
            dos = json.dumps(d["dos"], cls=MontyEncoder)
            fsid, compression = mmdb.insert_gridfs(
                dos, collection="dos_boltztrap_fs", compress=True)
            d["dos_boltztrap_fs_id"] = fsid
            del d["dos"]

            mmdb.db.boltztrap.insert(d)
Ejemplo n.º 59
0
    for struct, fname in zip(structs, fnames):
        filename = NAME + '_' + fname.lower() + '.' + fmt

        if "POSCAR" in fname and flag:
            # it is a bug in pymatgen
            print("The string POSCAR in filename will be replaced by poscar")
            flag = False

        if fmt == 'lammps':
            system = structure2system(struct)
            system.to_lammps_lmp(filename)
            continue

        try:
            print("Write {0:20s} {1:s}".format(fname, 'Pymatgen:Struture'))
            struct.to(fmt, filename)
        except:
            print("Write {0:20s} {1:s} ".format(fname, 'Atoms:Atoms'))
            atoms = pmg2ase(struct)
            write(filename)
    return True


if __name__ == "__main__":
    from pymatgen import Structure
    structure = Structure.from_file('POSCAR')
    system = structure2system(structure)
    print(system)
    print('--')
    covert_operation([structure], ["POSCAR"], 'lammps')
Ejemplo n.º 60
0
    modify_incar_params = { 'Full relax': {'incar_update': {"LAECHG":False,"LCHARG":False,"LWAVE":False}},
                            'PreStatic': {'incar_update': {"LAECHG":False,"LCHARG":False,"LWAVE":False}},
                            'PS2': {'incar_update': {"LAECHG":False,"LCHARG":False,"LWAVE":False}},
                            'static': {'incar_update': {"LAECHG":False,"LCHARG":False,"LWAVE":False}},
    """
    modify_incar_params = {}
    #dict, dict of class ModifyKpoints with keywords in Workflow name, similar with modify_incar_params
    modify_kpoints_params = {}
    #bool, print(True) or not(False) some informations, used for debug
    verbose = False

    ###################### DO NOT CHANGE THE FOLLOWING LINES ##############################
    from pymatgen import MPRester, Structure
    from dfttk.wflows import get_wf_gibbs

    structure = Structure.from_file(TEMPLATE_STRUCTURE_FILENAME)

    if magmom:
        structure.add_site_property('magmom', magmom)

    if not db_file:
        from fireworks.fw_config import config_to_dict
        from monty.serialization import loadfn
        db_file = loadfn(config_to_dict()["FWORKER_LOC"])["env"]["db_file"]

    wf = get_wf_gibbs(structure,
                      num_deformations=num_deformations,
                      deformation_fraction=deformation_fraction,
                      phonon=phonon,
                      phonon_supercell_matrix=phonon_supercell_matrix,
                      t_min=t_min,