Пример #1
0
def wf_bandstructure2D(structure, c=None):

    c = c or {}
    vasp_cmd = c.get("VASP_CMD", VASP_CMD)
    db_file = c.get("DB_FILE", DB_FILE)
    vdw_kernel = c.get("VDW_KERNEL_DIR", VDW_KERNEL_DIR)
    incar = _read_user_incar('Relax2D.txt')
    print(incar)
    mpr2d = MPRelaxSet(structure, force_gamma=True, user_incar_settings=incar)
    mpr2dstatic = MPRelaxSet(structure,
                             force_gamma=True,
                             user_incar_settings={
                                 "NEDOS": "3001",
                                 "EMIN": "-15.0",
                                 "EMAX": "15.0"
                             })
    #fws = [OptimizeFW2D(structure=structure, vasp_input_set=mpr2d, vasp_cmd=vasp_cmd, db_file=db_file, vdw_kernel_dir=vdw_kernel)]
    fws = [
        OptimizeFW2D(structure=structure,
                     vasp_input_set=mpr2d,
                     vasp_cmd=vasp_cmd,
                     vdw_kernel_dir=vdw_kernel)
    ]
    fws.append(StaticFW2D(parents=fws[0], vasp_input_set=mpr2dstatic))
    #fws.append(NonSCFFW2D(parents=fws[1], mode='uniform'))
    fws.append(NonSCFFW2D(parents=fws[1], mode='line'))
    wf = Workflow(fws)
    '''check bandstructure.yaml'''
    '''
    wf = get_wf(structure, "bandstructure.yaml", vis=MPScanRelaxSet2D(structure, force_gamma=True,), \
                params=[{'vasp_input_set': mpr2d},{},{},{}], common_params={"vasp_cmd": vasp_cmd, "db_file": db_file,}) #"vdw_kernel_dir": vdw_kernel})
    '''
    wf = add_common_powerups(wf, c)

    if c.get("SMALLGAP_KPOINT_MULTIPLY", SMALLGAP_KPOINT_MULTIPLY):
        wf = add_small_gap_multiply(wf, 0.5, 5, "static")
        wf = add_small_gap_multiply(wf, 0.5, 5, "nscf")

    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, structure)

    wf.name = "{}:{}".format(structure.composition.reduced_formula,
                             "bandStructure")
    '''
    fws = wf.fws
    fws[0] = new_firework
    print(fws)
    '''
    return wf
Пример #2
0
    def get_wf(self, num_orderings_hard_limit=16, c=None):
        """Retrieve Fireworks workflow.

        c is an optional dictionary that can contain:
        * heisenberg_settings:
            cutoff (float): Starting point for nearest neighbor search.
            tol (float): Tolerance for equivalent NN bonds.
        * mc_settings:
            mc_box_size (float): MC simulation box size in nm.
            equil_timesteps (int): Number of MC equilibration moves.
            mc_timesteps (int): Number of MC moves for averaging.
            avg (bool): Compute only <J>.
        * DB_FILE:
            path to db.json.

        Args:
            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 Optional[dict]: additional config dict described above

        Returns:
            wf (Workflow): Heisenberg Model + Vampire Monte Carlo.

        TODO:
            * Add static SCAN option (only optimization is available)

        """

        c = c or {"DB_FILE": DB_FILE}

        if "DB_FILE" not in c:
            c["DB_FILE"] = DB_FILE

        heisenberg_settings = c.get("heisenberg_settings", {})

        fws = []

        heisenberg_model_fw = HeisenbergModelFW(
            wf_uuid=self.uuid,
            parent_structure=self.structures[0],
            db_file=c["DB_FILE"],
            heisenberg_settings=heisenberg_settings,
            parents=None,
            structures=self.structures,
            energies=self.energies,
        )

        # Vampire Monte Carlo
        mc_settings = c.get("mc_settings", {})

        vampire_fw = VampireCallerFW(
            wf_uuid=self.uuid,
            parent_structure=self.structures[0],
            parents=[heisenberg_model_fw],
            db_file=c["DB_FILE"],
            mc_settings=mc_settings,
        )

        fws = [heisenberg_model_fw, vampire_fw]

        wf = Workflow(fws)

        # Add metadata
        wf = add_additional_fields_to_taskdocs(wf, {"wf_meta": self.wf_meta})
        formula = self.structures[0].composition.reduced_formula
        wf.name = f"{formula} - Exchange"

        return wf
Пример #3
0
def wf_electron_conductivity(structure,
                             vasp_input_set_relax=None,
                             vasp_input_set_fixvol_relax=None,
                             vasp_input_set_static=None,
                             vasp_input_set_band=None,
                             vasp_input_set_diel=None,
                             vasp_input_set_elastic=None,
                             vasp_kpoint_set=None,
                             vasp_cmd=">>vasp_cmd<<",
                             db_file=">>db_file<<",
                             mode="standard",
                             Temp=None,
                             Doping=None,
                             strain=None,
                             ifSB=None):
    '''This workflow aims to calculate electronic transport properties.'''

    tag = datetime.utcnow().strftime('%Y-%m-%d-%H-%M-%S-%f')
    fws = []
    # get the input set for the optimization and update it if we passed custom settings
    vis_relax = MPRelaxSet(structure,
                           user_incar_settings=vasp_input_set_relax,
                           user_kpoints_settings=vasp_kpoint_set)

    # Structure optimization firework
    fw_opt_equi = MyOptimizeFW(structure=structure,
                               vasp_input_set=vis_relax,
                               vasp_cmd=vasp_cmd,
                               db_file=db_file,
                               name="equi structure optimization",
                               count=1,
                               spec={"_queueadapter": {
                                   "job_name": 'opt'
                               }})
    fws.append(fw_opt_equi)  #1
    # static calculations firework
    fw_static_equi = MyStaticFW(
        structure=structure,
        vasp_input_set_params=vasp_input_set_static,
        prev_calc_loc="equi structure optimization-final",
        vasp_cmd=vasp_cmd,
        db_file=db_file,
        name="equi static",
        parents=fws[0],
        spec={"_queueadapter": {
            "job_name": 'static'
        }})
    fws.append(fw_static_equi)  #2

    # Structure optimization firework for 0.1% larger and 0.2% larger structures
    fw_opt_05 = MyOptimizeFW(structure=structure,
                             vasp_input_set_params=vasp_input_set_fixvol_relax,
                             strain=strain[0],
                             prev_calc_loc="equi structure optimization-final",
                             vasp_cmd=vasp_cmd,
                             db_file=db_file,
                             name="0.5per structure optimization",
                             count=1,
                             parents=fws[0],
                             spec={"_queueadapter": {
                                 "job_name": 'opt'
                             }})
    fw_opt_10 = MyOptimizeFW(structure=structure,
                             vasp_input_set_params=vasp_input_set_fixvol_relax,
                             strain=strain[1],
                             prev_calc_loc="equi structure optimization-final",
                             vasp_cmd=vasp_cmd,
                             db_file=db_file,
                             name="1.0per structure optimization",
                             count=1,
                             parents=fws[0],
                             spec={"_queueadapter": {
                                 "job_name": 'opt'
                             }})
    fws.append(fw_opt_05)  #3
    fws.append(fw_opt_10)  #4

    fw_static_05 = MyStaticFW(
        structure=structure,
        vasp_input_set_params=vasp_input_set_static,
        prev_calc_loc="0.5per structure optimization-final",
        vasp_cmd=vasp_cmd,
        db_file=db_file,
        name="0.5per static",
        parents=fws[2],
        spec={"_queueadapter": {
            "job_name": 'static'
        }})
    fw_static_10 = MyStaticFW(
        structure=structure,
        vasp_input_set_params=vasp_input_set_static,
        prev_calc_loc="1.0per structure optimization-final",
        vasp_cmd=vasp_cmd,
        db_file=db_file,
        name="1.0per static",
        parents=fws[3],
        spec={"_queueadapter": {
            "job_name": 'static'
        }})
    fws.append(fw_static_05)  #5
    fws.append(fw_static_10)  #6
    # band structure calculation firework
    fw_band_equi = MyNonSCFFW(structure=structure,
                              vasp_input_set_params=vasp_input_set_band,
                              prev_calc_loc="equi static",
                              name="equi nscf",
                              vasp_cmd=vasp_cmd,
                              db_file=db_file,
                              parents=fws[1],
                              spec={"_queueadapter": {
                                  "job_name": 'band'
                              }})
    fw_band_05 = MyNonSCFFW(structure=structure,
                            vasp_input_set_params=vasp_input_set_band,
                            prev_calc_loc="0.5per static",
                            name="0.5per nscf",
                            vasp_cmd=vasp_cmd,
                            db_file=db_file,
                            parents=fws[4],
                            spec={"_queueadapter": {
                                "job_name": 'band'
                            }})
    fw_band_10 = MyNonSCFFW(structure=structure,
                            vasp_input_set_params=vasp_input_set_band,
                            prev_calc_loc="1.0per static",
                            name="1.0per nscf",
                            vasp_cmd=vasp_cmd,
                            db_file=db_file,
                            parents=fws[5],
                            spec={"_queueadapter": {
                                "job_name": 'band'
                            }})
    fws.append(fw_band_equi)  #7
    fws.append(fw_band_05)  #8
    fws.append(fw_band_10)  #9
    # elastic constant calculation
    fw_elastic = MyElasticFW(structure=structure,
                             vasp_input_set_params=vasp_input_set_elastic,
                             prev_calc_loc="equi structure optimization-final",
                             name="elastic",
                             vasp_cmd=vasp_cmd,
                             db_file=db_file,
                             parents=fws[1],
                             spec={"_queueadapter": {
                                 "job_name": 'elastic'
                             }})
    fws.append(fw_elastic)  #10
    # dielect constant calculation
    fw_dielect = MyDFPTFW(structure=structure,
                          user_incar_settings=vasp_input_set_diel,
                          lepsilon=True,
                          prev_calc_loc="equi static",
                          name="dielectric",
                          vasp_cmd=vasp_cmd,
                          db_file=db_file,
                          parents=fws[1],
                          spec={"_queueadapter": {
                              "job_name": 'dielect'
                          }})
    fws.append(fw_dielect)  #11
    # effective mass
    fw_effectivemass_CBM = MyEffectivemassFW(
        structure=structure,
        vasp_input_set_params=vasp_input_set_band,
        prev_calc_loc="equi static",
        whichbnd="CBM",
        stepsize=0.01,
        name="CBM",
        vasp_cmd=vasp_cmd,
        db_file=db_file,
        parents=fws[6],
        spec={"_queueadapter": {
            "job_name": 'CBM'
        }})
    fw_effectivemass_VBM = MyEffectivemassFW(
        structure=structure,
        vasp_input_set_params=vasp_input_set_band,
        prev_calc_loc="equi static",
        whichbnd="VBM",
        stepsize=0.01,
        name="VBM",
        vasp_cmd=vasp_cmd,
        db_file=db_file,
        parents=fws[6],
        spec={"_queueadapter": {
            "job_name": 'VBM'
        }})
    fw_effectivemass_CSB = MyEffectivemassFW(
        structure=structure,
        vasp_input_set_params=vasp_input_set_band,
        prev_calc_loc="equi static",
        whichbnd="CSB",
        stepsize=0.01,
        name="CSB",
        vasp_cmd=vasp_cmd,
        db_file=db_file,
        parents=fws[6],
        spec={"_queueadapter": {
            "job_name": 'CSB'
        }})
    fw_effectivemass_VSB = MyEffectivemassFW(
        structure=structure,
        vasp_input_set_params=vasp_input_set_band,
        prev_calc_loc="equi static",
        whichbnd="VSB",
        stepsize=0.01,
        name="VSB",
        vasp_cmd=vasp_cmd,
        db_file=db_file,
        parents=fws[6],
        spec={"_queueadapter": {
            "job_name": 'VSB'
        }})
    fws.append(fw_effectivemass_CBM)  #12
    fws.append(fw_effectivemass_VBM)  #13
    fws.append(fw_effectivemass_CSB)  #14
    fws.append(fw_effectivemass_VSB)  #15

    # Call AICON
    fw_eleccond = CalElecCondFW(structure=structure,
                                name="electrical conductivity",
                                mode=mode,
                                Temp=Temp,
                                Doping=Doping,
                                ifSB=ifSB,
                                db_file=db_file,
                                parents=fws[6:15],
                                spec={"_queueadapter": {
                                    "job_name": 'AICON'
                                }})
    fws.append(fw_eleccond)  #16

    # finally, create the workflow
    wf_electron_conductivity = Workflow(fws)
    wf_electron_conductivity.name = "{}:{}".format(
        structure.composition.reduced_formula,
        "electronic transport properties")

    return add_namefile(wf_electron_conductivity)
Пример #4
0
def wf_phonon_conductivity(structure,
                           vasp_input_set_relax=None,
                           vasp_input_set_fixvol_relax=None,
                           vasp_input_set_dfpt=None,
                           vasp_kpoint_set=None,
                           vasp_cmd=">>vasp_cmd<<",
                           db_file=">>db_file<<",
                           Temp=None,
                           ifscale=None,
                           supercell=None):
    """ This workflow aims to calculate lattice thermal conductivity of the structure. """

    fws = []
    # get the input set for the optimization and update it if we passed custom settings
    vis_relax = MPRelaxSet(structure,
                           user_incar_settings=vasp_input_set_relax,
                           user_kpoints_settings=vasp_kpoint_set)

    # Structure optimization firework
    fw_opt_orig = MyOptimizeFW(structure=structure,
                               vasp_input_set=vis_relax,
                               vasp_cmd=vasp_cmd,
                               db_file=db_file,
                               name="equi structure optimization",
                               count=1,
                               spec={"_queueadapter": {
                                   "job_name": 'opt'
                               }})
    fws.append(fw_opt_orig)  #1

    # Structure optimization firework for 0.4% smaller and 0.4% larger structures
    fw_opt_minus = MyOptimizeFW(
        structure=structure,
        vasp_input_set_params=vasp_input_set_fixvol_relax,
        strain=-0.004,
        prev_calc_loc="equi structure optimization-final",
        vasp_cmd=vasp_cmd,
        db_file=db_file,
        name="minus structure optimization",
        count=1,
        parents=fws[0],
        spec={"_queueadapter": {
            "job_name": 'opt'
        }})
    fw_opt_plus = MyOptimizeFW(
        structure=structure,
        vasp_input_set_params=vasp_input_set_fixvol_relax,
        strain=0.004,
        prev_calc_loc="equi structure optimization-final",
        vasp_cmd=vasp_cmd,
        db_file=db_file,
        name="plus structure optimization",
        count=1,
        parents=fws[0],
        spec={"_queueadapter": {
            "job_name": 'opt'
        }})
    fws.append(fw_opt_minus)  #2
    fws.append(fw_opt_plus)  #3

    # 2nd Force Constant calculation using DFPT
    fw_dfpt_orig = MyPhononFW(
        structure=structure,
        user_incar_settings=vasp_input_set_dfpt,
        prev_calc_loc="equi structure optimization-final",
        supercell=supercell,
        name="orig phonon band",
        vasp_cmd=vasp_cmd,
        db_file=db_file,
        parents=fws[0],
        spec={"_queueadapter": {
            "job_name": 'dfpt',
            "ppnode": 8
        }})
    fw_dfpt_minus = MyPhononFW(
        structure=structure,
        user_incar_settings=vasp_input_set_dfpt,
        prev_calc_loc="minus structure optimization-final",
        supercell=supercell,
        name="minus phonon band",
        vasp_cmd=vasp_cmd,
        db_file=db_file,
        parents=fws[1],
        spec={"_queueadapter": {
            "job_name": 'dfpt',
            "ppnode": 8
        }})
    fw_dfpt_plus = MyPhononFW(
        structure=structure,
        user_incar_settings=vasp_input_set_dfpt,
        prev_calc_loc="plus structure optimization-final",
        supercell=supercell,
        name="plus phonon band",
        vasp_cmd=vasp_cmd,
        db_file=db_file,
        parents=fws[2],
        spec={"_queueadapter": {
            "job_name": 'dfpt',
            "ppnode": 8
        }})

    fws.append(fw_dfpt_orig)  #4
    fws.append(fw_dfpt_minus)  #5
    fws.append(fw_dfpt_plus)  #6
    # get band.yaml and gruneisen.yaml
    fw_phoncond = CalPhonCondFW(structure=structure,
                                Temp=Temp,
                                ifscale=ifscale,
                                supercell=supercell,
                                name="thermal conductivity",
                                db_file=db_file,
                                parents=fws[3:6],
                                spec={"_queueadapter": {
                                    "job_name": 'AICON'
                                }})
    fws.append(fw_phoncond)

    wf_phonon_conductivity = Workflow(fws)
    wf_phonon_conductivity.name = "{}:{}".format(
        structure.composition.reduced_formula, "phonon transport properties")

    return add_namefile(wf_phonon_conductivity)
Пример #5
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
Пример #6
0
def get_aneb_wf(
    structure,
    working_ion,
    insert_coords,
    insert_coords_combinations,
    n_images,
    vasp_input_set=None,
    override_default_vasp_params=None,
    handler_group=None,
    selective_dynamics_scheme="fix_two_atom",
    launch_mode="all",
    vasp_cmd=VASP_CMD,
    db_file=DB_FILE,
    wall_time=None,
    additional_fields=None,
    tags=None,
    powerup_dicts=None,
    name="ApproxNEB",
):
    """
    Workflow for running the "ApproxNEB" algorithm to estimate
    energetic barriers for a working ion in a structure (host)
    between end point positions specified by insert_coords and
    insert_coords_combinations. Note this workflow is only
    intended for the dilute lattice limit (where one working
    ion is in a large supercell structure of the host and
    little volume change upon insertion is expected).
    By default workflow sets appropriate VASP input parameters
    and Custodian handler groups.

    This workflow uses an "approx_neb" collection to organize
    outputs and generate inputs for new VASP calculations for
    easier data management and analysis. An "approx_neb"
    additional field is automatically added to all task docs
    generated to assist record keeping.

    To make modifications to docs generated by this
    workflow, use of the additional_fields and tags arguments
    is recommended to ensure all fireworks, tasks collection
    docs, and approx_neb collection docs are modified.

    Args:
    structure (Structure): structure of empty host
    working_ion: specie of site to insert in structure
        (e.g. "Li").
    insert_coords (1x3 array or list of 1x3 arrays):
        fractional coordinates of site(s) to insert in
        structure (e.g. [[0,0,0], [0,0.25,0], [0.5,0,0]]).
    insert_coords_combinations (list of strings): list of
        strings corresponding to the list index of
        insert_coords to specify which combination
        of end_points to use for path interpolation.
        (e.g. ["0+1", "0+2"])
    n_images: n_images (int): number of images
        interpolated between end point structures for
        each path set by insert_coords_combinations
    vasp_input_set (VaspInputSet class): can use to
        define VASP input parameters.
        See pymatgen.io.vasp.sets module for more
        information. MPRelaxSet() and
        override_default_vasp_params are used if
        vasp_input_set = None.
    override_default_vasp_params (dict): if provided,
        vasp_input_set is disregarded and the Vasp Input
        Set is created by passing override_default_vasp_params
        to MPRelaxSet(). Allows for easy modification of
        MPRelaxSet().
        For example, to set ISIF=2 in the INCAR use:
        {"user_incar_settings":{"ISIF":2}}
    handler_group (str or [ErrorHandler]): group of handlers to
        use for RunVaspCustodian firetask. See handler_groups
        dict in the code for the groups and complete list of
        handlers in each group. Alternatively, you can specify a
        list of ErrorHandler objects.
    selective_dynamics_scheme (str): "fix_two_atom"
    launch_mode (str): "all" or "screening"
    vasp_cmd (str): the name of the full executable for running
        VASP.
    db_file (str): path to file containing the database
        credentials.
    wall_time (int): Total walltime in seconds. If this is None and
        the job is running on a PBS system, the handler will attempt to
        determine the walltime from the PBS_WALLTIME environment
        variable. If the wall time cannot be determined or is not
        set, this handler will have no effect.
    additional_fields (dict): specifies more information
        to be stored in the approx_neb collection to
        assist user record keeping.
    tags (list): list of strings to be stored in the
        approx_neb collection under the "tags" field to
        assist user record keeping.
    powerup_dicts (list): additional powerups given to all the dynamically
        created image fireworks
    name (str): name for the workflow returned

    Returns: Workflow
    """
    approx_neb_params = override_default_vasp_params or {
        "user_incar_settings": {
            "EDIFF": 0.0005,
            "EDIFFG": -0.05,
            "IBRION": 1,
            "ISIF": 3,
            "ISMEAR": 0,
            "LDAU": False,
            "NSW": 400,
            "ADDGRID": True,
            "ISYM": 1,
            "NELMIN": 4,
        }
    }

    handler_group = handler_group or [
        VaspErrorHandler(),
        MeshSymmetryErrorHandler(),
        NonConvergingErrorHandler(),
        PotimErrorHandler(),
        PositiveEnergyErrorHandler(),
        FrozenJobErrorHandler(),
        StdErrHandler(),
        WalltimeHandler(wall_time=wall_time),
    ]

    wf_uuid = str(uuid4())
    additional_fields = deepcopy(additional_fields)

    host_fw = HostFW(
        structure=structure,
        approx_neb_wf_uuid=wf_uuid,
        db_file=db_file,
        vasp_input_set=vasp_input_set,
        vasp_cmd=vasp_cmd,
        override_default_vasp_params=deepcopy(approx_neb_params),
        additional_fields=additional_fields,
        tags=tags,
    )

    # modifies incar settings needed for end point and image structure relaxations
    if "user_incar_settings" not in approx_neb_params.keys():
        approx_neb_params = {"user_incar_settings": {}}
    approx_neb_params["user_incar_settings"]["ISIF"] = 2
    approx_neb_params["user_incar_settings"]["ISYM"] = 0
    approx_neb_params["user_incar_settings"]["LDAU"] = False

    end_point_fws = []
    for n, coord in enumerate(insert_coords):
        end_point_fws.append(
            EndPointFW(
                approx_neb_wf_uuid=wf_uuid,
                insert_specie=working_ion,
                insert_coords=coord,
                end_points_index=n,
                db_file=db_file,
                override_default_vasp_params=approx_neb_params,
                parents=host_fw,
            ))

    evaluate_path_fws = []
    for end_points_combo in insert_coords_combinations:
        if isinstance(end_points_combo, (str)):
            combo = end_points_combo.split("+")
            if len(combo) == 2:
                c = [int(combo[0]), int(combo[-1])]
            else:
                raise ValueError(
                    "string format in insert_coords_combinations is incorrect")

        evaluate_path_fws.append(
            EvaluatePathFW(
                approx_neb_wf_uuid=wf_uuid,
                end_points_combo=end_points_combo,
                mobile_specie=working_ion,
                n_images=n_images,
                selective_dynamics_scheme=selective_dynamics_scheme,
                launch_mode=launch_mode,
                vasp_cmd=vasp_cmd,
                db_file=db_file,
                override_default_vasp_params=approx_neb_params,
                handler_group=handler_group,
                parents=[end_point_fws[c[0]], end_point_fws[c[1]]],
                add_additional_fields=additional_fields,
                add_tags=tags,
            ))

    wf = Workflow([host_fw] + end_point_fws + evaluate_path_fws)

    wf = use_custodian(wf, custodian_params={"handler_group": handler_group})
    if isinstance(tags, (list)):
        wf = add_tags(wf, tags)
    if isinstance(additional_fields, (dict)):
        wf = add_additional_fields_to_taskdocs(wf,
                                               update_dict=additional_fields)
    if powerup_dicts is not None:
        wf = powerup_by_kwargs(wf, powerup_dicts)
        for fw in wf.fws:
            fw.spec["vasp_powerups"] = powerup_dicts
    wf.metadata.update({"approx_neb_wf_uuid": wf_uuid})
    wf.name = name

    return wf