Exemple #1
0
    def check_POSCAR(self, config):
        '''             
        First line must like [1,0]32 to match the elements in POSCAR, 0 could not ignored.
        '''
        # To check the sum of occupancies
        for m in range(len(self.site_ratios)):
            sum_occupancy = 0
            for n in range(len(self.occupancies[m])):
                sum_occupancy += self.occupancies[m][n]
            if abs(sum_occupancy - 1) > 1e-10:
                print(
                    'The sum of occupancies in %s is NOT equal to 1, please check!'
                    % self.occupancies[m])
                return (False)

        # To check config and occupancy

        temp_struct = Structure.from_file(self.poscarfile)
        namelist_elements = []
        numlist_elements = []
        for e, a in temp_struct.composition.items():
            namelist_elements.append(e)
            numlist_elements.append(a)  # [8.0, 24.0]
        num_element_firstline = 0
        for ocs in self.occupancies:
            num_element_firstline += len(ocs)
        if len(numlist_elements) != num_element_firstline:
            print(
                'The number of element kind(%s) in first line of POASCAR is NOT same one in the structure(%s), maybe "0" occupancy should be added.'
                % (num_element_firstline, len(numlist_elements)))
            return (False)

        index = 0
        for m in range(len(self.site_ratios)):
            if len(config[m]) < len(self.occupancies[m]):
                num_occupancy = 0
                for n in range(len(self.occupancies[m])):
                    num_occupancy += self.occupancies[m][n] * self.site_ratios[
                        m]
                if abs(num_occupancy - numlist_elements[index]) > 1e-10:
                    print(
                        'The sum of sites in %s%s is NOT equal to %s(Element: %s), please check!'
                        % (self.occupancies[m], self.site_ratios[m],
                           numlist_elements[index], namelist_elements[index]))
                    return (False)
                index += len(self.occupancies[m])
            else:
                for n in range(len(self.occupancies[m])):
                    if abs(numlist_elements[index] - self.occupancies[m][n] *
                           self.site_ratios[m]) > 1e-10:
                        print(
                            'The sites in %s * %s is NOT equal to %s(Element: %s), please check!'
                            % (self.occupancies[m][n], self.site_ratios[m],
                               numlist_elements[index],
                               namelist_elements[index]))
                        return (False)
                    index += 1
        return (True)
Exemple #2
0
def run(args):
    """
    Run dfttk
    Currently, only support get_wf_gibbs

    Parameters
        STR_FOLDER = args.STRUCTURE_FOLDER
            folder/file containing structures
        MATCH_PATTERN = args.MATCH_PATTERN
            Match patterns for structure file, e.g. *POSCAR
        RECURSIVE = args.RECURSIVE
            recursive or not
        WORKFLOW = args.WORKFLOW
            workflow, current only get_wf_gibbs
        LAUNCH = args.LAUNCH
            Launch to lpad or not
        MAX_JOB = args.MAX_JOB
            Max job to submit
        SETTINGS = args.SETTINGS
            Settings file
        WRITE_OUT_WF = args.WRITE_OUT_WF
            Write out wf file or not
    """
    STR_FOLDER = args.STRUCTURE_FOLDER  # folder/file containing structures
    MATCH_PATTERN = args.MATCH_PATTERN  # Match patterns for structure file, e.g. *POSCAR
    RECURSIVE = args.RECURSIVE  # recursive or not
    WORKFLOW = args.WORKFLOW  # workflow, current only get_wf_gibbs
    PHONON = args.PHONON  # run phonon
    LAUNCH = args.LAUNCH  # Launch to lpad or not
    MAX_JOB = args.MAX_JOB  # Max job to submit
    SETTINGS = args.SETTINGS  # Settings file
    WRITE_OUT_WF = args.WRITE_OUT_WF  # Write out wf file or not
    TAG = args.TAG  # Metadata from the command line
    APPEND = args.APPEND  # Append calculations, e.g. appending volumes or phonon or born
    db_file = args.db_file  # user supplier db_file such as db.json

    if not db_file:
        if os.path.exists('db.json'):
            db_file = 'db.json'
    elif not os.path.exists(db_file):
        db_file = None

    ## Initial wfs and metadatas
    wfs = []
    metadatas = {}

    if APPEND:
        if TAG:
            metadatas = {
                os.path.join(os.path.abspath('./'), 'POSCAR'): {
                    'tag': TAG
                }
            }
        elif os.path.exists('METADATAS.yaml'):
            metadatas = loadfn('METADATAS.yaml')
        else:
            raise ValueError(
                'For APPEND model, please provide TAG with -tag or provide METADATAS.yaml file'
            )
        for keyi in metadatas:
            (STR_PATH, STR_FILENAME_WITH_EXT) = os.path.split(keyi)
            (STR_FILENAME, STR_EXT) = os.path.splitext(STR_FILENAME_WITH_EXT)
            user_settings = get_user_settings(STR_FILENAME_WITH_EXT,
                                              STR_PATH=STR_PATH,
                                              NEW_SETTING=SETTINGS)
            metadata = user_settings.get('metadata', {})
            metadata.update(metadatas[keyi])
            user_settings.update({'metadata': metadata})
            structure = get_eq_structure_by_metadata(metadata=metadata,
                                                     db_file=db_file)
            if structure is None:
                raise FileNotFoundError(
                    'There is no static results under current metadata tag({})'
                    .format(metadata['tag']))
            if PHONON:
                user_settings.update({'phonon': True})
            phonon_supercell_matrix = user_settings.get(
                'phonon_supercell_matrix', None)
            if phonon_supercell_matrix is None:
                user_settings.update({"phonon_supercell_matrix": "atoms"})

            wf = get_wf_single(structure,
                               WORKFLOW=WORKFLOW,
                               settings=user_settings,
                               db_file=db_file)

            wf = Customizing_Workflows(wf,
                                       powerups_options=user_settings.get(
                                           'powerups', None))
            if isinstance(wf, list):
                wfs = wfs + wf
            else:
                wfs.append(wf)

            if WRITE_OUT_WF:
                dfttk_wf_filename = os.path.join(
                    STR_PATH, "dfttk_wf-" + STR_FILENAME_WITH_EXT + ".yaml")
                dumpfn(wf, dfttk_wf_filename)
    else:
        if os.path.exists('METADATAS.yaml'):
            metadatas = loadfn('METADATAS.yaml')
        ## Get the file names of files
        STR_FILES = get_structure_file(STR_FOLDER=STR_FOLDER,
                                       RECURSIVE=RECURSIVE,
                                       MATCH_PATTERN=MATCH_PATTERN)
        ## generat the wf
        for STR_FILE in STR_FILES:
            (STR_PATH, STR_FILENAME_WITH_EXT) = os.path.split(STR_FILE)
            (STR_FILENAME, STR_EXT) = os.path.splitext(STR_FILENAME_WITH_EXT)
            str_filename = STR_FILENAME.lower()
            if (str_filename.endswith("-" + SETTINGS.lower())
                    or str_filename.startswith(SETTINGS.lower() + "-")
                    or (str_filename == SETTINGS.lower())):
                print(
                    STR_FILE +
                    " is a setting file, not structure file, and skipped when reading the structure."
                )
            elif STR_FILE == os.path.abspath(__file__):
                #This is current file
                pass
            else:
                flag_run = False
                try:
                    structure = Structure.from_file(STR_FILE)
                    flag_run = True
                except Exception as e:
                    warnings.warn("The name or the contant of " + STR_FILE + " is not supported by dfttk, and skipped. " + \
                        "Ref. https://pymatgen.org/pymatgen.core.structure.html#pymatgen.core.structure.IStructure.from_file")

                if flag_run:
                    user_settings = get_user_settings(STR_FILENAME_WITH_EXT,
                                                      STR_PATH=STR_PATH,
                                                      NEW_SETTING=SETTINGS)
                    metadatai = metadatas.get(STR_FILE, None)
                    if metadatai:
                        user_settings.update({'metadata': metadatai})
                    if PHONON:
                        user_settings.update({'phonon': True})
                    phonon_supercell_matrix = user_settings.get(
                        'phonon_supercell_matrix', None)
                    if phonon_supercell_matrix is None:
                        user_settings.update(
                            {"phonon_supercell_matrix": "atoms"})

                    wf = get_wf_single(structure,
                                       WORKFLOW=WORKFLOW,
                                       settings=user_settings)
                    wf = Customizing_Workflows(
                        wf,
                        powerups_options=user_settings.get('powerups', None))
                    metadatas[STR_FILE] = wf.as_dict()["metadata"]
                    wfs.append(wf)

                    if WRITE_OUT_WF:
                        dfttk_wf_filename = os.path.join(
                            STR_PATH,
                            "dfttk_wf-" + STR_FILENAME_WITH_EXT + ".yaml")
                        dumpfn(wf.to_dict(), dfttk_wf_filename)

        #Write Out the metadata for POST and continue purpose
        dumpfn(metadatas, "METADATAS.yaml")
    """
    _fws = []
    for wflow in wfs:
        revised_wflow = Customizing_Workflows(wflow,user_settings={})
        _fws.append(revised_wflow)
    fws = _fws
    """

    if LAUNCH:
        from fireworks import LaunchPad
        lpad = LaunchPad.auto_load()

        for wflow in wfs:
            lpad.add_wf(wflow)

        if MAX_JOB:
            # Not False or Empty
            if MAX_JOB == 1:
                os.system("qlaunch singleshot")
            else:
                os.system("qlaunch rapidfire -m " + str(MAX_JOB))
Exemple #3
0
    modify_incar_params = { 'Full relax': {'incar_update': {"LAECHG":False,"LCHARG":False,"LWAVE":False}},
                            'PreStatic': {'incar_update': {"LAECHG":False,"LCHARG":False,"LWAVE":False}},
                            'PS2': {'incar_update': {"LAECHG":False,"LCHARG":False,"LWAVE":False}},
                            'static': {'incar_update': {"LAECHG":False,"LCHARG":False,"LWAVE":False}},
    """
    modify_incar_params={}
    #dict, dict of class ModifyKpoints with keywords in Workflow name, similar with modify_incar_params
    modify_kpoints_params={}
    #bool, print(True) or not(False) some informations, used for debug
    verbose=False

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

    structure = Structure.from_file(TEMPLATE_STRUCTURE_FILENAME)

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

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

    wf = get_wf_gibbs(structure, num_deformations=num_deformations, deformation_fraction=deformation_fraction,
                phonon=phonon, phonon_supercell_matrix=phonon_supercell_matrix,  t_min=t_min, t_max=t_max,
                t_step=t_step, tolerance=tolerance, volume_spacing_min=volume_spacing_min,vasp_cmd=vasp_cmd,
                db_file=db_file, metadata=metadata, name='EV_QHA', symmetry_tolerance=symmetry_tolerance,
                run_isif2=run_isif2, pass_isif4=pass_isif4, passinitrun=passinitrun, relax_path=relax_path,
                modify_incar_params=modify_incar_params, modify_kpoints_params=modify_kpoints_params,
Exemple #4
0
def check_symmetry(tol_energy=0.025,
                   tol_strain=0.05,
                   tol_bond=0.10,
                   site_properties=None):
    '''
    Check symmetry for vasp run. This should be run for each vasp run

    Parameter
    ---------
        tol_energy: float
            The tolerance of energy
        tol_strain: float
            The tolerance of strain
        tol_bond: float
            The tolerance of bond
    Return
        symm_data: dict
            It will store the initial structure/final_structure, isif, initial_energy_per_atom,
                final_energy_per_atom, symmetry_checks_passed, tolerances, failures, number_of_failures
    ------
    '''
    # Get relevant files as pmg objects
    incar = Incar.from_file("INCAR")
    outcar = Outcar('OUTCAR')
    vasprun = Vasprun("vasprun.xml")
    inp_struct = Structure.from_file("POSCAR")
    out_struct = Structure.from_file("CONTCAR")

    if site_properties:
        if 'magmom' in site_properties:
            in_mag = incar.as_dict()['MAGMOM']
            inp_struct.add_site_property('magmom', in_mag)
            out_mag = [m['tot'] for m in outcar.magnetization]
            if len(out_mag) == 0:
                out_mag = copy.deepcopy(in_mag)
            out_struct.add_site_property('magmom', out_mag)
            site_properties.pop('magmom')
        for site_property in site_properties:
            inp_struct.add_site_property(site_property,
                                         site_properties[site_property])
            out_struct.add_site_property(site_property,
                                         site_properties[site_property])

    current_isif = incar['ISIF']
    initial_energy = float(
        vasprun.ionic_steps[0]['e_wo_entrp']) / len(inp_struct)
    final_energy = float(vasprun.final_energy) / len(out_struct)

    # perform all symmetry breaking checks
    failures = []
    energy_difference = np.abs(final_energy - initial_energy)
    if energy_difference > tol_energy:
        fail_dict = {
            'reason': 'energy',
            'tolerance': tol_energy,
            'value': energy_difference,
        }
        failures.append(fail_dict)
    strain_norm = get_non_isotropic_strain(inp_struct.lattice.matrix,
                                           out_struct.lattice.matrix)
    if strain_norm > tol_strain:
        fail_dict = {
            'reason': 'strain',
            'tolerance': tol_strain,
            'value': strain_norm,
        }
        failures.append(fail_dict)
    bond_distance_change = get_bond_distance_change(inp_struct, out_struct)
    if bond_distance_change > tol_bond:
        fail_dict = {
            'reason': 'bond distance',
            'tolerance': tol_bond,
            'value': bond_distance_change,
        }
        failures.append(fail_dict)

    symm_data = {
        "initial_structure": inp_struct.as_dict(),
        "final_structure": out_struct.as_dict(),
        "isif": current_isif,
        "initial_energy_per_atom": initial_energy,
        "final_energy_per_atom": final_energy,
        "real_value": {
            "energy": energy_difference,
            "strain": strain_norm,
            "bond": bond_distance_change
        },
        "tolerances": {
            "energy": tol_energy,
            "strain": tol_strain,
            "bond": tol_bond,
        },
        "failures": failures,
        "number_of_failures": len(failures),
        "symmetry_checks_passed": len(failures) == 0,
    }
    return symm_data