Esempio n. 1
0
def get_relax_static_wf(structures,
                        vasp_cmd=">>vasp_cmd<<",
                        db_file=">>db_file<<",
                        name="regular_relax",
                        **kwargs):
    """
    :param structures:
    :param vasp_cmd:
    :param db_file:
    :param name:
    :param kwargs:
    :return:
    """
    wfs = []
    for s in structures:
        fw1 = OptimizeFW(s,
                         vasp_cmd=vasp_cmd,
                         db_file=db_file,
                         parents=[],
                         **kwargs)
        fw2 = StaticFW(s, vasp_cmd=vasp_cmd, db_file=db_file, parents=[fw1])
        wfs.append(
            Workflow([fw1, fw2],
                     name=name + str(s.composition.reduced_formula)))
    return wfs
Esempio n. 2
0
def get_wf_structure_sampler(xdatcar_file,
                             n=10,
                             steps_skip_first=1000,
                             vasp_cmd=">>vasp_cmd<<",
                             db_file=">>db_file<<",
                             name="structure_sampler",
                             **kwargs):
    """
    :param xdatcar_file:
    :param n:
    :param steps_skip_first:
    :param vasp_cmd:
    :param db_file:
    :param name:
    :param kwargs:
    :return:
    """
    structures = get_sample_structures(xdatcar_path=xdatcar_file,
                                       n=n,
                                       steps_skip_first=steps_skip_first)
    wfs = []
    for s in structures:
        fw1 = OptimizeFW(s,
                         vasp_cmd=vasp_cmd,
                         db_file=db_file,
                         parents=[],
                         **kwargs)
        fw2 = StaticFW(s, vasp_cmd=vasp_cmd, db_file=db_file, parents=[fw1])
        wfs.append(
            Workflow([fw1, fw2],
                     name=name + str(s.composition.reduced_formula)))
    return wfs
Esempio n. 3
0
    def run_task(self, fw_spec):

        #create structure from CONTCAR
        struct = Poscar.from_file('CONTCAR').structure

        #repeat layers of bulk to create supercell
        struct.make_supercell([1, 1, self.get("num_layers", 2)])

        #add vacuum to create slab
        struct = add_vacuum(struct, self.get("vacuum", 15))

        #add selective dynamics
        selective_dynamics = []
        """
        min_bulk = self.get("surf_layers_to_relax",3)/(self.get("atomic_thickness")*self.get("num_layers",2)) * max([site.z for site in struct.sites])
        
        max_bulk = (self.get("atomic_thickness")*self.get("num_layers",2) - self.get("surf_layers_to_relax",3))/(self.get("atomic_thickness")*self.get("num_layers",2)) * max([site.z for site in struct.sites])
                     
        for site in struct.sites:
            if site.z > min_bulk and site.z <= max_bulk:
                selective_dynamics.append([False, False, False])
            else:
                selective_dynamics.append([True, True, True])
        struct.add_site_property("selective_dynamics", selective_dynamics)
        """
        #create optimize and static fireworks using the newly created slab
        slab_optimize = OptimizeFW(struct,
                                   name=name + '_slab_optimization' + time,
                                   vasp_cmd=">>vasp_cmd<<",
                                   db_file=">>db_file<<",
                                   parents=[bulk_optimize])

        slab_optimize = Workflow(slab_optimize)
        optimize_incar_settings = {"ISIF": 2}
        optimize_update = {"incar_update": optimize_incar_settings}
        slab_optimize = add_modify_incar(slab_optimize,
                                         modify_incar_params=optimize_update,
                                         fw_name_constraint='optimization')

        slab_static = StaticFW(struct,
                               name=name + '_slab_static_' + time,
                               parents=[slab_optimize],
                               prev_calc_loc=True,
                               vasp_cmd=">>vasp_cmd<<",
                               db_file=">>db_file<<")
        #slab_static.tasks.append(Slab_energy_and_SA())

        #surface_energy_calc_fw = Firework(Surface_energy_calc(), parents = [bulk_static, slab_static])

        #return FWAction(additions = [slab_optimize, slab_static, surface_energy_calc_fw])
        return FWAction(additions=[slab_optimize, slab_static])
Esempio n. 4
0
    def testLobsterFW(self):
        static_fw = StaticFW(structure=self.structure).name
        self.assertEqual(
            LobsterFW(structure=self.structure, parents=static_fw).name,
            "Si-lobster_calculation",
        )
        lobster_fw = LobsterFW(prev_calc_dir="/",
                               delete_wavecar=True,
                               delete_wavecar_previous_fw=True)
        self.assertEqual(lobster_fw.name, "unknown-lobster_calculation")
        self.assertEqual(lobster_fw.tasks[0]["calc_dir"], "/")
        self.assertEqual(len(lobster_fw.tasks), 7)

        lobster_fw = LobsterFW(prev_calc_dir="/",
                               delete_wavecar=False,
                               delete_wavecar_previous_fw=False)
        self.assertEqual(len(lobster_fw.tasks), 5)

        # check for ValueError when no parent or calc_dir are provided
        with self.assertRaises(ValueError):
            LobsterFW()
Esempio n. 5
0
    def run_task(self, fw_spec):
        inserted_structure = fw_spec.get("optimal_structure")
        working_ion = fw_spec.get("working_ion")
        vasptodb_kwargs = fw_spec.get("vasptodb_kwargs")
        staticfw_kwargs = fw_spec.get("staticfw_kwargs", {})

        fw1 = StaticFW(
            inserted_structure,
            vasptodb_kwargs=vasptodb_kwargs,
            db_file=DB_FILE,
            **staticfw_kwargs,
        )
        n_ion = int(
            inserted_structure.composition.element_composition[working_ion])
        fw2 = Firework(
            [AnalyzeChgcar(), GetInsertionCalcs()],
            name=f"Charge Density Analysis-{n_ion}",
            parents=fw1,
        )
        wf = Workflow([fw1, fw2], name=f"Obtain inserted sites-{n_ion}")
        wf = get_powerup_wf(wf, fw_spec)
        update_wf_keys(wf, fw_spec)
        return FWAction(additions=[wf])
Esempio n. 6
0
    def get_wf(self,
               scan=False,
               perform_bader=True,
               num_orderings_hard_limit=16,
               c=None):
        """
        Retrieve the FireWorks workflow.

        Args:
            scan (bool): if True, use the SCAN functional instead of GGA+U,
                since the SCAN functional has shown to have improved
                performance for magnetic systems in some cases
            perform_bader (bool): if True, make sure the "bader" binary is in
                your path, will use Bader analysis to calculate
                atom-projected magnetic moments
            num_orderings_hard_limit (int): will make sure total number of
                magnetic orderings does not exceed this number even if there
                are extra orderings of equivalent symmetry
            c (dict): additional config dict (as used elsewhere in atomate)

        Returns: FireWorks Workflow

        """

        c_defaults = {"VASP_CMD": VASP_CMD, "DB_FILE": DB_FILE}
        additional_fields = {"relax": not self.static}
        c = c or {}
        for k, v in c_defaults.items():
            if k not in c:
                c[k] = v

        fws = []
        analysis_parents = []

        # trim total number of orderings (useful in high-throughput context)
        # this is somewhat course, better to reduce num_orderings kwarg and/or
        # change enumeration strategies
        ordered_structures = self.ordered_structures
        ordered_structure_origins = self.ordered_structure_origins

        def _add_metadata(structure):
            """
            For book-keeping, store useful metadata with the Structure
            object for later database ingestion including workflow
            version and a UUID for easier querying of all tasks generated
            from the workflow.

            Args:
                structure: Structure

            Returns: TransformedStructure

            """

            # this could be further improved by storing full transformation
            # history, but would require an improved transformation pipeline
            return TransformedStructure(
                structure, other_parameters={"wf_meta": self.wf_meta})

        ordered_structures = [
            _add_metadata(struct) for struct in ordered_structures
        ]

        if (num_orderings_hard_limit
                and len(self.ordered_structures) > num_orderings_hard_limit):
            ordered_structures = self.ordered_structures[
                0:num_orderings_hard_limit]
            ordered_structure_origins = self.ordered_structure_origins[
                0:num_orderings_hard_limit]
            logger.warning("Number of ordered structures exceeds hard limit, "
                           "removing last {} structures.".format(
                               len(self.ordered_structures) -
                               len(ordered_structures)))
            # always make sure input structure is included
            if self.input_index and self.input_index > num_orderings_hard_limit:
                ordered_structures.append(
                    self.ordered_structures[self.input_index])
                ordered_structure_origins.append(
                    self.ordered_structure_origins[self.input_index])

        # default incar settings
        user_incar_settings = {"ISYM": 0, "LASPH": True, "EDIFFG": -0.05}
        if scan:
            # currently, using SCAN relaxation as a static calculation also
            # since it is typically high quality enough, but want to make
            # sure we are also writing the AECCAR* files
            user_incar_settings.update({"LAECHG": True})
        user_incar_settings.update(c.get("user_incar_settings", {}))
        c["user_incar_settings"] = user_incar_settings

        for idx, ordered_structure in enumerate(ordered_structures):

            analyzer = CollinearMagneticStructureAnalyzer(ordered_structure)

            name = f" ordering {idx} {analyzer.ordering.value} -"

            if not scan:

                vis = MPRelaxSet(ordered_structure,
                                 user_incar_settings=user_incar_settings)

                if not self.static:

                    # relax
                    fws.append(
                        OptimizeFW(
                            ordered_structure,
                            vasp_input_set=vis,
                            vasp_cmd=c["VASP_CMD"],
                            db_file=c["DB_FILE"],
                            max_force_threshold=0.05,
                            half_kpts_first_relax=False,
                            name=name + " optimize",
                        ))

                # static
                fws.append(
                    StaticFW(
                        ordered_structure,
                        vasp_cmd=c["VASP_CMD"],
                        db_file=c["DB_FILE"],
                        name=name + " static",
                        prev_calc_loc=True,
                        parents=fws[-1],
                        vasptodb_kwargs={
                            "parse_chgcar": True,
                            "parse_aeccar": True
                        },
                    ))

                if not self.static:
                    # so a failed optimize doesn't crash workflow
                    fws[-1].spec["_allow_fizzled_parents"] = True

            elif scan:

                # wf_scan_opt is just a single FireWork so can append it directly
                scan_fws = wf_scan_opt(ordered_structure, c=c).fws
                # change name for consistency with non-SCAN
                new_name = scan_fws[0].name.replace("structure optimization",
                                                    name + " optimize")
                scan_fws[0].name = new_name
                scan_fws[0].tasks[-1]["additional_fields"][
                    "task_label"] = new_name
                fws += scan_fws

            analysis_parents.append(fws[-1])

        fw_analysis = Firework(
            MagneticOrderingsToDb(
                db_file=c["DB_FILE"],
                wf_uuid=self.uuid,
                parent_structure=self.sanitized_structure,
                origins=ordered_structure_origins,
                input_index=self.input_index,
                perform_bader=perform_bader,
                scan=scan,
                additional_fields=additional_fields,
            ),
            name="Magnetic Orderings Analysis",
            parents=analysis_parents,
            spec={"_allow_fizzled_parents": True},
        )
        fws.append(fw_analysis)

        formula = self.sanitized_structure.composition.reduced_formula
        wf_name = f"{formula} - magnetic orderings"
        if scan:
            wf_name += " - SCAN"
        wf = Workflow(fws, name=wf_name)

        wf = add_additional_fields_to_taskdocs(wf, {"wf_meta": self.wf_meta})

        tag = f"magnetic_orderings group: >>{self.uuid}<<"
        wf = add_tags(wf, [tag, ordered_structure_origins])

        return wf
Esempio n. 7
0
    def get_wf(self, c=None):
        """
        Get the workflow.

        Returns:
            Workflow

        """

        c = c or {"VASP_CMD": VASP_CMD, "DB_FILE": DB_FILE}
        vasp_cmd = c.get("VASP_CMD", VASP_CMD)
        db_file = c.get("DB_FILE", DB_FILE)

        nsites = len(self.structure.sites)

        vis = MPRelaxSet(self.structure, potcar_functional="PBE_54", force_gamma=True)

        opt_fw = OptimizeFW(
            self.structure,
            vasp_input_set=vis,
            vasp_cmd=c["VASP_CMD"],
            db_file=c["DB_FILE"],
        )

        vis = MPStaticSet(self.structure, potcar_functional="PBE_54", force_gamma=True)

        static_fw = StaticFW(
            self.structure,
            vasp_input_set=vis,
            vasp_cmd=c["VASP_CMD"],
            db_file=c["DB_FILE"],
            parents=[opt_fw],
        )

        # Separate FW for each BZ surface calc
        # Run Z2Pack on unique TRIM planes in the BZ

        surfaces = ["kx_0", "kx_1"]
        equiv_planes = self.get_equiv_planes()

        # Only run calcs on inequivalent BZ surfaces
        if self.symmetry_reduction:
            for add_surface in equiv_planes.keys():
                mark = True
                for surface in surfaces:
                    if surface in equiv_planes[add_surface]:
                        mark = False
                if mark and add_surface not in surfaces:
                    surfaces.append(add_surface)
        else:  # 4 TRI surfaces define Z2 in 3D
            surfaces = ["kx_1", "ky_1", "kz_0", "kz_1"]

        z2pack_fws = []

        for surface in surfaces:
            z2pack_fw = Z2PackFW(
                parents=[static_fw],
                structure=self.structure,
                surface=surface,
                uuid=self.uuid,
                name="z2pack",
                vasp_cmd=c["VASP_CMD"],
                db_file=c["DB_FILE"],
            )
            z2pack_fws.append(z2pack_fw)

        analysis_fw = InvariantFW(
            parents=z2pack_fws,
            structure=self.structure,
            symmetry_reduction=self.symmetry_reduction,
            equiv_planes=equiv_planes,
            uuid=self.uuid,
            name="invariant",
            db_file=c["DB_FILE"],
        )

        fws = [opt_fw, static_fw] + z2pack_fws + [analysis_fw]

        wf = Workflow(fws)
        wf = add_additional_fields_to_taskdocs(wf, {"wf_meta": self.wf_meta})

        # Add vdW corrections if structure is layered
        dim_data = StructureDimensionality(self.structure)

        if np.any(
            [
                dim == 2
                for dim in [dim_data.larsen_dim, dim_data.cheon_dim, dim_data.gorai_dim]
            ]
        ):
            wf = add_modify_incar(
                wf,
                modify_incar_params={
                    "incar_update": {
                        "IVDW": 11,
                        "EDIFFG": 0.005,
                        "IBRION": 2,
                        "NSW": 100,
                    }
                },
                fw_name_constraint="structure optimization",
            )

            wf = add_modify_incar(
                wf,
                modify_incar_params={"incar_update": {"IVDW": 11}},
                fw_name_constraint="static",
            )

            wf = add_modify_incar(
                wf,
                modify_incar_params={"incar_update": {"IVDW": 11}},
                fw_name_constraint="z2pack",
            )

        else:
            wf = add_modify_incar(
                wf,
                modify_incar_params={
                    "incar_update": {"EDIFFG": 0.005, "IBRION": 2, "NSW": 100}
                },
                fw_name_constraint="structure optimization",
            )

        # Helpful vasp settings and no parallelization
        wf = add_modify_incar(
            wf,
            modify_incar_params={
                "incar_update": {
                    "ADDGRID": ".TRUE.",
                    "LASPH": ".TRUE.",
                    "GGA": "PS",
                    "NCORE": 1,
                }
            },
        )

        # Generate inputs for Z2Pack with a static calc
        wf = add_modify_incar(
            wf,
            modify_incar_params={"incar_update": {"PREC": "Accurate"}},
            fw_name_constraint="static",
        )

        wf = add_common_powerups(wf, c)

        wf.name = "{} {}".format(self.structure.composition.reduced_formula, "Z2Pack")

        if c.get("STABILITY_CHECK", STABILITY_CHECK):
            wf = add_stability_check(wf, fw_name_constraint="structure optimization")

        if c.get("ADD_WF_METADATA", ADD_WF_METADATA):
            wf = add_wf_metadata(wf, self.structure)

        tag = "z2pack: {}".format(self.uuid)
        wf = add_tags(wf, [tag])

        return wf
Esempio n. 8
0
    tilt_count = 15
    temp_structs = copy.deepcopy(tilts_and_orders)
    comp_tag = composition[0] + composition[1] + 'N' + 'O' + str(
        composition[2])
    struct_tag = 'tetra'
    for structure in temp_structs:
        if composition[2] == 1:
            structure.replace_species({'O': 'N', 'N': 'O'})
        structure.replace_species({
            default_B: composition[1]
        })  #this will break if B-site is default_a but that shouldn't happen
        structure.replace_species({default_A: composition[0]})
        poscar_key = tetra_dict[tilt_count]

        opt = OptimizeFW(structure, vasp_cmd='ibrun tacc_affinity vasp_std')
        stat = StaticFW(parents=opt, vasp_cmd='ibrun tacc_affinity vasp_std')
        wf = Workflow([opt, stat])
        wf = add_modify_incar(wf,
                              modify_incar_params={
                                  'incar_update': {
                                      'KPAR': 2,
                                      'NCORE': 4,
                                      'NSIM': 8,
                                      'EDIFF': 0.000002,
                                      'LMAXMIX': 6,
                                      'LSCALAPACK': '.FALSE.',
                                      'ALGO': 'All'
                                  }
                              })
        wf = add_modify_incar(wf,
                              modify_incar_params={