예제 #1
0
def nebef(ediffg):
	"""
	Run nebef.pl
	Args:
		ediffg (float): specified EDIFFG vlaue in VASP

	Returns:
		neb_conv (bool): True if NEB converged within EDIFFG
	"""
	ediffg = abs(ediffg)
	clean_files(['POSCAR'])
	open('nebef.dat','w').close()
	os.system('nebef.pl > nebef.dat')
	max_F = 0
	if os.stat('nebef.dat').st_size == 0:
		raise ValueError('nebef.dat not written')
	with open('nebef.dat','r') as rf:
		for line in rf:
			line = line.strip()
			max_F_temp = np.fromstring(line,dtype=float,sep=' ')[1]
			if max_F_temp > max_F:
				max_F = max_F_temp
	if max_F == 0.0:
		neb_conv = False
	elif max_F <= ediffg:
		neb_conv = True
	else:
		neb_conv = False

	return neb_conv
예제 #2
0
    def isif2_medacc(self):
        """
		Run medium accuracy ISIF2
		Returns:
			mof (ASE Atoms object): updated ASE Atoms object
		"""
        acc_levels = self.acc_levels
        outcar_paths = self.outcar_paths
        error_outcar_paths = self.error_outcar_paths
        spin_label = self.spin_label
        kpts_lo = self.kpts_dict['kpts_lo']
        kpts_hi = self.kpts_dict['kpts_hi']
        acc_level = acc_levels[self.run_i]
        calcs = self.calcs
        prior_results_path = os.path.join(
            self.results_partial_paths[self.run_i - 1], spin_label)

        if os.path.isfile(outcar_paths[self.run_i - 1]) and not os.path.isfile(
                outcar_paths[self.run_i]) and not os.path.isfile(
                    error_outcar_paths[self.run_i]):
            mof = prep_new_run(self)
            if sum(kpts_lo) == 3 and sum(kpts_hi) > 3:
                clean_files(['CHGCAR', 'WAVECAR'])
            else:
                manage_restart_files(prior_results_path)
            pprint('Running ' + spin_label + ', ' + acc_level)
            mof, self.calc_swaps = mof_run(self, mof, calcs('isif2_medacc'),
                                           kpts_hi)
            if mof is not None and mof.calc.scf_converged and mof.calc.converged:
                write_success(self)
            else:
                write_errors(self, mof)
        elif os.path.isfile(outcar_paths[self.run_i]):
            pprint('COMPLETED: ' + spin_label + ', ' + acc_level)
        mof = prep_next_run(self)
        if mof is None:
            pprint('Skipping rest because of errors')
            return None

        return mof
예제 #3
0
def mof_run(workflow, mof, calc, kpts, images=None, force_nupdown=False):
    """
	Run an atoms.get_potential_energy() calculation
	Args:
		workflow (class): pymofscreen.screen_phases.worfklow class

		mof (ASE Atoms object): ASE Atoms object for MOF

		calc (dict): ASE Vasp calculator

		kpts (list of ints): k-point grid

		images (int): number of NEB images

		force_nupdown (bool): force NUPDOWN to nearest int

	Returns:
		mof (ASE Atoms object): updated ASE Atoms object

		calc_swaps (list of strings): calc swaps
	"""

    nprocs = workflow.nprocs
    ppn = workflow.ppn
    calc_swaps = workflow.calc_swaps
    refcode = workflow.refcode
    stdout_file = workflow.stdout_file
    calc_swaps = workflow.calc_swaps
    gamma = workflow.kpts_dict['gamma']

    if force_nupdown:
        init_mags = mof.get_initial_magnetic_moments()
        summed_mags = np.sum(np.abs(init_mags))
        nupdown = int(np.round(summed_mags, 0))
        calc.int_params['nupdown'] = nupdown
    elif workflow.nupdown is not None:
        calc.int_params['nupdown'] = workflow.nupdown

    if sum(kpts) == 3:
        gpt_version = True
    else:
        gpt_version = False
    if images is not None:
        neb = True
        calc.int_params['images'] = images
    else:
        neb = False
    if not neb:
        try:
            nprocs = check_nprocs(len(mof), nprocs, ppn)
        except:
            pass
    choose_vasp_version(gpt_version, nprocs)
    calc.input_params['kpts'] = kpts
    calc.input_params['gamma'] = gamma
    if calc.int_params['ncore'] is None and calc.int_params['npar'] is None:
        calc.int_params['ncore'] = int(ppn / 2.0)
    calc, calc_swaps = update_calc(calc, calc_swaps)
    mof.set_calculator(calc)
    success = False

    try:
        mof.get_potential_energy()
        niter = get_niter('OUTCAR')
        if niter < mof.calc.int_params['nsw'] and mof.calc.converged != True:
            raise SystemError('VASP stopped but did not die')
        success = True
    except:

        if not os.path.isfile('STOPCAR') and not neb:

            old_error_len = 0
            restart_files = ['WAVECAR', 'CHGCAR']

            while True:

                errormsg = get_error_msgs('OUTCAR', refcode, stdout_file)
                print(errormsg)
                calc, calc_swaps = update_calc_after_errors(
                    calc, calc_swaps, errormsg)
                error_len = len(errormsg)
                if error_len == old_error_len:
                    break

                clean_files(restart_files)
                mof = continue_mof()
                choose_vasp_version(gpt_version, nprocs)
                mof.set_calculator(calc)

                try:
                    mof.get_potential_energy()
                    niter = get_niter('OUTCAR')
                    if (niter < mof.calc.int_params['nsw']
                            and mof.calc.converged != True):
                        raise SystemError('VASP stopped but did not die')
                    success = True
                except:
                    pass

                old_error_len = error_len

    if not success:
        mof = None

    return mof, calc_swaps
예제 #4
0
def mof_bfgs_run(workflow,
                 mof,
                 calc,
                 kpts,
                 steps=100,
                 fmax=0.05,
                 force_nupdown=False):
    """
	Run ASE BFGSLineSearch calculation
	Args:
		workflow (class): pymofscreen.screen_phases.worfklow class

		mof (ASE Atoms object): ASE Atoms object for MOF

		calc (dict): ASE Vasp calculator

		kpts (list of ints): k-point grid

		steps (int): maximum number of steps

		fmax (int): force tolerance

		force_nupdown (bool): force NUPDOWN to nearest int

	Returns:
		mof (ASE Atoms object): updated ASE Atoms object

		dyn (class): ASE dynamics class

		calc_swaps (list of strings): calc swaps
	"""

    nprocs = workflow.nprocs
    ppn = workflow.ppn
    calc_swaps = workflow.calc_swaps
    refcode = workflow.refcode
    stdout_file = workflow.stdout_file
    calc_swaps = workflow.calc_swaps
    gamma = workflow.kpts_dict['gamma']

    if force_nupdown:
        init_mags = mof.get_initial_magnetic_moments()
        summed_mags = np.sum(np.abs(init_mags))
        nupdown = int(np.round(summed_mags, 0))
        calc.int_params['nupdown'] = nupdown
    elif workflow.nupdown is not None:
        calc.int_params['nupdown'] = workflow.nupdown

    if sum(kpts) == 3:
        gpt_version = True
    else:
        gpt_version = False

    nprocs = check_nprocs(len(mof), nprocs, ppn)
    choose_vasp_version(gpt_version, nprocs)
    calc.input_params['kpts'] = kpts
    calc.input_params['gamma'] = gamma
    if calc.int_params['ncore'] is None and calc.int_params['npar'] is None:
        calc.int_params['ncore'] = int(ppn / 2.0)
    calc, calc_swaps = update_calc(calc, calc_swaps)
    mof.set_calculator(calc)
    dyn = BFGSLineSearch(mof, trajectory='opt.traj')
    success = False

    try:
        dyn.run(fmax=fmax, steps=steps)
        success = True
    except:

        if not os.path.isfile('STOPCAR'):

            old_error_len = 0
            restart_files = ['WAVECAR', 'CHGCAR']

            while True:

                errormsg = get_error_msgs('OUTCAR', refcode, stdout_file)
                print(errormsg)
                calc, calc_swaps = update_calc_after_errors(
                    calc, calc_swaps, errormsg)
                error_len = len(errormsg)
                if error_len == old_error_len:
                    break

                clean_files(restart_files)
                mof = continue_mof()
                mof.set_calculator(calc)
                dyn = BFGSLineSearch(mof, trajectory='opt.traj')

                try:
                    dyn.run(fmax=fmax, steps=steps)
                    success = True
                except:
                    pass

                old_error_len = error_len

    if not success:
        mof = None

    return mof, dyn, calc_swaps
예제 #5
0
    def dimer(self):
        """
		Run dimer
		Returns:
			mof (ASE Atoms object): updated ASE Atoms object
		"""
        acc_levels = self.acc_levels
        outcar_paths = self.outcar_paths
        error_outcar_paths = self.error_outcar_paths
        spin_level = self.spin_level
        spin_label = self.spin_label
        prior_spin = self.prior_spin
        acc_level = acc_levels[self.run_i]
        prior_acc_level = acc_levels[self.run_i - 1]
        results_partial_paths = self.results_partial_paths
        pwd = os.getcwd()
        if 'lowacc' in acc_level:
            kpts = self.kpts_dict['kpts_lo']
        else:
            kpts_lo = self.kpts_dict['kpts_lo']
            kpts = self.kpts_dict['kpts_hi']
        calcs = self.calcs
        if 'neb' in prior_acc_level and prior_spin is None:
            prior_results_path = os.path.join(
                results_partial_paths[self.run_i - 1])
            prior_results_file = os.path.join(prior_results_path, 'neb.tar.gz')
        elif 'lowacc' in acc_level and prior_spin is not None:
            prior_results_path = os.path.join(results_partial_paths[-1],
                                              prior_spin)
            prior_results_file = os.path.join(prior_results_path, 'OUTCAR')
        else:
            prior_results_file = outcar_paths[self.run_i - 1]
            prior_results_path = os.path.join(
                results_partial_paths[self.run_i - 1], spin_label)
        if os.path.isfile(prior_results_file) and not os.path.isfile(
                outcar_paths[self.run_i]) and not os.path.isfile(
                    error_outcar_paths[self.run_i]):
            if 'scf_test' in prior_acc_level:
                mof = prep_new_run(self)
                manage_restart_files(prior_results_path, dimer=False)
            elif 'neb' in prior_acc_level and prior_spin is None:
                manage_restart_files(prior_results_path, neb=True)
                mof = neb2dim()
                mof = set_initial_magmoms(mof, spin_level)
            elif 'lowacc' in acc_level and prior_spin is not None:
                mof = read(prior_results_file)
                mof = set_initial_magmoms(mof, spin_level)
                manage_restart_files(prior_results_path,
                                     dimer=True,
                                     wavechg=False)
            else:
                mof = prep_new_run(self)
                manage_restart_files(prior_results_path, dimer=True)
                if 'medacc' in acc_level and sum(
                        kpts_lo) == 3 and sum(kpts) > 3:
                    clean_files(['CHGCAR', 'WAVECAR'])
            if 'highacc' in acc_level and 'large_supercell' in self.calc_swaps:
                self.calc_swaps.remove('large_supercell')
            pprint('Running ' + spin_label + ', ' + acc_level)
            mof, self.calc_swaps = mof_run(self, mof, calcs(acc_level), kpts)
            if mof is not None and mof.calc.scf_converged and mof.calc.converged:
                write_success(self)
            else:
                write_errors(self, mof)
            vtst_cleanup()
        elif os.path.isfile(outcar_paths[self.run_i]):
            pprint('COMPLETED: ' + spin_label + ', ' + acc_level)
        mof = prep_next_run(self)
        os.chdir(pwd)
        if mof is None:
            pprint('Skipping rest because of errors')
            return None

        return mof
예제 #6
0
    def isif3_highacc(self):
        """
		Run high accuracy ISIF3
		Returns:
			mof (ASE Atoms object): updated ASE Atoms object
		"""
        acc_levels = self.acc_levels
        outcar_paths = self.outcar_paths
        error_outcar_paths = self.error_outcar_paths
        spin_label = self.spin_label
        kpts_lo = self.kpts_dict['kpts_lo']
        kpts_hi = self.kpts_dict['kpts_hi']
        acc_level = acc_levels[self.run_i]
        calcs = self.calcs
        prior_results_path = os.path.join(
            self.results_partial_paths[self.run_i - 1], spin_label)

        if os.path.isfile(outcar_paths[self.run_i - 1]) and not os.path.isfile(
                outcar_paths[self.run_i]) and not os.path.isfile(
                    error_outcar_paths[self.run_i]):
            mof = prep_new_run(self)
            converged = False
            loop_i = 0
            n_runs = 15
            V_diff = np.inf
            V_cut = 0.01
            V0 = mof.get_volume()
            if sum(kpts_lo) == 3 and sum(kpts_hi) > 3:
                clean_files(['CHGCAR', 'WAVECAR'])
            else:
                manage_restart_files(prior_results_path)
            while (not converged or V_diff > V_cut) and loop_i < n_runs:
                if loop_i == 10 and 'fire' not in self.calc_swaps and 'zbrent' not in self.calc_swaps:
                    self.calc_swaps.append('fire')
                pprint('Running ' + spin_label + ', ' + acc_level +
                       ': iteration ' + str(loop_i) + '/' + str(n_runs - 1))
                mof, self.calc_swaps = mof_run(self, mof,
                                               calcs('isif3_highacc'), kpts_hi)
                if mof is None:
                    break
                if loop_i > 0:
                    converged = mof.calc.converged
                mof = read('OUTCAR')
                V = mof.get_volume()
                mof = continue_magmoms(mof, 'INCAR')
                if loop_i > 0:
                    V_diff = np.abs((V - V0)) / V0
                V0 = V
                loop_i += 1
            if mof is not None and converged and V_diff <= V_cut and 'large_supercell' in self.calc_swaps:
                self.calc_swaps.append('nsw=100')
                self.calc_swaps.remove('large_supercell')
                pprint('Running ' + spin_label + ', ' + acc_level +
                       ' (LREAL=False)')
                mof, self.calc_swaps = mof_run(self, mof,
                                               calcs('isif3_highacc'), kpts_hi)
                self.calc_swaps.remove('nsw=100')
                if mof is not None and mof.calc.converged:
                    write_success(self)
                else:
                    write_errors(self, mof)
            else:
                write_errors(self, mof)
                if mof is not None and V_diff > V_cut:
                    pprint('^ Change in V of ' + str(V_diff) + ' percent')
            if 'fire' in self.calc_swaps:
                self.calc_swaps.remove('fire')
        elif os.path.isfile(outcar_paths[self.run_i]):
            pprint('COMPLETED: ' + spin_label + ', ' + acc_level)
        mof = prep_next_run(self)
        if mof is None:
            pprint('Skipping rest because of errors')
            return None

        return mof
예제 #7
0
    def __init__(self,
                 screener,
                 cif_file,
                 kpts_dict,
                 spin_level,
                 prior_spin=None,
                 vasp_files=None):
        """
		Initialize variables that should be used on all MOFs in a database
		Args:
			screener (class): pymofscreen.screen.screener class

			cif_file (string): name of CIF file

			kpts_dict (dict): dictionary containing kpoint and gamma information

			spin_level (string): name of spin level

			prior_spin (string): name of previous spin level (if applicable)
			
			vasp_files (list of strings): VASP files to save
		"""
        self.cif_file = cif_file
        self.kpts_dict = kpts_dict
        self.spin_level = spin_level
        self.acc_levels = screener.acc_levels
        self.spin_label = screener.spin_label
        if vasp_files is None:
            self.vasp_files = [
                'INCAR', 'POSCAR', 'KPOINTS', 'POTCAR', 'OUTCAR', 'CONTCAR',
                'CHGCAR', 'WAVECAR', 'EIGENVAL'
            ]
        self.calc_swaps = []
        self.run_i = 0
        if '.cif' in cif_file:
            self.refcode = cif_file.split('.cif')[0]
        elif 'POSCAR_' in cif_file:
            self.refcode = cif_file.split('POSCAR_')[1]
        else:
            self.refcode = cif_file
        self.stdout_file = screener.stdout_file
        self.mofpath = screener.mofpath
        self.submit_script = screener.submit_script
        self.basepath = screener.basepath
        self.niggli = screener.niggli
        self.calcs = screener.calcs
        self.nprocs, self.ppn = get_nprocs(self.submit_script)
        self.nupdown = screener.nupdown

        clean_files(self.vasp_files + ['CHG', 'AECCAR0', 'AECCAR1', 'AECCAR2'])

        results_partial_paths = []
        error_partial_paths = []
        error_outcar_paths = []
        outcar_paths = []
        for acc_level in self.acc_levels:
            results_partial_paths.append(
                os.path.join(self.basepath, 'results', self.refcode,
                             acc_level))
            error_partial_paths.append(
                os.path.join(self.basepath, 'errors', self.refcode, acc_level))
        self.results_partial_paths = results_partial_paths
        self.error_partial_paths = error_partial_paths
        for results_partial_path in results_partial_paths:
            outcar_paths.append(
                os.path.join(results_partial_path, self.spin_label, 'OUTCAR'))
        for error_partial_path in error_partial_paths:
            error_outcar_paths.append(
                os.path.join(error_partial_path, self.spin_label, 'OUTCAR'))
        self.outcar_paths = outcar_paths
        self.error_outcar_paths = error_outcar_paths
        self.prior_spin = prior_spin
        if prior_spin is None:
            self.spin1_final_mof_path = None
        else:
            self.spin1_final_mof_path = os.path.join(results_partial_paths[-1],
                                                     prior_spin, 'OUTCAR')
예제 #8
0
    def isif2_lowacc(self):
        """
		Run low accuracy ISIF2
		Returns:
			mof (ASE Atoms object): updated ASE Atoms object
		"""
        acc_levels = self.acc_levels
        outcar_paths = self.outcar_paths
        error_outcar_paths = self.error_outcar_paths
        spin_level = self.spin_level
        spin_label = self.spin_label
        cif_file = self.cif_file
        mofpath = self.mofpath
        prior_spin = self.prior_spin
        spin1_final_mof_path = self.spin1_final_mof_path
        kpts_lo = self.kpts_dict['kpts_lo']
        acc_level = acc_levels[self.run_i]
        niggli = self.niggli
        calcs = self.calcs
        prior_results_path = os.path.join(
            self.results_partial_paths[self.run_i - 1], spin_label)
        if os.path.isfile(outcar_paths[self.run_i - 1]) and not os.path.isfile(
                outcar_paths[self.run_i]) and not os.path.isfile(
                    error_outcar_paths[self.run_i]):
            if prior_spin is None:
                mof = cif_to_mof(os.path.join(mofpath, cif_file), niggli)
            else:
                mof = read(spin1_final_mof_path)
            manage_restart_files(prior_results_path)
            mof = set_initial_magmoms(mof, spin_level)
            fmax = 5.0
            pprint('Running ' + spin_label + ', ' + acc_level)
            mof, dyn, self.calc_swaps = mof_bfgs_run(self,
                                                     mof,
                                                     calcs('ase_bfgs'),
                                                     kpts_lo,
                                                     fmax=fmax)
            if mof is not None and dyn:
                loop_i = 0
                converged = False
                clean_files(['opt.traj'])
                while mof is not None and loop_i < 4 and not converged and mof.calc.scf_converged:
                    if loop_i == 2 and 'fire' not in self.calc_swaps and 'zbrent' not in self.calc_swaps:
                        self.calc_swaps.append('fire')
                    mof = read('OUTCAR')
                    mof = continue_magmoms(mof, 'INCAR')
                    mof, self.calc_swaps = mof_run(self, mof,
                                                   calcs('isif2_lowacc'),
                                                   kpts_lo)
                    if mof is None:
                        break
                    converged = mof.calc.converged
                    loop_i += 1
            if 'fire' in self.calc_swaps:
                self.calc_swaps.remove('fire')
            if mof is not None and mof.calc.scf_converged and mof.calc.converged:
                write_success(self)
            else:
                write_errors(self, mof)
        elif os.path.isfile(outcar_paths[self.run_i]):
            pprint('COMPLETED: ' + spin_label + ', ' + acc_level)
        mof = prep_next_run(self)
        if mof is None:
            pprint('Skipping rest because of errors')
            return None

        return mof