for V, st in zip(volume, structures): rmd.chdir(str(np.round(V, 2))) if run_specs['phonopy']['mode'] == 'force_set': structure = mg.Structure.from_dict(st) structure.to(filename='POSCAR') call('phonopy -d --dim="' + phonopy_specs['dim'] + '" > /dev/null', shell=True) os.remove('SPOSCAR') disp_structures = sorted(glob.glob('POSCAR-*')) disp_dirs = ['disp-' + i.split('POSCAR-')[1] for i in disp_structures] for disp_d, disp_p in zip(disp_dirs, disp_structures): rmd.chdir(disp_d) rmd.init_stdout() shutil.move('../' + disp_p, 'POSCAR') incar.write_file('INCAR') kpoints.write_file('KPOINTS') rmd.write_potcar(run_specs) job = str(V) + '-' + disp_d shutil.copy(cwd + '/INPUT/deploy.job', job) call('sed -i "/python/c time ' + rmd.VASP_EXEC + ' 2>&1 | tee -a stdout" ' + job, shell=True) call('M ' + job, shell=True) os.remove(job) os.chdir('..') elif run_specs['phonopy']['mode'] == 'force_constant': rmd.init_stdout() incar.write_file('INCAR') kpoints.write_file('KPOINTS') structure = mg.Structure.from_dict(st) structure.to(filename='POSCAR') call('phonopy -d --dim="' + phonopy_specs['dim'] + '" > /dev/null', shell=True) os.rename('POSCAR', 'POSCAR_orig') os.rename('SPOSCAR', 'POSCAR')
def volume_fitting(structure, is_mag, fitting_results): """ Construct a loop to get and fit the energy with changing volumes, return some indicators showing if the fit is "good" or not. """ volume = np.linspace(V_begin, V_end, V_sample_point_num) energy = np.zeros(len(volume)) mag = np.zeros(len(volume)) structures = [] for i, V in enumerate(volume): incar.write_file('INCAR') kpoints.write_file('KPOINTS') structure.scale_lattice(V) structure.to(filename='POSCAR') rmd.write_potcar(run_specs) rmd.run_vasp() oszicar = mg.io.vasp.Oszicar('OSZICAR') energy[i] = oszicar.final_energy structure = mg.Structure.from_file('CONTCAR') structures.append(structure.as_dict()) if is_mag: mag[i] = oszicar.ionic_steps[-1]['mag'] # dump in case error in fitting fitting_results.append({'volume': volume.tolist(), 'energy': energy.tolist(), 'mag': mag.tolist(), 'structures': structures}) rmd.filedump(fitting_results, 'fitting_results.json') # plot in case error in fitting plt.plot(volume, energy, 'o') plt.tight_layout() plt.savefig('eos_fit.pdf') plt.close() # fitting and dumping fitting_result_raw = pv.fitting.eos_fit(volume, energy, plot=True) plt.savefig('eos_fit.pdf') plt.close() params = fitting_result_raw['params'] fitting_results[-1]['pressure'] = pv.fitting.birch_murnaghan_p(volume, params['V0'], params['B0'], params['B0_prime']).tolist() fitting_results[-1]['params'] = params fitting_results[-1]['r_squared'] = fitting_result_raw['r_squared'] rmd.filedump(fitting_results, 'fitting_results.json') # a simplifed version of the file dump fitting_params = params.copy() fitting_params['r_squared'] = fitting_result_raw['r_squared'] rmd.filedump(fitting_params, 'fitting_params.json') # uncomment to make calculation faster by switching off ISPIN if possible # is_mag = rmd.detect_is_mag(mag) # if not is_mag: # incar.update({'ISPIN': 1}) V0 = params['V0'] V0_ralative_pos = (V0 - V_begin) / (V_end - V_begin) is_V0_within_valley = V0_ralative_pos > 0.4 and V0_ralative_pos < 0.6 is_range_proportional = (volume[-1] - volume[0])/V0 < 0.25 is_well_fitted = (is_V0_within_valley and is_range_proportional) return is_well_fitted, V0, structure, is_mag
force_gamma = kpoints_specs['force_gamma'] else: force_gamma = False if 'density_change' in kpoints_specs: density_change = np.array(kpoints_specs['density_change']) else: density_change = np.array(range(kpoints_specs['begin'], kpoints_specs['end'], kpoints_specs['step'])) energy = np.zeros(len(density_change)) for i, kp in enumerate(density_change): incar.write_file('INCAR') kpoints = mg.io.vasp.Kpoints.automatic_density(structure, kp, force_gamma=force_gamma) kpoints.write_file('KPOINTS') structure.to(filename='POSCAR') rmd.write_potcar(run_specs) rmd.run_vasp() oszicar = mg.io.vasp.Oszicar('OSZICAR') energy[i] = oszicar.final_energy energy /= structure.num_sites plt.plot(density_change, energy, 'o') ax = plt.gca() plt.xlabel('KPPRA') plt.ylabel('Energy (eV)') plt.tight_layout() plt.savefig('energy-kps.pdf') plt.close() np.savetxt('energy-kps.txt', np.column_stack((density_change, energy)), '%12.4f', header='kps energy') energy_relative = np.abs(np.diff(energy))
def volume_fitting(structure, is_mag, fitting_results): """ Construct a loop to get and fit the energy with changing volumes, return some indicators showing if the fit is "good" or not. """ volume = np.linspace(V_begin, V_end, V_sample_point_num) energy = np.zeros(len(volume)) mag = np.zeros(len(volume)) structures = [] for i, V in enumerate(volume): incar.write_file('INCAR') kpoints.write_file('KPOINTS') structure.scale_lattice(V) structure.to(filename='POSCAR') rmd.write_potcar(run_specs) rmd.run_vasp() oszicar = mg.io.vasp.Oszicar('OSZICAR') energy[i] = oszicar.final_energy structure = mg.Structure.from_file('CONTCAR') structures.append(structure.as_dict()) if is_mag: mag[i] = oszicar.ionic_steps[-1]['mag'] # dump in case error in fitting fitting_results.append({ 'volume': volume.tolist(), 'energy': energy.tolist(), 'mag': mag.tolist(), 'structures': structures }) rmd.filedump(fitting_results, 'fitting_results.json') # plot in case error in fitting plt.plot(volume, energy, 'o') plt.tight_layout() plt.savefig('eos_fit.pdf') plt.close() # fitting and dumping fitting_result_raw = pv.fitting.eos_fit(volume, energy, plot=True) plt.savefig('eos_fit.pdf') plt.close() params = fitting_result_raw['params'] fitting_results[-1]['pressure'] = pv.fitting.birch_murnaghan_p( volume, params['V0'], params['B0'], params['B0_prime']).tolist() fitting_results[-1]['params'] = params fitting_results[-1]['r_squared'] = fitting_result_raw['r_squared'] rmd.filedump(fitting_results, 'fitting_results.json') # a simplifed version of the file dump fitting_params = params.copy() fitting_params['r_squared'] = fitting_result_raw['r_squared'] rmd.filedump(fitting_params, 'fitting_params.json') # uncomment to make calculation faster by switching off ISPIN if possible # is_mag = rmd.detect_is_mag(mag) # if not is_mag: # incar.update({'ISPIN': 1}) V0 = params['V0'] V0_ralative_pos = (V0 - V_begin) / (V_end - V_begin) is_V0_within_valley = V0_ralative_pos > 0.4 and V0_ralative_pos < 0.6 is_range_proportional = (volume[-1] - volume[0]) / V0 < 0.25 is_well_fitted = (is_V0_within_valley and is_range_proportional) return is_well_fitted, V0, structure, is_mag