Beispiel #1
0
def make_supercell(
    cell_structure: pmg.Structure,
    scaling_matrix: Optional[ScalingMatrix] = None,
    scaling_factors: Optional[Tuple[int, int, int]] = None,
) -> pmg.Structure:
    """Transforms a pymatgen ``Structure`` object into a supercell according to the
    scaling parameters.

    :param cell_structure: A pymatgen ``Structure`` object.
    :param scaling_matrix: A matrix of transforming the lattice vectors. Has to be all
        integers. e.g., [[2,1,0],[0,3,0],[0,0,1]] generates a new structure with lattice
        vectors a" = 2a + b, b" = 3b, c" = c where a, b, and c are the lattice vectors
        of the original structure.
    :param scaling_factors: A tuple of three numbers used to scale each lattice vector.
        Same as: ``scaling_matrix=[[scale_a, 0, 0], [0, scale_b, 0], [0, 0, scale_c]]``

    :return: A pymatgen ``Structure`` object.
    """
    if scaling_matrix is not None:
        cell_transformation: SupercellTransformation = SupercellTransformation(
            scaling_matrix=scaling_matrix)
        return cell_transformation.apply_transformation(cell_structure)

    elif scaling_factors is not None:
        cell_transformation = SupercellTransformation.from_scaling_factors(
            scale_a=scaling_factors[0],
            scale_b=scaling_factors[1],
            scale_c=scaling_factors[2],
        )
        return cell_transformation.apply_transformation(cell_structure)

    else:
        return cell_structure
Beispiel #2
0
 def test_append_transformation(self):
     t = SubstitutionTransformation({"Fe": "Mn"})
     self.trans.append_transformation(t)
     self.assertEqual(
         "NaMnPO4", self.trans.final_structure.composition.reduced_formula)
     self.assertEqual(len(self.trans.structures), 3)
     coords = list()
     coords.append([0, 0, 0])
     coords.append([0.75, 0.5, 0.75])
     lattice = [
         [3.8401979337, 0.00, 0.00],
         [1.9200989668, 3.3257101909, 0.00],
         [0.00, -2.2171384943, 3.1355090603],
     ]
     struct = Structure(lattice, ["Si4+", "Si4+"], coords)
     ts = TransformedStructure(struct, [])
     ts.append_transformation(
         SupercellTransformation.from_scaling_factors(2, 1, 1))
     alt = ts.append_transformation(
         PartialRemoveSpecieTransformation(
             "Si4+",
             0.5,
             algo=PartialRemoveSpecieTransformation.ALGO_COMPLETE),
         5,
     )
     self.assertEqual(len(alt), 2)
Beispiel #3
0
 def test_from_scaling_factors(self):
     scale_factors = [random.randint(1, 5) for i in range(3)]
     t = SupercellTransformation.from_scaling_factors(*scale_factors)
     s = t.apply_transformation(self.struct)
     self.assertEqual(
         s.num_sites,
         4 * functools.reduce(lambda a, b: a * b, scale_factors))
Beispiel #4
0
    def abi_sanitize(self, symprec=1e-3, primitive=True):
        """
        Returns a new structure in which:

            * Oxidation states are removed.
            * Structure is refined.
            * Reduced to primitive settings.
            * Lattice vectors are exchanged if the triple product is negative 

        Args:
            symprec: Symmetry precision used to refine the structure.
                if `symprec` is None, so structure refinement is peformed.
            primitive (bool): Whether to convert to a primitive cell.
        """

        from pymatgen.transformations.standard_transformations import OxidationStateRemovalTransformation, \
            PrimitiveCellTransformation, SupercellTransformation

        # Remove oxidation states.
        remove_ox = OxidationStateRemovalTransformation()
        structure = remove_ox.apply_transformation(self)

        # Refine structure
        if symprec is not None:
            sym_finder = SpacegroupAnalyzer(structure=structure,
                                            symprec=symprec)
            structure = sym_finder.get_refined_structure()

        # Convert to primitive structure.
        if primitive:
            get_prim = PrimitiveCellTransformation()
            structure = get_prim.apply_transformation(structure)

        # Exchange last two lattice vectors if triple product is negative.
        m = structure.lattice.matrix
        x_prod = np.dot(np.cross(m[0], m[1]), m[2])
        if x_prod < 0:
            trans = SupercellTransformation(((1, 0, 0), (0, 0, 1), (0, 1, 0)))
            structure = trans.apply_transformation(structure)
            m = structure.lattice.matrix
            x_prod = np.dot(np.cross(m[0], m[1]), m[2])
            if x_prod < 0: raise RuntimeError("x_prod is still negative!")

        return structure
Beispiel #5
0
    def abi_sanitize(self, symprec=1e-3, angle_tolerance=5, primitive=True, primitive_standard=False):
        """
        Returns a new structure in which:

            * Structure is refined.
            * Reduced to primitive settings.
            * Lattice vectors are exchanged if the triple product is negative 

        Args:
            symprec: Symmetry precision used to refine the structure.
                if `symprec` is None, so structure refinement is peformed.
            primitive (bool): Whether to convert to a primitive cell.
        """

        from pymatgen.transformations.standard_transformations import PrimitiveCellTransformation, SupercellTransformation

        structure = self.__class__.from_sites(self)

        # Refine structure
        if symprec is not None and angle_tolerance is not None:
            sym_finder = SpacegroupAnalyzer(structure=structure, symprec=symprec, angle_tolerance=angle_tolerance)
            structure = sym_finder.get_refined_structure()

        # Convert to primitive structure.
        if primitive:
            if primitive_standard:
                sym_finder_prim = SpacegroupAnalyzer(structure=structure, symprec=symprec, angle_tolerance=angle_tolerance)
                structure = sym_finder_prim.get_primitive_standard_structure()
            else:
                get_prim = PrimitiveCellTransformation()
                structure = get_prim.apply_transformation(structure)

        # Exchange last two lattice vectors if triple product is negative.
        m = structure.lattice.matrix
        x_prod = np.dot(np.cross(m[0], m[1]), m[2])
        if x_prod < 0:
            trans = SupercellTransformation(((1, 0, 0), (0, 0, 1), (0, 1, 0)))
            structure = trans.apply_transformation(structure)
            m = structure.lattice.matrix
            x_prod = np.dot(np.cross(m[0], m[1]), m[2])
            if x_prod < 0: raise RuntimeError("x_prod is still negative!")

        return structure
Beispiel #6
0
def refine_structure(structure, symprec=1e-3):
    remove_ox = OxidationStateRemovalTransformation()
    structure = remove_ox.apply_transformation(structure)
    sym_finder = SpacegroupAnalyzer(structure=structure, symprec=symprec)
    structure = sym_finder.get_refined_structure()
    get_prim = PrimitiveCellTransformation()
    structure = get_prim.apply_transformation(structure)
    m = structure.lattice.matrix
    x_prod = np.dot(np.cross(m[0], m[1]), m[2])
    if x_prod < 0:
        print(x_prod)
        trans = SupercellTransformation(((1, 0, 0), (0, 0, 1), (0, 1, 0)))
        structure = trans.apply_transformation(structure)
        m = structure.lattice.matrix
        x_prod = np.dot(np.cross(m[0], m[1]), m[2])
        print(x_prod)
        if x_prod < 0:
            raise RuntimeError
    return structure
Beispiel #7
0
def refine_structure(structure, symprec=1e-3):
    remove_ox = OxidationStateRemovalTransformation()
    structure = remove_ox.apply_transformation(structure)
    sym_finder = SpacegroupAnalyzer(structure=structure, symprec=symprec)
    structure = sym_finder.get_refined_structure()
    get_prim = PrimitiveCellTransformation()
    structure = get_prim.apply_transformation(structure)
    m = structure.lattice.matrix
    x_prod = np.dot(np.cross(m[0], m[1]), m[2])
    if x_prod < 0:
        print(x_prod)
        trans = SupercellTransformation(((1, 0, 0), (0, 0, 1), (0, 1, 0)))
        structure = trans.apply_transformation(structure)
        m = structure.lattice.matrix
        x_prod = np.dot(np.cross(m[0], m[1]), m[2])
        print(x_prod)
        if x_prod < 0:
            raise RuntimeError
    return structure
Beispiel #8
0
    def create_input(self):
        """
        create input for all the benchmark calculations

        :return 0 on succes
        """
        self.reset_bar()
        print('testing executable %s' % self.subject)
        print(
            "creating input for %s system sizes and %s calculations per size:"
            % (len(self.sizes), int(self.total / len(self.sizes))))
        sys.stdout.write(self.bar_len * "-" + "\n")
        sys.stdout.flush()
        for s in self.sizes:
            sys.stdout.write("|")
            sys.stdout.flush()
            struc = copy.deepcopy(self.structure)
            trans = SupercellTransformation.from_scaling_factors(scale_a=s,
                                                                 scale_b=s,
                                                                 scale_c=s)
            struc = trans.apply_transformation(struc)
            for n in self.np_list:
                if self.kpar:
                    kpar = itr(n)
                else:
                    kpar = 1
                self.inpset.incar_settings.update({'KPAR': kpar})
                for x in self.parameter_lists:
                    for o in self.parameter_lists[x]:
                        sys.stdout.write("*")
                        sys.stdout.flush()
                        v = functions(x)(o, int(n / kpar))
                        self.inpset.incar_settings.update({x: v})
                        path = '%s_super%s_par%s%s%s' % (self.name, s, n, x, o)
                        path = os.path.join(os.getcwd(), path)
                        self.inpset.incar_settings.update(
                            {'system': '%s_super%s' % (self.name, s)})
                        self.inpset.write_input(structure=struc,
                                                output_dir=path)
                        q = self.manager.qadapter
                        q.set_mpi_procs(n)
                        job_string = q.get_script_str(
                            job_name=self.name + 's' + str(s) + 'np' + str(n),
                            executable=self.subject,
                            launch_dir=path,
                            partition=None,
                            qerr_path='qerr.out',
                            qout_path='qout.out')
                        self.script_list.append(os.path.join(path, 'job.sh'))
                        f = open(self.script_list[-1], 'w')
                        f.write(job_string)
                        f.close()
        sys.stdout.write("|\n")
        sys.stdout.flush()
        return 0
Beispiel #9
0
def planar_structure_normalization(structure):
    '''
    This function does the following:
        1. check whether the structure is planar using coordniates standard deviation
        2. move the planar layer to the center of c-direction

    Args:
        structure: pymatgen structure
    Return:
        a boolean whether the structure is planar
        tranformed pymatgen structure
    '''
    tol = 1E-3 # tolerance to check whether the structure is planar
    is_planar = True

    coords = structure.frac_coords
    ts = TransformedStructure(structure, [])
    
    if np.std(coords[:,2]) < tol : 
        center_translate = 0.5 - coords[:,2].mean()
    elif np.std(coords[:,0]) < tol :
        ts.append_transformation(SupercellTransformation([[0,0,1],[0,1,0],[1,0,0]]))
        ts.append_transformation(RotationTransformation([0,1,0], 90))        
        center_translate = 0.5 - coords[:,0].mean()
    elif np.std(coords[:,1]) < tol :
        ts.append_transformation(SupercellTransformation([[1,0,0],[0,0,1],[0,1,0]]))
        ts.append_transformation(RotationTransformation([1,0,0], 90)) 
        center_translate = 0.5 - coords[:,1].mean()
    else : 
        is_planar = False
        transformed_structure = None

    if is_planar:
        ts.append_transformation(TranslateSitesTransformation(
                            list(range(len(structure))), [0,0,center_translate]))        
        # Use pymatgen 2019.7.2, ts.structures[-1] may change in a newer version           
        transformed_structure = ts.structures[-1]
    
    return is_planar, transformed_structure
Beispiel #10
0
 def test_append_transformation(self):
     t = SubstitutionTransformation({"Fe":"Mn"})
     self.trans.append_transformation(t)
     self.assertEqual("NaMnPO4", self.trans.final_structure.composition.reduced_formula)
     self.assertEqual(len(self.trans.structures), 3)
     coords = list()
     coords.append([0, 0, 0])
     coords.append([0.75, 0.5, 0.75])
     lattice = [[ 3.8401979337, 0.00, 0.00], [1.9200989668, 3.3257101909, 0.00], [0.00, -2.2171384943, 3.1355090603]]
     struct = Structure(lattice, ["Si4+", "Si4+"], coords)
     ts = TransformedStructure(struct, [])
     ts.append_transformation(SupercellTransformation.from_scaling_factors(2, 1, 1))
     alt = ts.append_transformation(PartialRemoveSpecieTransformation('Si4+', 0.5, algo=PartialRemoveSpecieTransformation.ALGO_COMPLETE), 5)
     self.assertEqual(len(alt), 2)
Beispiel #11
0
    def create_input(self):
        """
        create input for all the benchmark calculations

        :return 0 on succes
        """
        self.reset_bar()
        print('testing executable %s' % self.subject)
        print("creating input for %s system sizes and %s calculations per size:" %
              (len(self.sizes), int(self.total / len(self.sizes))))
        sys.stdout.write(self.bar_len*"-"+"\n")
        sys.stdout.flush()
        for s in self.sizes:
            sys.stdout.write("|")
            sys.stdout.flush()
            struc = copy.deepcopy(self.structure)
            trans = SupercellTransformation.from_scaling_factors(scale_a=s, scale_b=s, scale_c=s)
            struc = trans.apply_transformation(struc)
            for n in self.np_list:
                if self.kpar:
                    kpar = itr(n)
                else:
                    kpar = 1
                self.inpset.incar_settings.update({'KPAR': kpar})
                for x in self.parameter_lists:
                    for o in self.parameter_lists[x]:
                        sys.stdout.write("*")
                        sys.stdout.flush()
                        v = functions(x)(o, int(n/kpar))
                        self.inpset.incar_settings.update({x: v})
                        path = '%s_super%s_par%s%s%s' % (self.name, s, n, x, o)
                        path = os.path.join(os.getcwd(), path)
                        self.inpset.incar_settings.update({'system': '%s_super%s' % (self.name, s)})
                        self.inpset.write_input(structure=struc, output_dir=path)
                        q = self.manager.qadapter
                        q.set_mpi_procs(n)
                        job_string = q.get_script_str(job_name=self.name+'s'+str(s)+'np'+str(n),
                                                      executable=self.subject,
                                                      launch_dir=path,
                                                      partition=None,
                                                      qerr_path='qerr.out',
                                                      qout_path='qout.out')
                        self.script_list.append(os.path.join(path, 'job.sh'))
                        f = open(self.script_list[-1], 'w')
                        f.write(job_string)
                        f.close()
        sys.stdout.write("|\n")
        sys.stdout.flush()
        return 0
Beispiel #12
0
 def test_apply_transformation(self):
     t = SupercellTransformation([[2, 1, 0], [0, 2, 0], [1, 0, 2]])
     s = t.apply_transformation(self.struct)
     self.assertEqual(s.composition.formula, "Li16 O16")
Beispiel #13
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
Beispiel #14
0
    def correct(self):
        backup(VASP_BACKUP_FILES | {self.output_filename})
        actions = []
        vi = VaspInput.from_directory(".")

        if self.errors.intersection(["tet", "dentet"]):
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"ISMEAR": 0}}})

        if "inv_rot_mat" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"SYMPREC": 1e-8}}})

        if "brmix" in self.errors:
            # If there is not a valid OUTCAR already, increment
            # error count to 1 to skip first fix
            if self.error_count['brmix'] == 0:
                try:
                    assert (Outcar(zpath(os.path.join(
                        os.getcwd(), "OUTCAR"))).is_stopped is False)
                except:
                    self.error_count['brmix'] += 1

            if self.error_count['brmix'] == 0:
                # Valid OUTCAR - simply rerun the job and increment
                # error count for next time
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"ISTART": 1}}})
                self.error_count['brmix'] += 1

            elif self.error_count['brmix'] == 1:
                # Use Kerker mixing w/default values for other parameters
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"IMIX": 1}}})
                self.error_count['brmix'] += 1

            elif self.error_count['brmix'] == 2 and vi["KPOINTS"].style \
                    == Kpoints.supported_modes.Gamma:
                actions.append({"dict": "KPOINTS",
                                "action": {"_set": {"generation_style":
                                                        "Monkhorst"}}})
                actions.append({"dict": "INCAR",
                                "action": {"_unset": {"IMIX": 1}}})
                self.error_count['brmix'] += 1

            elif self.error_count['brmix'] in [2, 3] and vi["KPOINTS"].style \
                    == Kpoints.supported_modes.Monkhorst:
                actions.append({"dict": "KPOINTS",
                                "action": {"_set": {"generation_style":
                                                        "Gamma"}}})
                actions.append({"dict": "INCAR",
                                "action": {"_unset": {"IMIX": 1}}})
                self.error_count['brmix'] += 1

                if vi["KPOINTS"].num_kpts < 1:
                    all_kpts_even = all([
                        bool(n % 2 == 0) for n in vi["KPOINTS"].kpts[0]
                    ])
                    print("all_kpts_even = {}".format(all_kpts_even))
                    if all_kpts_even:
                        new_kpts = (
                            tuple(n + 1 for n in vi["KPOINTS"].kpts[0]),)
                        print("new_kpts = {}".format(new_kpts))
                        actions.append({"dict": "KPOINTS", "action": {"_set": {
                            "kpoints": new_kpts
                        }}})

            else:
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"ISYM": 0}}})

                if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst:
                    actions.append({"dict": "KPOINTS",
                                    "action": {
                                        "_set": {"generation_style": "Gamma"}}})

                # Based on VASP forum's recommendation, you should delete the
                # CHGCAR and WAVECAR when dealing with this error.
                if vi["INCAR"].get("ICHARG", 0) < 10:
                    actions.append({"file": "CHGCAR",
                                    "action": {
                                        "_file_delete": {'mode': "actual"}}})
                    actions.append({"file": "WAVECAR",
                                    "action": {
                                        "_file_delete": {'mode': "actual"}}})

        if "zpotrf" in self.errors:
            # Usually caused by short bond distances. If on the first step,
            # volume needs to be increased. Otherwise, it was due to a step
            # being too big and POTIM should be decreased.  If a static run
            # try turning off symmetry.
            try:
                oszicar = Oszicar("OSZICAR")
                nsteps = len(oszicar.ionic_steps)
            except:
                nsteps = 0

            if nsteps >= 1:
                potim = float(vi["INCAR"].get("POTIM", 0.5)) / 2.0
                actions.append(
                    {"dict": "INCAR",
                     "action": {"_set": {"ISYM": 0, "POTIM": potim}}})
            elif vi["INCAR"].get("NSW", 0) == 0 \
                    or vi["INCAR"].get("ISIF", 0) in range(3):
                actions.append(
                    {"dict": "INCAR", "action": {"_set": {"ISYM": 0}}})
            else:
                s = vi["POSCAR"].structure
                s.apply_strain(0.2)
                actions.append({"dict": "POSCAR",
                                "action": {"_set": {"structure": s.as_dict()}}})

            # Based on VASP forum's recommendation, you should delete the
            # CHGCAR and WAVECAR when dealing with this error.
            if vi["INCAR"].get("ICHARG", 0) < 10:
                actions.append({"file": "CHGCAR",
                                "action": {"_file_delete": {'mode': "actual"}}})
                actions.append({"file": "WAVECAR",
                                "action": {"_file_delete": {'mode': "actual"}}})

        if self.errors.intersection(["subspacematrix", "rspher",
                                     "real_optlay", "nicht_konv"]):
            s = vi["POSCAR"].structure
            if len(s) < self.natoms_large_cell:
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"LREAL": False}}})
            else:
                # for large supercell, try an in-between option LREAL = True
                # prior to LREAL = False
                if self.error_count['real_optlay'] == 0:
                    # use real space projectors generated by pot
                    actions.append({"dict": "INCAR",
                                    "action": {"_set": {"LREAL": True}}})
                    self.error_count['real_optlay'] += 1
                elif self.error_count['real_optlay'] == 1:
                    actions.append({"dict": "INCAR",
                                    "action": {"_set": {"LREAL": False}}})
                    self.error_count['real_optlay'] += 1

        if self.errors.intersection(["tetirr", "incorrect_shift"]):

            if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst:
                actions.append({"dict": "KPOINTS",
                                "action": {
                                    "_set": {"generation_style": "Gamma"}}})

        if "rot_matrix" in self.errors:
            if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst:
                actions.append({"dict": "KPOINTS",
                                "action": {
                                    "_set": {"generation_style": "Gamma"}}})
            else:
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"ISYM": 0}}})

        if "amin" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"AMIN": "0.01"}}})

        if "triple_product" in self.errors:
            s = vi["POSCAR"].structure
            trans = SupercellTransformation(((1, 0, 0), (0, 0, 1), (0, 1, 0)))
            new_s = trans.apply_transformation(s)
            actions.append({"dict": "POSCAR",
                            "action": {"_set": {"structure": new_s.as_dict()}},
                            "transformation": trans.as_dict()})

        if "pricel" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"SYMPREC": 1e-8, "ISYM": 0}}})

        if "brions" in self.errors:
            potim = float(vi["INCAR"].get("POTIM", 0.5)) + 0.1
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"POTIM": potim}}})

        if "zbrent" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"IBRION": 1}}})
            actions.append({"file": "CONTCAR",
                            "action": {"_file_copy": {"dest": "POSCAR"}}})

        if "too_few_bands" in self.errors:
            if "NBANDS" in vi["INCAR"]:
                nbands = int(vi["INCAR"]["NBANDS"])
            else:
                with open("OUTCAR") as f:
                    for line in f:
                        if "NBANDS" in line:
                            try:
                                d = line.split("=")
                                nbands = int(d[-1].strip())
                                break
                            except (IndexError, ValueError):
                                pass
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"NBANDS": int(1.1 * nbands)}}})

        if "pssyevx" in self.errors:
            actions.append({"dict": "INCAR", "action":
                {"_set": {"ALGO": "Normal"}}})
        if "eddrmm" in self.errors:
            # RMM algorithm is not stable for this calculation
            if vi["INCAR"].get("ALGO", "Normal") in ["Fast", "VeryFast"]:
                actions.append({"dict": "INCAR", "action":
                    {"_set": {"ALGO": "Normal"}}})
            else:
                potim = float(vi["INCAR"].get("POTIM", 0.5)) / 2.0
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"POTIM": potim}}})
            if vi["INCAR"].get("ICHARG", 0) < 10:
                actions.append({"file": "CHGCAR",
                                "action": {"_file_delete": {'mode': "actual"}}})
                actions.append({"file": "WAVECAR",
                                "action": {"_file_delete": {'mode': "actual"}}})

        if "edddav" in self.errors:
            if vi["INCAR"].get("ICHARG", 0) < 10:
                actions.append({"file": "CHGCAR",
                                "action": {"_file_delete": {'mode': "actual"}}})
            actions.append({"dict": "INCAR", "action":
                {"_set": {"ALGO": "All"}}})

        if "grad_not_orth" in self.errors:
            if vi["INCAR"].get("ISMEAR", 1) < 0:
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"ISMEAR": "0"}}})

        if "zheev" in self.errors:
            if vi["INCAR"].get("ALGO", "Fast").lower() != "exact":
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"ALGO": "Exact"}}})
        if "elf_kpar" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"KPAR": 1}}})

        if "rhosyg" in self.errors:
            if vi["INCAR"].get("SYMPREC", 1e-4) == 1e-4:
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"ISYM": 0}}})
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"SYMPREC": 1e-4}}})

        if "posmap" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"SYMPREC": 1e-6}}})

        VaspModder(vi=vi).apply_actions(actions)
        return {"errors": list(self.errors), "actions": actions}
Beispiel #15
0
    def correct(self):
        backup(VASP_BACKUP_FILES | {self.output_filename})
        actions = []
        vi = VaspInput.from_directory(".")

        if self.errors.intersection(["tet", "dentet"]):
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"ISMEAR": 0}}})

        if "inv_rot_mat" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"SYMPREC": 1e-8}}})

        if "brmix" in self.errors:
            # If there is not a valid OUTCAR already, increment
            # error count to 1 to skip first fix
            if self.error_count['brmix'] == 0:
                try:
                    assert(Outcar(zpath(os.path.join(
                        os.getcwd(), "OUTCAR"))).is_stopped is False)
                except:
                    self.error_count['brmix'] += 1

            if self.error_count['brmix'] == 0:
                # Valid OUTCAR - simply rerun the job and increment
                # error count for next time
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"ISTART": 1}}})
                self.error_count['brmix'] += 1

            elif self.error_count['brmix'] == 1:
                # Use Kerker mixing w/default values for other parameters
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"IMIX": 1}}})
                self.error_count['brmix'] += 1

            elif self.error_count['brmix'] == 2 and vi["KPOINTS"].style \
                    == Kpoints.supported_modes.Gamma:
                actions.append({"dict": "KPOINTS",
                                "action": {"_set": {"generation_style":
                                                        "Monkhorst"}}})
                actions.append({"dict": "INCAR",
                                "action": {"_unset": {"IMIX": 1}}})
                self.error_count['brmix'] += 1

            elif self.error_count['brmix'] in [2, 3] and vi["KPOINTS"].style \
                    == Kpoints.supported_modes.Monkhorst:
                actions.append({"dict": "KPOINTS",
                                "action": {"_set": {"generation_style":
                                                        "Gamma"}}})
                actions.append({"dict": "INCAR",
                                "action": {"_unset": {"IMIX": 1}}})
                self.error_count['brmix'] += 1

                if vi["KPOINTS"].num_kpts < 1:
                    all_kpts_even = all([
                        bool(n % 2 == 0) for n in vi["KPOINTS"].kpts[0]
                    ])
                    print("all_kpts_even = {}".format(all_kpts_even))
                    if all_kpts_even:
                        new_kpts = (tuple(n+1 for n in vi["KPOINTS"].kpts[0]),)
                        print("new_kpts = {}".format(new_kpts))
                        actions.append({"dict": "KPOINTS", "action": {"_set": {
                            "kpoints": new_kpts
                        }}})

            else:
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"ISYM": 0}}})

                if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst:
                   actions.append({"dict": "KPOINTS",
                                   "action": {"_set": {"generation_style": "Gamma"}}})

                # Based on VASP forum's recommendation, you should delete the
                # CHGCAR and WAVECAR when dealing with this error.
                if vi["INCAR"].get("ICHARG", 0) < 10:
                    actions.append({"file": "CHGCAR",
                                    "action": {"_file_delete": {'mode': "actual"}}})
                    actions.append({"file": "WAVECAR",
                                    "action": {"_file_delete": {'mode': "actual"}}})

        if "zpotrf" in self.errors:
            # Usually caused by short bond distances. If on the first step,
            # volume needs to be increased. Otherwise, it was due to a step
            # being too big and POTIM should be decreased.
            try:
                oszicar = Oszicar("OSZICAR")
                nsteps = len(oszicar.ionic_steps)
            except:
                nsteps = 0

            if nsteps >= 1:
                potim = float(vi["INCAR"].get("POTIM", 0.5)) / 2.0
                actions.append(
                    {"dict": "INCAR",
                     "action": {"_set": {"ISYM": 0, "POTIM": potim}}})
            else:
                s = vi["POSCAR"].structure
                s.apply_strain(0.2)
                actions.append({"dict": "POSCAR",
                                "action": {"_set": {"structure": s.as_dict()}}})

            # Based on VASP forum's recommendation, you should delete the
            # CHGCAR and WAVECAR when dealing with this error.
            if vi["INCAR"].get("ICHARG", 0) < 10:
                actions.append({"file": "CHGCAR",
                                "action": {"_file_delete": {'mode': "actual"}}})
                actions.append({"file": "WAVECAR",
                                "action": {"_file_delete": {'mode': "actual"}}})

        if self.errors.intersection(["subspacematrix", "rspher",
                                     "real_optlay"]):
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"LREAL": False}}})

        if self.errors.intersection(["tetirr", "incorrect_shift"]):

            if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst:
                actions.append({"dict": "KPOINTS",
                                "action": {"_set": {"generation_style": "Gamma"}}})

        if "rot_matrix" in self.errors:
            if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst:
                actions.append({"dict": "KPOINTS",
                                "action": {"_set": {"generation_style": "Gamma"}}})
            else:
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"ISYM": 0}}})

        if "amin" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"AMIN": "0.01"}}})

        if "triple_product" in self.errors:
            s = vi["POSCAR"].structure
            trans = SupercellTransformation(((1, 0, 0), (0, 0, 1), (0, 1, 0)))
            new_s = trans.apply_transformation(s)
            actions.append({"dict": "POSCAR",
                            "action": {"_set": {"structure": new_s.as_dict()}},
                            "transformation": trans.as_dict()})

        if "pricel" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"SYMPREC": 1e-8, "ISYM": 0}}})

        if "brions" in self.errors:
            potim = float(vi["INCAR"].get("POTIM", 0.5)) + 0.1
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"POTIM": potim}}})

        if "zbrent" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"IBRION": 1}}})
            actions.append({"file": "CONTCAR",
                            "action": {"_file_copy": {"dest": "POSCAR"}}})

        if "too_few_bands" in self.errors:
            if "NBANDS" in vi["INCAR"]:
                nbands = int(vi["INCAR"]["NBANDS"])
            else:
                with open("OUTCAR") as f:
                    for line in f:
                        if "NBANDS" in line:
                            try:
                                d = line.split("=")
                                nbands = int(d[-1].strip())
                                break
                            except (IndexError, ValueError):
                                pass
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"NBANDS": int(1.1 * nbands)}}})

        if "pssyevx" in self.errors:
            actions.append({"dict": "INCAR", "action":
                                    {"_set": {"ALGO": "Normal"}}})
        if "eddrmm" in self.errors:
            # RMM algorithm is not stable for this calculation
            if vi["INCAR"].get("ALGO", "Normal") in ["Fast", "VeryFast"]:
                actions.append({"dict": "INCAR", "action":
                                        {"_set": {"ALGO": "Normal"}}})
            else:
                potim = float(vi["INCAR"].get("POTIM", 0.5)) / 2.0
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"POTIM": potim}}})
            if vi["INCAR"].get("ICHARG", 0) < 10:
                actions.append({"file": "CHGCAR",
                                "action": {"_file_delete": {'mode': "actual"}}})
                actions.append({"file": "WAVECAR",
                                "action": {"_file_delete": {'mode': "actual"}}})

        if "edddav" in self.errors:
            if vi["INCAR"].get("ICHARG", 0) < 10:
                actions.append({"file": "CHGCAR",
                                "action": {"_file_delete": {'mode': "actual"}}})
            actions.append({"dict": "INCAR", "action":
                            {"_set": {"ALGO": "All"}}})

        if "grad_not_orth" in self.errors:
            if vi["INCAR"].get("ISMEAR", 1) < 0:
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"ISMEAR": "0"}}})

        VaspModder(vi=vi).apply_actions(actions)
        return {"errors": list(self.errors), "actions": actions}
Beispiel #16
0
    def correct(self):
        backup(VASP_BACKUP_FILES | {self.output_filename})
        actions = []
        vi = VaspInput.from_directory(".")

        if self.errors.intersection(["tet", "dentet"]):
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "ISMEAR": 0
                    }
                }
            })

        if "inv_rot_mat" in self.errors:
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "SYMPREC": 1e-8
                    }
                }
            })

        if "brmix" in self.errors:

            if self.error_count['brmix'] == 0 and vi[
                    "KPOINTS"].style == Kpoints.supported_modes.Gamma:
                actions.append({
                    "dict": "KPOINTS",
                    "action": {
                        "_set": {
                            "generation_style": "Monkhorst"
                        }
                    }
                })
                self.error_count['brmix'] += 1

            elif self.error_count['brmix'] <= 1 and vi[
                    "KPOINTS"].style == Kpoints.supported_modes.Monkhorst:
                actions.append({
                    "dict": "KPOINTS",
                    "action": {
                        "_set": {
                            "generation_style": "Gamma"
                        }
                    }
                })
                self.error_count['brmix'] += 1

                if vi["KPOINTS"].num_kpts < 1:
                    all_kpts_even = all(
                        [bool(n % 2 == 0) for n in vi["KPOINTS"].kpts[0]])
                    print("all_kpts_even = {}".format(all_kpts_even))
                    if all_kpts_even:
                        new_kpts = (tuple(n + 1
                                          for n in vi["KPOINTS"].kpts[0]), )
                        print("new_kpts = {}".format(new_kpts))
                        actions.append({
                            "dict": "KPOINTS",
                            "action": {
                                "_set": {
                                    "kpoints": new_kpts
                                }
                            }
                        })

            else:
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "ISYM": 0
                        }
                    }
                })

                if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst:
                    actions.append({
                        "dict": "KPOINTS",
                        "action": {
                            "_set": {
                                "generation_style": "Gamma"
                            }
                        }
                    })

                # Based on VASP forum's recommendation, you should delete the
                # CHGCAR and WAVECAR when dealing with this error.
                actions.append({
                    "file": "CHGCAR",
                    "action": {
                        "_file_delete": {
                            'mode': "actual"
                        }
                    }
                })
                actions.append({
                    "file": "WAVECAR",
                    "action": {
                        "_file_delete": {
                            'mode': "actual"
                        }
                    }
                })

        if "zpotrf" in self.errors:
            # Usually caused by short bond distances. If on the first step,
            # volume needs to be increased. Otherwise, it was due to a step
            # being too big and POTIM should be decreased.
            try:
                oszicar = Oszicar("OSZICAR")
                nsteps = len(oszicar.ionic_steps)
            except:
                nsteps = 0

            if nsteps >= 1:
                potim = float(vi["INCAR"].get("POTIM", 0.5)) / 2.0
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "ISYM": 0,
                            "POTIM": potim
                        }
                    }
                })
            else:
                s = vi["POSCAR"].structure
                s.apply_strain(0.2)
                actions.append({
                    "dict": "POSCAR",
                    "action": {
                        "_set": {
                            "structure": s.as_dict()
                        }
                    }
                })

            # Based on VASP forum's recommendation, you should delete the
            # CHGCAR and WAVECAR when dealing with this error.

            actions.append({
                "file": "CHGCAR",
                "action": {
                    "_file_delete": {
                        'mode': "actual"
                    }
                }
            })
            actions.append({
                "file": "WAVECAR",
                "action": {
                    "_file_delete": {
                        'mode': "actual"
                    }
                }
            })

        if self.errors.intersection(
            ["subspacematrix", "rspher", "real_optlay"]):
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "LREAL": False
                    }
                }
            })

        if self.errors.intersection(["tetirr", "incorrect_shift"]):

            if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst:
                actions.append({
                    "dict": "KPOINTS",
                    "action": {
                        "_set": {
                            "generation_style": "Gamma"
                        }
                    }
                })

        if "rot_matrix" in self.errors:
            if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst:
                actions.append({
                    "dict": "KPOINTS",
                    "action": {
                        "_set": {
                            "generation_style": "Gamma"
                        }
                    }
                })
            else:
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "ISYM": 0
                        }
                    }
                })

        if "amin" in self.errors:
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "AMIN": "0.01"
                    }
                }
            })

        if "triple_product" in self.errors:
            s = vi["POSCAR"].structure
            trans = SupercellTransformation(((1, 0, 0), (0, 0, 1), (0, 1, 0)))
            new_s = trans.apply_transformation(s)
            actions.append({
                "dict": "POSCAR",
                "action": {
                    "_set": {
                        "structure": new_s.as_dict()
                    }
                },
                "transformation": trans.as_dict()
            })

        if "pricel" in self.errors:
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "SYMPREC": 1e-8,
                        "ISYM": 0
                    }
                }
            })

        if "brions" in self.errors:
            potim = float(vi["INCAR"].get("POTIM", 0.5)) + 0.1
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "POTIM": potim
                    }
                }
            })

        if "zbrent" in self.errors:
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "IBRION": 1
                    }
                }
            })

        if "too_few_bands" in self.errors:
            if "NBANDS" in vi["INCAR"]:
                nbands = int(vi["INCAR"]["NBANDS"])
            else:
                with open("OUTCAR") as f:
                    for line in f:
                        if "NBANDS" in line:
                            try:
                                d = line.split("=")
                                nbands = int(d[-1].strip())
                                break
                            except (IndexError, ValueError):
                                pass
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "NBANDS": int(1.1 * nbands)
                    }
                }
            })

        if "pssyevx" in self.errors:
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "ALGO": "Normal"
                    }
                }
            })
        if "eddrmm" in self.errors:
            #RMM algorithm is not stable for this calculation
            if vi["INCAR"].get("ALGO", "Normal") in ["Fast", "VeryFast"]:
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "ALGO": "Normal"
                        }
                    }
                })
            else:
                potim = float(vi["INCAR"].get("POTIM", 0.5)) / 2.0
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "POTIM": potim
                        }
                    }
                })

            actions.append({
                "file": "CHGCAR",
                "action": {
                    "_file_delete": {
                        'mode': "actual"
                    }
                }
            })
            actions.append({
                "file": "WAVECAR",
                "action": {
                    "_file_delete": {
                        'mode': "actual"
                    }
                }
            })
        if "edddav" in self.errors:
            actions.append({
                "file": "CHGCAR",
                "action": {
                    "_file_delete": {
                        'mode': "actual"
                    }
                }
            })
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "ALGO": "All"
                    }
                }
            })

        VaspModder(vi=vi).apply_actions(actions)
        return {"errors": list(self.errors), "actions": actions}
def create_SNL(dirbase, molecules, atoms, spc_present, num_each_spc, struct,
               s):
    layers = len(molecules)
    with MPRester("sm5RbuEp83T9Wo7P") as m:
        first_mol = struct[0]
        mono_or_homo = 0
        #if system is a monolayer or homogeneous use its proper .cif file, else use generic WTe2 for heterostructures
        if (layers == 1) or all(x == first_mol for x in struct):
            mono_or_homo = 1
            if (first_mol == molec[0]):
                structure = m.get_structure_by_material_id("mp-2815")  #MoS2
                ref = m.get_materials_id_references("mp-2815")
                r1 = np.array([0, 2, 4])
            elif (first_mol == molec[1]):
                structure = m.get_structure_by_material_id("mp-1634")  #MoSe2
                ref = m.get_materials_id_references("mp-1634")
                r1 = np.array([0, 2, 4])
            elif (first_mol == molec[2]):
                structure = m.get_structure_by_material_id("mp-602")  #MoTe2
                ref = m.get_materials_id_references("mp-602")
                r1 = np.array([1, 2, 5])
            elif (first_mol == molec[3]):
                structure = m.get_structure_by_material_id("mp-224")  #WS2
                ref = m.get_materials_id_references("mp-224")
                r1 = np.array([0, 3, 5])
            elif (first_mol == molec[4]):
                structure = m.get_structure_by_material_id("mp-1821")  #WSe2
                ref = m.get_materials_id_references("mp-1821")
                r1 = np.array([0, 2, 4])
            elif (first_mol == molec[5]):
                structure = m.get_structure_by_material_id("mp-1019322")  #WTe2
                ref = m.get_materials_id_references("mp-1019322")
                r1 = np.array([0, 3, 5])
        else:
            structure = m.get_structure_by_material_id("mp-1019322")  #WTe2
            ref = m.get_materials_id_references("mp-1019322")
            r1 = np.array([0, 3, 5])

        # initialize history
        history = []

        #half the height of original unit cell...to be used for vacuum length calculation later
        halfz = (structure.lattice.c) / 2

        #make supercell if necessary
        levels = layers
        if (levels % 2 == 1): levels = levels + 1
        tsuper = SupercellTransformation([[1, 0, 0], [0, 1, 0],
                                          [0, 0, (levels) / 2]])
        history.append(history_node(tsuper))
        supercell = tsuper.apply_transformation(structure)

        #make species replacements for heterostructures with more than one layer
        levels = layers
        if (levels % 2 == 1): levels = levels + 1
        #if heterostructure has more than one layer:
        if (mono_or_homo == 0):
            for i in range(0, len(molecules)):
                if (molecules[i] == 5):
                    continue
                else:
                    TMspc = elems[atoms[2 * i]]
                    TMloc = (levels * 2) + (i % 2) * (levels / 2) + int(
                        np.floor((i) / 2))
                    DCspc = elems[atoms[2 * i + 1]]
                    DCloc1 = (levels -
                              (levels / 2)) - i % 2 * (levels / 2) + int(
                                  np.floor((i) / 2))
                    DCloc2 = levels + i % 2 * (levels / 2) + int(
                        np.floor((i) / 2))
                    t1 = ReplaceSiteSpeciesTransformation({TMloc: TMspc})
                    t2 = ReplaceSiteSpeciesTransformation({DCloc1: DCspc})
                    t3 = ReplaceSiteSpeciesTransformation({DCloc2: DCspc})
                    history.append(history_node(t1))
                    history.append(history_node(t2))
                    history.append(history_node(t3))
                    supercell = t1.apply_transformation(supercell)
                    supercell = t2.apply_transformation(supercell)
                    supercell = t3.apply_transformation(supercell)

        #remove top layer of atom if necessary
        mult_factor = (layers + 1) / 2 - 1
        r = r1 + (r1 + 1) * mult_factor
        tremove = RemoveSitesTransformation(r)
        if (layers % 2 == 1):
            supercell = tremove.apply_transformation(supercell)
            history.append(history_node(tremove))

        #sort structure
        supercell = supercell.get_sorted_structure()

        #extend z-axis cell vector to add vaccuum to supercell
        vacuum = 10.0
        old_lattice = supercell.lattice
        if (layers % 2 == 1):
            new_c = old_lattice.c - halfz + vacuum
        else:
            new_c = old_lattice.c + vacuum
        new_lattice = Lattice.from_parameters(old_lattice.a, old_lattice.b,
                                              new_c, old_lattice.alpha,
                                              old_lattice.beta,
                                              old_lattice.gamma)
        final_structure = Structure(
            new_lattice,
            supercell.species,
            supercell.frac_coords *
            np.array([1., 1., (old_lattice.c / new_lattice.c)]),
            coords_are_cartesian=False)
        hnode = {
            'name': 'add vaccuum',
            'url': '',
            'description': 'increase z-direction cell vector by 10 angstroms'
        }
        history.append(hnode)

        #creat final SNL
        authors = [{"name": "Lindsay Bassman", "email": "*****@*****.**"}]
        projects = ["TMDC-Heterostructures"]
        remarks = [
            "MAGICS calculation of band structures of 2D TMDC stacked heterostructures"
        ]
        final_snl = StructureNL(final_structure,
                                authors,
                                projects=projects,
                                remarks=remarks,
                                references=ref,
                                history=history)

        #optionally write POSCAR file
        poscar = Poscar(final_structure, s)
        poscar.write_file(dirbase + "POSCAR", direct=False)
Beispiel #18
0
    def correct(self):
        backup(VASP_BACKUP_FILES | {self.output_filename})
        actions = []
        vi = VaspInput.from_directory(".")

        if self.errors.intersection(["tet", "dentet"]):
            actions.append({"dict": "INCAR", "action": {"_set": {"ISMEAR": 0}}})

        if "inv_rot_mat" in self.errors:
            actions.append({"dict": "INCAR", "action": {"_set": {"SYMPREC": 1e-8}}})

        if "brmix" in self.errors:
            actions.append({"dict": "INCAR", "action": {"_set": {"ISYM": 0}}})

            if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst:
                actions.append({"dict": "KPOINTS", "action": {"_set": {"generation_style": "Gamma"}}})

            # Based on VASP forum's recommendation, you should delete the
            # CHGCAR and WAVECAR when dealing with this error.
            actions.append({"file": "CHGCAR", "action": {"_file_delete": {"mode": "actual"}}})
            actions.append({"file": "WAVECAR", "action": {"_file_delete": {"mode": "actual"}}})

        if "zpotrf" in self.errors:
            # Usually caused by short bond distances. If on the first step,
            # volume needs to be increased. Otherwise, it was due to a step
            # being too big and POTIM should be decreased.
            try:
                oszicar = Oszicar("OSZICAR")
                nsteps = len(oszicar.ionic_steps)
            except:
                nsteps = 0

            if nsteps >= 1:
                potim = float(vi["INCAR"].get("POTIM", 0.5)) / 2.0
                actions.append({"dict": "INCAR", "action": {"_set": {"ISYM": 0, "POTIM": potim}}})
            else:
                s = vi["POSCAR"].structure
                s.apply_strain(0.2)
                actions.append({"dict": "POSCAR", "action": {"_set": {"structure": s.as_dict()}}})

            # Based on VASP forum's recommendation, you should delete the
            # CHGCAR and WAVECAR when dealing with this error.

            actions.append({"file": "CHGCAR", "action": {"_file_delete": {"mode": "actual"}}})
            actions.append({"file": "WAVECAR", "action": {"_file_delete": {"mode": "actual"}}})

        if self.errors.intersection(["subspacematrix", "rspher", "real_optlay"]):
            actions.append({"dict": "INCAR", "action": {"_set": {"LREAL": False}}})

        if self.errors.intersection(["tetirr", "incorrect_shift"]):

            if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst:
                actions.append({"dict": "KPOINTS", "action": {"_set": {"generation_style": "Gamma"}}})

        if "rot_matrix" in self.errors:
            if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst:
                actions.append({"dict": "KPOINTS", "action": {"_set": {"generation_style": "Gamma"}}})
            else:
                actions.append({"dict": "INCAR", "action": {"_set": {"ISYM": 0}}})

        if "amin" in self.errors:
            actions.append({"dict": "INCAR", "action": {"_set": {"AMIN": "0.01"}}})

        if "triple_product" in self.errors:
            s = vi["POSCAR"].structure
            trans = SupercellTransformation(((1, 0, 0), (0, 0, 1), (0, 1, 0)))
            new_s = trans.apply_transformation(s)
            actions.append(
                {
                    "dict": "POSCAR",
                    "action": {"_set": {"structure": new_s.as_dict()}},
                    "transformation": trans.as_dict(),
                }
            )

        if "pricel" in self.errors:
            actions.append({"dict": "INCAR", "action": {"_set": {"SYMPREC": 1e-8, "ISYM": 0}}})

        if "brions" in self.errors:
            potim = float(vi["INCAR"].get("POTIM", 0.5)) + 0.1
            actions.append({"dict": "INCAR", "action": {"_set": {"POTIM": potim}}})

        if "zbrent" in self.errors:
            actions.append({"dict": "INCAR", "action": {"_set": {"IBRION": 1}}})

        if "too_few_bands" in self.errors:
            if "NBANDS" in vi["INCAR"]:
                nbands = int(vi["INCAR"]["NBANDS"])
            else:
                with open("OUTCAR") as f:
                    for line in f:
                        if "NBANDS" in line:
                            try:
                                d = line.split("=")
                                nbands = int(d[-1].strip())
                                break
                            except (IndexError, ValueError):
                                pass
            actions.append({"dict": "INCAR", "action": {"_set": {"NBANDS": int(1.1 * nbands)}}})

        if "pssyevx" in self.errors:
            actions.append({"dict": "INCAR", "action": {"_set": {"ALGO": "Normal"}}})
        if "eddrmm" in self.errors:
            # RMM algorithm is not stable for this calculation
            if vi["INCAR"].get("ALGO", "Normal") in ["Fast", "VeryFast"]:
                actions.append({"dict": "INCAR", "action": {"_set": {"ALGO": "Normal"}}})
            else:
                potim = float(vi["INCAR"].get("POTIM", 0.5)) / 2.0
                actions.append({"dict": "INCAR", "action": {"_set": {"POTIM": potim}}})

            actions.append({"file": "CHGCAR", "action": {"_file_delete": {"mode": "actual"}}})
            actions.append({"file": "WAVECAR", "action": {"_file_delete": {"mode": "actual"}}})
        if "edddav" in self.errors:
            actions.append({"file": "CHGCAR", "action": {"_file_delete": {"mode": "actual"}}})
            actions.append({"dict": "INCAR", "action": {"_set": {"ALGO": "All"}}})

        VaspModder(vi=vi).apply_actions(actions)
        return {"errors": list(self.errors), "actions": actions}
Beispiel #19
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
Beispiel #20
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")
    def correct(self):

        backup(orig_handlers.VASP_BACKUP_FILES | {self.output_filename})
        actions = []
        vi = VaspInput.from_directory(".")

        if self.errors.intersection(["tet", "dentet"]):
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "ISMEAR": 0
                    }
                }
            })

        if "inv_rot_mat" in self.errors:
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "SYMPREC": 1e-8
                    }
                }
            })

        # ----- added ---------------------------------------------------
        if "plane_wave_coeff" in self.errors:
            actions.append({
                "file": "WAVECAR",
                "action": {
                    "_file_delete": {
                        'mode': "actual"
                    }
                }
            })
            actions.append({
                "file": "CHGCAR",
                "action": {
                    "_file_delete": {
                        'mode': "actual"
                    }
                }
            })
        # ---------------------------------------------------------------

        if "zpotrf" in self.errors:
            # Usually caused by short bond distances. If on the first step,
            # volume needs to be increased. Otherwise, it was due to a step
            # being too big and POTIM should be decreased.  If a static run
            # try turning off symmetry.
            try:
                oszicar = Oszicar("OSZICAR")
                nsteps = len(oszicar.ionic_steps)
            except:
                nsteps = 0

            if nsteps >= 1:
                potim = float(vi["INCAR"].get("POTIM", 0.5)) / 2.0
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "ISYM": 0,
                            "POTIM": potim
                        }
                    }
                })
            elif vi["INCAR"].get("NSW", 0) == 0 \
                    or vi["INCAR"].get("ISIF", 0) in range(3):
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "ISYM": 0
                        }
                    }
                })
            else:
                s = vi["POSCAR"].structure
                s.apply_strain(0.2)
                actions.append({
                    "dict": "POSCAR",
                    "action": {
                        "_set": {
                            "structure": s.as_dict()
                        }
                    }
                })

            # Based on VASP forum's recommendation, you should delete the
            # CHGCAR and WAVECAR when dealing with this error.
            if vi["INCAR"].get("ICHARG", 0) < 10:
                actions.append({
                    "file": "CHGCAR",
                    "action": {
                        "_file_delete": {
                            'mode': "actual"
                        }
                    }
                })
                actions.append({
                    "file": "WAVECAR",
                    "action": {
                        "_file_delete": {
                            'mode': "actual"
                        }
                    }
                })

        if self.errors.intersection(["subspacematrix"]):
            if self.error_count["subspacematrix"] == 0:
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "LREAL": False
                        }
                    }
                })
            else:
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "PREC": "Accurate"
                        }
                    }
                })
            self.error_count["subspacematrix"] += 1

        if self.errors.intersection(["rspher", "real_optlay", "nicht_konv"]):
            s = vi["POSCAR"].structure
            if len(s) < self.natoms_large_cell:
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "LREAL": False
                        }
                    }
                })
            else:
                # for large supercell, try an in-between option LREAL = True
                # prior to LREAL = False
                if self.error_count['real_optlay'] == 0:
                    # use real space projectors generated by pot
                    actions.append({
                        "dict": "INCAR",
                        "action": {
                            "_set": {
                                "LREAL": True
                            }
                        }
                    })
                elif self.error_count['real_optlay'] == 1:
                    actions.append({
                        "dict": "INCAR",
                        "action": {
                            "_set": {
                                "LREAL": False
                            }
                        }
                    })
                self.error_count['real_optlay'] += 1

        if self.errors.intersection(["tetirr", "incorrect_shift"]):

            # --Modified------------------------------------------------------
            if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst or \
                    vi["KPOINTS"].kpts_shift != [0.0, 0.0, 0.0]:
                actions.append({
                    "dict": "KPOINTS",
                    "action": {
                        "_set": {
                            "generation_style": "Gamma",
                            "usershift": [0.0, 0.0, 0.0]
                        }
                    }
                })
            # -----------------------------------------------------------
        if "rot_matrix" in self.errors:
            # --Modified------------------------------------------------------
            if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst or \
                    vi["KPOINTS"].kpts_shift != [0.0, 0.0, 0.0]:
                actions.append({
                    "dict": "KPOINTS",
                    "action": {
                        "_set": {
                            "generation_style": "Gamma",
                            "usershift": [0.0, 0.0, 0.0]
                        }
                    }
                })
            # -----------------------------------------------------------
            else:
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "ISYM": 0
                        }
                    }
                })

        if "amin" in self.errors:
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "AMIN": "0.01"
                    }
                }
            })

        if "triple_product" in self.errors:
            s = vi["POSCAR"].structure
            trans = SupercellTransformation(((1, 0, 0), (0, 0, 1), (0, 1, 0)))
            new_s = trans.apply_transformation(s)
            actions.append({
                "dict": "POSCAR",
                "action": {
                    "_set": {
                        "structure": new_s.as_dict()
                    }
                },
                "transformation": trans.as_dict()
            })

        if "pricel" in self.errors:
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "SYMPREC": 1e-8,
                        "ISYM": 0
                    }
                }
            })

        if "brions" in self.errors:
            potim = float(vi["INCAR"].get("POTIM", 0.5)) + 0.1
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "POTIM": potim
                    }
                }
            })

        if "zbrent" in self.errors:
            # Modified so as not to use IBRION=1 as it does not show the
            # eigenvalues in vasprun.xml >>>>>>>>>>>>
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "ADDGRID": True
                    }
                }
            })
            actions.append({
                "file": "CONTCAR",
                "action": {
                    "_file_copy": {
                        "dest": "POSCAR"
                    }
                }
            })
        #            actions.append({"dict": "INCAR",
        #                            "action": {"_set": {"IBRION": 1}}})
        #            actions.append({"file": "CONTCAR",
        #                            "action": {"_file_copy": {"dest": "POSCAR"}}})
        # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

        if "too_few_bands" in self.errors:
            if "NBANDS" in vi["INCAR"]:
                nbands = int(vi["INCAR"]["NBANDS"])
            else:
                with open("OUTCAR") as f:
                    for line in f:
                        if "NBANDS" in line:
                            try:
                                d = line.split("=")
                                nbands = int(d[-1].strip())
                                break
                            except (IndexError, ValueError):
                                pass
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "NBANDS": int(1.1 * nbands)
                    }
                }
            })

        if "pssyevx" in self.errors:
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "ALGO": "Normal"
                    }
                }
            })
        if "eddrmm" in self.errors:
            # RMM algorithm is not stable for this calculation
            if vi["INCAR"].get("ALGO", "Normal") in ["Fast", "VeryFast"]:
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "ALGO": "Normal"
                        }
                    }
                })
            else:
                potim = float(vi["INCAR"].get("POTIM", 0.5)) / 2.0
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "POTIM": potim
                        }
                    }
                })
            if vi["INCAR"].get("ICHARG", 0) < 10:
                actions.append({
                    "file": "CHGCAR",
                    "action": {
                        "_file_delete": {
                            'mode': "actual"
                        }
                    }
                })
                actions.append({
                    "file": "WAVECAR",
                    "action": {
                        "_file_delete": {
                            'mode': "actual"
                        }
                    }
                })

        if "edddav" in self.errors:
            if vi["INCAR"].get("ICHARG", 0) < 10:
                actions.append({
                    "file": "CHGCAR",
                    "action": {
                        "_file_delete": {
                            'mode': "actual"
                        }
                    }
                })
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "ALGO": "All"
                    }
                }
            })

        if "grad_not_orth" in self.errors:
            if vi["INCAR"].get("ISMEAR", 1) < 0:
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "ISMEAR": "0"
                        }
                    }
                })

        if "zheev" in self.errors:
            if vi["INCAR"].get("ALGO", "Fast").lower() != "exact":
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "ALGO": "Exact"
                        }
                    }
                })
        if "elf_kpar" in self.errors:
            actions.append({"dict": "INCAR", "action": {"_set": {"KPAR": 1}}})

        if "rhosyg" in self.errors:
            if vi["INCAR"].get("SYMPREC", 1e-4) == 1e-4:
                actions.append({
                    "dict": "INCAR",
                    "action": {
                        "_set": {
                            "ISYM": 0
                        }
                    }
                })
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "SYMPREC": 1e-4
                    }
                }
            })

        if "posmap" in self.errors:
            actions.append({
                "dict": "INCAR",
                "action": {
                    "_set": {
                        "SYMPREC": 1e-6
                    }
                }
            })

        if "point_group" in self.errors:
            actions.append({"dict": "INCAR", "action": {"_set": {"ISYM": 0}}})

        ViseVaspModder(vi=vi).apply_actions(actions)
        return {"errors": list(self.errors), "actions": actions}
Beispiel #22
0
    def correct(self):
        backup(self.output_filename)
        actions = []
        vi = VaspInput.from_directory(".")

        if "tet" in self.errors or "dentet" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"ISMEAR": 0}}})
        if "inv_rot_mat" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"SYMPREC": 1e-8}}})
        if "brmix" in self.errors or "zpotrf" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"ISYM": 0}}})
        if "subspacematrix" in self.errors or "rspher" in self.errors or \
                "real_optlay" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"LREAL": False}}})
        if "tetirr" in self.errors or "incorrect_shift" in self.errors:
            actions.append({"dict": "KPOINTS",
                            "action": {"_set": {"generation_style": "Gamma"}}})
        if "amin" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"AMIN": "0.01"}}})
        if "too_few_bands" in self.errors:
            if "NBANDS" in vi["INCAR"]:
                nbands = int(vi["INCAR"]["NBANDS"])
            else:
                with open("OUTCAR") as f:
                    for line in f:
                        if "NBANDS" in line:
                            try:
                                d = line.split("=")
                                nbands = int(d[-1].strip())
                                break
                            except (IndexError, ValueError):
                                pass
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"NBANDS": int(1.1 * nbands)}}})

        if "triple_product" in self.errors:
            s = vi["POSCAR"].structure
            trans = SupercellTransformation(((1, 0, 0), (0, 0, 1), (0, 1, 0)))
            new_s = trans.apply_transformation(s)
            actions.append({"dict": "POSCAR",
                            "action": {"_set": {"structure": new_s.to_dict}},
                            "transformation": trans.to_dict})

        if "rot_matrix" in self.errors or "pricel" in self.errors:
            s = vi["POSCAR"].structure
            trans = PerturbStructureTransformation(0.05)
            new_s = trans.apply_transformation(s)
            actions.append({"dict": "POSCAR",
                            "action": {"_set": {"structure": new_s.to_dict}},
                            "transformation": trans.to_dict})
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"SYMPREC": 1e-8}}})

        if "brions" in self.errors:
            potim = float(vi["INCAR"].get("POTIM", 0.5)) + 0.1
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"POTIM": potim}}})
        m = Modder()
        modified = []
        for a in actions:
            modified.append(a["dict"])
            vi[a["dict"]] = m.modify_object(a["action"], vi[a["dict"]])
        for f in modified:
            vi[f].write_file(f)
        return {"errors": list(self.errors), "actions": actions}
Beispiel #23
0
    def correct(self):
        backup([self.output_filename, "INCAR", "KPOINTS", "POSCAR", "OUTCAR",
                "OSZICAR", "vasprun.xml"])
        actions = []
        vi = VaspInput.from_directory(".")

        if self.errors.intersection(["tet", "dentet"]):
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"ISMEAR": 0}}})

        if "inv_rot_mat" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"SYMPREC": 1e-8}}})

        if "brmix" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"ISYM": 0}}})

            if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst:
                actions.append({"dict": "KPOINTS",
                                "action": {"_set": {"generation_style": "Gamma"}}})

            # Based on VASP forum's recommendation, you should delete the
            # CHGCAR and WAVECAR when dealing with this error.
            actions.append({"file": "CHGCAR",
                            "action": {"_file_delete": {'mode': "actual"}}})
            actions.append({"file": "WAVECAR",
                            "action": {"_file_delete": {'mode': "actual"}}})

        if "zpotrf" in self.errors:
            # Usually caused by short bond distances. If on the first step,
            # volume needs to be increased. Otherwise, it was due to a step
            # being too big and POTIM should be decreased.
            try:
                oszicar = Oszicar("OSZICAR")
                nsteps = len(oszicar.ionic_steps)
            except:
                nsteps = 0

            if nsteps >= 1:
                potim = float(vi["INCAR"].get("POTIM", 0.5)) / 2.0
                actions.append(
                    {"dict": "INCAR",
                     "action": {"_set": {"ISYM": 0, "POTIM": potim}}})
            else:
                s = vi["POSCAR"].structure
                s.apply_strain(0.2)
                actions.append({"dict": "POSCAR",
                                "action": {"_set": {"structure": s.as_dict()}}})

            # Based on VASP forum's recommendation, you should delete the
            # CHGCAR and WAVECAR when dealing with this error.

            actions.append({"file": "CHGCAR",
                            "action": {"_file_delete": {'mode': "actual"}}})
            actions.append({"file": "WAVECAR",
                            "action": {"_file_delete": {'mode': "actual"}}})

        if self.errors.intersection(["subspacematrix", "rspher",
                                     "real_optlay"]):
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"LREAL": False}}})

        if self.errors.intersection(["tetirr", "incorrect_shift"]):

            if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst:
                actions.append({"dict": "KPOINTS",
                                "action": {"_set": {"generation_style": "Gamma"}}})

        if "rot_matrix" in self.errors:
            if vi["KPOINTS"].style == Kpoints.supported_modes.Monkhorst:
                actions.append({"dict": "KPOINTS",
                                "action": {"_set": {"generation_style": "Gamma"}}})
            else:
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"ISYM": 0}}})

        if "amin" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"AMIN": "0.01"}}})

        if "triple_product" in self.errors:
            s = vi["POSCAR"].structure
            trans = SupercellTransformation(((1, 0, 0), (0, 0, 1), (0, 1, 0)))
            new_s = trans.apply_transformation(s)
            actions.append({"dict": "POSCAR",
                            "action": {"_set": {"structure": new_s.as_dict()}},
                            "transformation": trans.as_dict()})

        if "pricel" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"SYMPREC": 1e-8, "ISYM": 0}}})

        if "brions" in self.errors:
            potim = float(vi["INCAR"].get("POTIM", 0.5)) + 0.1
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"POTIM": potim}}})

        if "zbrent" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"IBRION": 1}}})

        if "too_few_bands" in self.errors:
            if "NBANDS" in vi["INCAR"]:
                nbands = int(vi["INCAR"]["NBANDS"])
            else:
                with open("OUTCAR") as f:
                    for line in f:
                        if "NBANDS" in line:
                            try:
                                d = line.split("=")
                                nbands = int(d[-1].strip())
                                break
                            except (IndexError, ValueError):
                                pass
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"NBANDS": int(1.1 * nbands)}}})

        if "aliasing" in self.errors:
            with open("OUTCAR") as f:
                grid_adjusted = False
                changes_dict = {}
                r = re.compile(".+aliasing errors.*(NG.)\s*to\s*(\d+)")
                for line in f:
                    m = r.match(line)
                    if m:
                        changes_dict[m.group(1)] = int(m.group(2))
                        grid_adjusted = True
                    #Ensure that all NGX, NGY, NGZ have been checked
                    if grid_adjusted and 'NGZ' in line:
                        actions.extend(
                            [{"dict": "INCAR",
                              "action": {"_set": changes_dict}},
                             {"file": "CHGCAR",
                              "action": {"_file_delete": {'mode': "actual"}}},
                             {"file": "WAVECAR",
                              "action": {"_file_delete": {'mode': "actual"}}}])
                        break

        if "aliasing_incar" in self.errors:
            #vasp seems to give different warnings depending on whether the
            #aliasing error was caused by user supplied inputs
            d = {k: 1 for k in ['NGX', 'NGY', 'NGZ'] if k in vi['INCAR'].keys()}
            actions.extend([{"dict": "INCAR", "action": {"_unset": d}},
                            {"file": "CHGCAR",
                             "action": {"_file_delete": {'mode': "actual"}}},
                            {"file": "WAVECAR",
                             "action": {"_file_delete": {'mode': "actual"}}}])

        if "pssyevx" in self.errors:
            actions.append({"dict": "INCAR", "action":
                                    {"_set": {"ALGO": "Normal"}}})
        if "eddrmm" in self.errors:
            #RMM algorithm is not stable for this calculation
            if vi["INCAR"].get("ALGO", "Normal") in ["Fast", "VeryFast"]:
                actions.append({"dict": "INCAR", "action":
                                        {"_set": {"ALGO": "Normal"}}})
            else:
                potim = float(vi["INCAR"].get("POTIM", 0.5)) / 2.0
                actions.append({"dict": "INCAR",
                                "action": {"_set": {"POTIM": potim}}})

            actions.append({"file": "CHGCAR",
                            "action": {"_file_delete": {'mode': "actual"}}})
            actions.append({"file": "WAVECAR",
                            "action": {"_file_delete": {'mode': "actual"}}})

        VaspModder(vi=vi).apply_actions(actions)
        return {"errors": list(self.errors), "actions": actions}
Beispiel #24
0
    def correct(self): #pylint: disable=R0915,R0912,R0914
        """
        "brmix"にてINCARにADDGRIDを追加する
        """
        backup([self.output_filename, "INCAR", "KPOINTS", "POSCAR", "OUTCAR",
                "vasprun.xml"])
        actions = []
        vi = VaspInput.from_directory(".")

        if "tet" in self.errors or "dentet" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"ISMEAR": 0}}})

        if "inv_rot_mat" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"SYMPREC": 1e-8}}})

        if "brmix" in self.errors and "NELECT" in vi["INCAR"]:
            #brmix error always shows up after DAV steps if NELECT is specified
            self.errors.remove("brmix")
        if "brmix" in self.errors or "zpotrf" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"ISYM": 0}}})
            #140814 add
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"ADDGRID": True}}})
            # Based on VASP forum's recommendation, you should delete the
            # CHGCAR and WAVECAR when dealing with these errors.
            actions.append({"file": "CHGCAR",
                            "action": {"_file_delete": {'mode': "actual"}}})
            actions.append({"file": "WAVECAR",
                            "action": {"_file_delete": {'mode': "actual"}}})

        if "subspacematrix" in self.errors or "rspher" in self.errors or \
                        "real_optlay" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"LREAL": False}}})

        if "tetirr" in self.errors or "incorrect_shift" in self.errors or \
                    "rot_matrix" in self.errors:
            actions.append({"dict": "KPOINTS",
                            "action": {"_set": {"generation_style": "Gamma"}}})

        if "amin" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"AMIN": "0.01"}}})

        if "triple_product" in self.errors:
            s = vi["POSCAR"].structure
            trans = SupercellTransformation(((1, 0, 0), (0, 0, 1), (0, 1, 0)))
            new_s = trans.apply_transformation(s)
            actions.append({"dict": "POSCAR",
                            "action": {"_set": {"structure": new_s.to_dict}},
                            "transformation": trans.to_dict})

        if "pricel" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"SYMPREC": 1e-8, "ISYM": 0}}})

        if "brions" in self.errors:
            potim = float(vi["INCAR"].get("POTIM", 0.5)) + 0.1
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"POTIM": potim}}})

        if "zbrent" in self.errors:
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"IBRION": 1}}})

        if "too_few_bands" in self.errors:
            if "NBANDS" in vi["INCAR"]:
                nbands = int(vi["INCAR"]["NBANDS"])
            else:
                with open("OUTCAR") as f:
                    for line in f:
                        if "NBANDS" in line:
                            try:
                                d = line.split("=")
                                nbands = int(d[-1].strip())
                                break
                            except (IndexError, ValueError):
                                pass
            actions.append({"dict": "INCAR",
                            "action": {"_set": {"NBANDS": int(1.1 * nbands)}}})

        if "aliasing" in self.errors:
            with open("OUTCAR") as f:
                grid_adjusted = False
                changes_dict = {}
                for line in f:
                    if "aliasing errors" in line:
                        try:
                            grid_vector = line.split(" NG", 1)[1]
                            value = [int(s) for s in grid_vector.split(" ")
                                     if s.isdigit()][0]

                            changes_dict["NG" + grid_vector[0]] = value
                            grid_adjusted = True
                        except (IndexError, ValueError):
                            pass
                    #Ensure that all NGX, NGY, NGZ have been checked
                    if grid_adjusted and 'NGZ' in line:
                        actions.append({"dict": "INCAR",
                                        "action": {"_set": changes_dict}})
                        break

        m = Modder(actions=[DictActions, FileActions])
        modified = []
        for a in actions:
            if "dict" in a:
                modified.append(a["dict"])
                vi[a["dict"]] = m.modify_object(a["action"], vi[a["dict"]])
            elif "file" in a:
                m.modify(a["action"], a["file"])
        for f in modified:
            vi[f].write_file(f)
        return {"errors": list(self.errors), "actions": actions}