def test_wf_functions(self):
        # Test slab trans params generator
        for slab in self.slabs:
            trans_params = get_slab_trans_params(slab)
            trans = SlabTransformation(**trans_params)
            new_slab = trans.apply_transformation(slab.oriented_unit_cell)
            self.assertTrue(np.allclose(new_slab.cart_coords, slab.cart_coords))
            self.assertTrue(np.allclose(new_slab.lattice.matrix,
                                        slab.lattice.matrix))

        # Try something a bit more complicated
        formulas = ['Si', 'Sn', 'SrTiO3', 'Li2O']
        structs = [PymatgenTest.get_structure(s) for s in formulas]
        for struct in structs:
            slabs = generate_all_slabs(struct, max_index=2, min_slab_size=10,
                                       min_vacuum_size=20)
            for slab in slabs:
                trans_params = get_slab_trans_params(slab)
                trans = SlabTransformation(**trans_params)
                new_slab = trans.apply_transformation(slab.oriented_unit_cell)
                old_coords = np.around(slab.frac_coords, 10) % 1
                new_coords = np.around(new_slab.frac_coords, 10) % 1
                self.assertTrue(np.allclose(old_coords, new_coords))
                self.assertTrue(np.allclose(new_slab.lattice.matrix,
                                            slab.lattice.matrix))
Пример #2
0
    def test_apply_transformation(self):
        trans = SubstituteSurfaceSiteTransformation("Au")
        pt = Structure(Lattice.cubic(5), ["Pt"], [[0, 0, 0]])  # fictitious
        slab = SlabTransformation([0, 0, 1], 20, 10).apply_transformation(pt)
        out = trans.apply_transformation(slab)

        self.assertEqual(out.composition.reduced_formula, "Pt3Au")
Пример #3
0
    def test_apply_transformation(self):
        co = Molecule(["C", "O"], [[0, 0, 0], [0, 0, 1.23]])
        trans = AddAdsorbateTransformation(co)
        pt = Structure(Lattice.cubic(5), ["Pt"], [[0, 0, 0]])  # fictitious
        slab = SlabTransformation([0, 0, 1], 20, 10).apply_transformation(pt)
        out = trans.apply_transformation(slab)

        self.assertEqual(out.composition.reduced_formula, "Pt4CO")
    def test_apply_transformation(self):
        s = self.get_structure("LiFePO4")
        trans = SlabTransformation([0, 0, 1], 10, 10, shift = 0.25)
        gen = SlabGenerator(s, [0, 0, 1], 10, 10)
        slab_from_gen = gen.get_slab(0.25)
        slab_from_trans = trans.apply_transformation(s)
        self.assertArrayAlmostEqual(slab_from_gen.lattice.matrix, 
                                    slab_from_trans.lattice.matrix)
        self.assertArrayAlmostEqual(slab_from_gen.cart_coords, 
                                    slab_from_trans.cart_coords)

        fcc = Structure.from_spacegroup("Fm-3m", Lattice.cubic(3), ["Fe"],
                                        [[0, 0, 0]])
        trans = SlabTransformation([1, 1, 1], 10, 10)
        slab_from_trans = trans.apply_transformation(fcc)
        gen = SlabGenerator(fcc, [1, 1, 1], 10, 10)
        slab_from_gen = gen.get_slab()
        self.assertArrayAlmostEqual(slab_from_gen.lattice.matrix,
                                    slab_from_trans.lattice.matrix)
        self.assertArrayAlmostEqual(slab_from_gen.cart_coords, 
                                    slab_from_trans.cart_coords)
Пример #5
0
    def test_wf_functions(self):
        # Test slab trans params generator
        for slab in self.slabs:
            trans_params = get_slab_trans_params(slab)
            trans = SlabTransformation(**trans_params)
            new_slab = trans.apply_transformation(slab.oriented_unit_cell)
            self.assertTrue(np.allclose(new_slab.cart_coords,
                                        slab.cart_coords))
            self.assertTrue(
                np.allclose(new_slab.lattice.matrix, slab.lattice.matrix))

        # Try something a bit more complicated
        formulas = ['Si', 'Sn', 'SrTiO3', 'Li2O']
        structs = [PymatgenTest.get_structure(s) for s in formulas]
        for struct in structs:
            slabs = generate_all_slabs(struct,
                                       max_index=2,
                                       min_slab_size=10,
                                       min_vacuum_size=20)
            for slab in slabs:
                trans_params = get_slab_trans_params(slab)
                trans = SlabTransformation(**trans_params)
                new_slab = trans.apply_transformation(slab.oriented_unit_cell)
                old_coords = np.around(slab.frac_coords, 10) % 1
                new_coords = np.around(new_slab.frac_coords, 10) % 1
                self.assertTrue(np.allclose(old_coords, new_coords))
                self.assertTrue(
                    np.allclose(new_slab.lattice.matrix, slab.lattice.matrix))
    def test_apply_transformation(self):
        s = self.get_structure("LiFePO4")
        trans = SlabTransformation([0, 0, 1], 10, 10, shift=0.25)
        gen = SlabGenerator(s, [0, 0, 1], 10, 10)
        slab_from_gen = gen.get_slab(0.25)
        slab_from_trans = trans.apply_transformation(s)
        self.assertArrayAlmostEqual(slab_from_gen.lattice.matrix, slab_from_trans.lattice.matrix)
        self.assertArrayAlmostEqual(slab_from_gen.cart_coords, slab_from_trans.cart_coords)

        fcc = Structure.from_spacegroup("Fm-3m", Lattice.cubic(3), ["Fe"], [[0, 0, 0]])
        trans = SlabTransformation([1, 1, 1], 10, 10)
        slab_from_trans = trans.apply_transformation(fcc)
        gen = SlabGenerator(fcc, [1, 1, 1], 10, 10)
        slab_from_gen = gen.get_slab()
        self.assertArrayAlmostEqual(slab_from_gen.lattice.matrix, slab_from_trans.lattice.matrix)
        self.assertArrayAlmostEqual(slab_from_gen.cart_coords, slab_from_trans.cart_coords)
Пример #7
0
def get_slab_fw(slab,
                transmuter=False,
                db_file=None,
                vasp_input_set=None,
                parents=None,
                vasp_cmd="vasp",
                name="",
                add_slab_metadata=True,
                user_incar_settings=None):
    """
    Function to generate a a slab firework.  Returns a TransmuterFW if
    bulk_structure is specified, constructing the necessary transformations
    from the slab and slab generator parameters, or an OptimizeFW if only a
    slab is specified.

    Args:
        slab (Slab or Structure): structure or slab corresponding
            to the slab to be calculated
        transmuter (bool): whether or not to use a TransmuterFW based
            on slab params, if this option is selected, input slab must
            be a Slab object (as opposed to Structure)
        vasp_input_set (VaspInputSet): vasp_input_set corresponding to
            the slab calculation
        parents (Fireworks or list of ints): parent FWs
        db_file (string): path to database file
        vasp_cmd (string): vasp command
        name (string): name of firework
        add_slab_metadata (bool): whether to add slab metadata to task doc

    Returns:
        Firework corresponding to slab calculation
    """
    vasp_input_set = vasp_input_set or MPSurfaceSet(
        slab, user_incar_settings=user_incar_settings)

    # If a bulk_structure is specified, generate the set of transformations,
    # else just create an optimize FW with the slab
    if transmuter:
        if not isinstance(slab, Slab):
            raise ValueError(
                "transmuter mode requires slab to be a Slab object")

        # Get transformation from oriented bulk and slab
        oriented_bulk = slab.oriented_unit_cell
        slab_trans_params = get_slab_trans_params(slab)
        trans_struct = SlabTransformation(**slab_trans_params)
        slab_from_bulk = trans_struct.apply_transformation(oriented_bulk)

        # Ensures supercell construction
        supercell_trans = SupercellTransformation.from_scaling_factors(
            round(slab.lattice.a / slab_from_bulk.lattice.a),
            round(slab.lattice.b / slab_from_bulk.lattice.b))

        # Get site properties, set velocities to zero if not set to avoid
        # custodian issue
        site_props = slab.site_properties
        if 'velocities' not in site_props:
            site_props['velocities'] = [0. for s in slab]

        # Get adsorbates for InsertSitesTransformation
        if "adsorbate" in slab.site_properties.get("surface_properties", ""):
            ads_sites = [
                site for site in slab
                if site.properties["surface_properties"] == "adsorbate"
            ]
        else:
            ads_sites = []
        transformations = [
            "SlabTransformation", "SupercellTransformation",
            "InsertSitesTransformation", "AddSitePropertyTransformation"
        ]
        trans_params = [
            slab_trans_params, {
                "scaling_matrix": supercell_trans.scaling_matrix
            }, {
                "species": [site.species_string for site in ads_sites],
                "coords": [site.frac_coords for site in ads_sites]
            }, {
                "site_properties": site_props
            }
        ]
        fw = TransmuterFW(name=name,
                          structure=oriented_bulk,
                          transformations=transformations,
                          transformation_params=trans_params,
                          copy_vasp_outputs=True,
                          db_file=db_file,
                          vasp_cmd=vasp_cmd,
                          parents=parents,
                          vasp_input_set=vasp_input_set)
    else:
        fw = OptimizeFW(name=name,
                        structure=slab,
                        vasp_input_set=vasp_input_set,
                        vasp_cmd=vasp_cmd,
                        db_file=db_file,
                        parents=parents,
                        job_type="normal")
    # Add slab metadata
    if add_slab_metadata:
        parent_structure_metadata = get_meta_from_structure(
            slab.oriented_unit_cell)
        fw.tasks[-1]["additional_fields"].update({
            "slab":
            slab,
            "parent_structure":
            slab.oriented_unit_cell,
            "parent_structure_metadata":
            parent_structure_metadata
        })
    return fw
Пример #8
0
def get_slab_fw(slab,
                bulk_structure=None,
                slab_gen_params={},
                db_file=None,
                vasp_input_set=None,
                parents=None,
                vasp_cmd="vasp",
                name=""):
    """
    Function to generate a a slab firework.  Returns a TransmuterFW if bulk_structure is specified,
    constructing the necessary transformations from the slab and slab generator parameters,
    or an OptimizeFW if only a slab is specified.

    Args:
        slab (Slab or Structure): structure or slab corresponding
            to the slab to be calculated
        bulk_structure (Structure): bulk structure corresponding to slab, if
            provided, slab firework is constructed as a TransmuterFW using
            the necessary transformations to get the slab from the bulk
        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
        vasp_input_set (VaspInputSet): vasp_input_set corresponding to
            the slab calculation
        parents (Fireworks or list of ints): parent FWs
        db_file (string): path to database file
        vasp_cmd (string): vasp command

    Returns:
        Firework
    """
    vasp_input_set = vasp_input_set or MVLSlabSet(slab)

    # If a bulk_structure is specified, generate the set of transformations, else
    # just create an optimize FW with the slab
    if bulk_structure:
        if not isinstance(slab, Slab):
            raise ValueError(
                "structure input to get_slab_fw requires slab to be a slab object!"
            )
        slab_trans_params = {
            "miller_index": slab.miller_index,
            "shift": slab.shift
        }
        slab_trans_params.update(slab_gen_params)

        # Get supercell parameters
        trans_struct = SlabTransformation(**slab_trans_params)
        slab_from_bulk = trans_struct.apply_transformation(bulk_structure)
        supercell_trans = SupercellTransformation.from_scaling_factors(
            round(slab.lattice.a / slab_from_bulk.lattice.a),
            round(slab.lattice.b / slab_from_bulk.lattice.b))

        # Get adsorbates for InsertSitesTransformation
        if "adsorbate" in slab.site_properties.get("surface_properties",
                                                   [None]):
            ads_sites = [
                site for site in slab
                if site.properties["surface_properties"] == "adsorbate"
            ]
        else:
            ads_sites = []
        transformations = [
            "SlabTransformation", "SupercellTransformation",
            "InsertSitesTransformation", "AddSitePropertyTransformation"
        ]
        trans_params = [
            slab_trans_params, {
                "scaling_matrix": supercell_trans.scaling_matrix
            }, {
                "species": [site.species_string for site in ads_sites],
                "coords": [site.frac_coords for site in ads_sites]
            }, {
                "site_properties": slab.site_properties
            }
        ]
        return TransmuterFW(name=name,
                            structure=bulk_structure,
                            transformations=transformations,
                            transformation_params=trans_params,
                            copy_vasp_outputs=True,
                            db_file=db_file,
                            vasp_cmd=vasp_cmd,
                            parents=parents,
                            vasp_input_set=vasp_input_set)
    else:
        return OptimizeFW(name=name,
                          structure=slab,
                          vasp_input_set=vasp_input_set,
                          vasp_cmd=vasp_cmd,
                          db_file=db_file,
                          parents=parents,
                          job_type="normal")
Пример #9
0
def get_slab_fw(slab, transmuter=False, db_file=None, vasp_input_set=None,
                parents=None, vasp_cmd="vasp", name="", add_slab_metadata=True):
    """
    Function to generate a a slab firework.  Returns a TransmuterFW if
    bulk_structure is specified, constructing the necessary transformations
    from the slab and slab generator parameters, or an OptimizeFW if only a
    slab is specified.

    Args:
        slab (Slab or Structure): structure or slab corresponding
            to the slab to be calculated
        transmuter (bool): whether or not to use a TransmuterFW based
            on slab params, if this option is selected, input slab must
            be a Slab object (as opposed to Structure)
        vasp_input_set (VaspInputSet): vasp_input_set corresponding to
            the slab calculation
        parents (Fireworks or list of ints): parent FWs
        db_file (string): path to database file
        vasp_cmd (string): vasp command
        name (string): name of firework
        add_slab_metadata (bool): whether to add slab metadata to task doc

    Returns:
        Firework corresponding to slab calculation
    """
    vasp_input_set = vasp_input_set or MPSurfaceSet(slab)

    # If a bulk_structure is specified, generate the set of transformations,
    # else just create an optimize FW with the slab
    if transmuter:
        if not isinstance(slab, Slab):
            raise ValueError("transmuter mode requires slab to be a Slab object")

        # Get transformation from oriented bulk and slab
        oriented_bulk = slab.oriented_unit_cell
        slab_trans_params = get_slab_trans_params(slab)
        trans_struct = SlabTransformation(**slab_trans_params)
        slab_from_bulk = trans_struct.apply_transformation(oriented_bulk)

        # Ensures supercell construction
        supercell_trans = SupercellTransformation.from_scaling_factors(
            round(slab.lattice.a / slab_from_bulk.lattice.a),
            round(slab.lattice.b / slab_from_bulk.lattice.b))

        # Get site properties, set velocities to zero if not set to avoid
        # custodian issue
        site_props = slab.site_properties
        if 'velocities' not in site_props:
            site_props['velocities'] = [0. for s in slab]

        # Get adsorbates for InsertSitesTransformation
        if "adsorbate" in slab.site_properties.get("surface_properties", ""):
            ads_sites = [site for site in slab
                         if site.properties["surface_properties"] == "adsorbate"]
        else:
            ads_sites = []
        transformations = [
            "SlabTransformation", "SupercellTransformation",
            "InsertSitesTransformation", "AddSitePropertyTransformation"]
        trans_params = [slab_trans_params,
                        {"scaling_matrix": supercell_trans.scaling_matrix},
                        {"species": [site.species_string for site in ads_sites],
                         "coords": [site.frac_coords for site in ads_sites]},
                        {"site_properties": site_props}]
        fw = TransmuterFW(name=name, structure=oriented_bulk,
                          transformations=transformations,
                          transformation_params=trans_params,
                          copy_vasp_outputs=True, db_file=db_file,
                          vasp_cmd=vasp_cmd, parents=parents,
                          vasp_input_set=vasp_input_set)
    else:
        fw = OptimizeFW(name=name, structure=slab,
                        vasp_input_set=vasp_input_set, vasp_cmd=vasp_cmd,
                        db_file=db_file, parents=parents, job_type="normal")
    # Add slab metadata
    if add_slab_metadata:
        parent_structure_metadata = get_meta_from_structure(
            slab.oriented_unit_cell)
        fw.tasks[-1]["additional_fields"].update(
            {"slab": slab, "parent_structure": slab.oriented_unit_cell,
             "parent_structure_metadata": parent_structure_metadata})
    return fw