Run convergence test with changing kpoints subdivision values, and plot figures. You should set a 'kpoints_test' tag in the specs file, like kpoints_test: density_change: [1000, 2000, 4000] force_gamma: True Obviously, 'kpoints' tag should be omitted. """ run_specs, filename = rmd.get_run_specs_and_filename() rmd.chdir(rmd.get_run_dir(run_specs)) rmd.filedump(run_specs, filename) rmd.init_stdout() rmd.infer_from_json(run_specs) structure = rmd.get_structure(run_specs) incar = rmd.read_incar(run_specs) kpoints_specs = run_specs['kpoints_test'] if 'force_gamma' in kpoints_specs: 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:
structures will be concatenated and sorted according to the volume value. If you set a 'slice' tag in the under the tag 'phonopy', like phonopy: volumes_and_structures: slice: [null, -4] The slice is applied to the volume and structure list. """ run_specs, filename = rmd.get_run_specs_and_filename() cwd = os.getcwd() rmd.chdir(rmd.get_run_dir(run_specs)) rmd.filedump(run_specs, filename) phonopy_specs = run_specs['phonopy'] phonopy_specs['dim'] = ' '.join(map(str, phonopy_specs['dim'])) incar = rmd.read_incar(run_specs) if os.path.isfile('../properties.json'): properties = rmd.fileload('../properties.json') if 'ISPIN' not in incar: if rmd.detect_is_mag(properties['mag']): incar.update({'ISPIN': 2}) else: incar.update({'ISPIN': 1}) # higher priority for run_specs if 'poscar' in run_specs: structure = rmd.get_structure(run_specs)
sample_point_num: 5 In this case, an intial run will take action and obtain the fitting parameters and find the correct volumes corresponding to the given pressure range. A second run is done using those volume values. the tag 'skip_test_run' tells the code to just use the fitting_params.json in the working directory without doing the test run. If 'dump_to_json' exists in the specs file and is set to a path, output some important results to that file. """ run_specs, filename = rmd.get_run_specs_and_filename() rmd.chdir(rmd.get_run_dir(run_specs)) rmd.filedump(run_specs, filename) rmd.init_stdout() rmd.infer_from_json(run_specs) structure = rmd.get_structure(run_specs) incar = rmd.read_incar(run_specs) kpoints = rmd.read_kpoints(run_specs, structure) is_mag = incar['ISPIN'] == 2 if 'ISPIN' in incar else False if 'volume' in run_specs and run_specs['volume']: volume_params = run_specs['volume'] V_begin = volume_params['begin'] V_end = volume_params['end'] V_sample_point_num = volume_params['sample_point_num'] else:
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
energy values from each strain set to a polynomial, extract the parameters and plot figures, and then linearly solve for the elastic constants. The strain sets used to solve the elastic constants are detailed in run_module_elastic.py. You should set a 'elastic' tag in the specs file, like elastic: cryst_sys: cubic """ run_specs, filename = rmd.get_run_specs_and_filename() rmd.chdir(rmd.get_run_dir(run_specs)) rmd.filedump(run_specs, filename) cryst_sys = run_specs['elastic']['cryst_sys'] rmd.infer_from_json(run_specs) structure = rmd.get_structure(run_specs) incar = rmd.read_incar(run_specs) kpoints = rmd.read_kpoints(run_specs, structure) is_mag = incar['ISPIN'] == 2 if 'ISPIN' in incar else False fitting_results_summary = {} rmd.chdir('nostrain') rmd.init_stdout() incar.write_file('INCAR')
like elastic: num_norm: 2 num_shear: 2 After the set of VASP runs, you need to use the process script process_elastic_stress_strain to solve for the elastic constants. """ # pre-config run_specs, filename = rmd.get_run_specs_and_filename() cwd = os.getcwd() rmd.chdir(rmd.get_run_dir(run_specs)) rmd.filedump(run_specs, filename) # read settings incar = rmd.read_incar(run_specs) structure = rmd.get_structure(run_specs) kpoints = rmd.read_kpoints(run_specs, structure) # elastic if 'elastic' in run_specs and ('num_norm' in run_specs['elastic'] or 'num_shear' in run_specs['elastic']): dss = elasticity.strain.DeformedStructureSet(structure, num_norm=run_specs['elastic']['num_norm'], num_shear=run_specs['elastic']['num_shear']) else: dss = elasticity.strain.DeformedStructureSet(structure) strain_list = [i.green_lagrange_strain for i in dss.deformations] rmd.filedump([i.tolist() for i in strain_list], 'strain_list.json') for idx, defo in enumerate(dss.deformations): rmd.chdir(str(idx))
rmd.chdir(test_type) energy = np.zeros(len(delta)) mag = np.zeros(len(delta)) for ind, value in enumerate(delta): rmd.chdir(str(value)) oszicar = mg.io.vasp.Oszicar('OSZICAR') energy[ind] = oszicar.final_energy if is_mag: mag[ind] = oszicar.ionic_steps[-1]['mag'] os.chdir('..') fitting_results = pydass_vasp.fitting.curve_fit(rmd_e.central_poly, delta, energy, plot=True) plt.savefig(test_type + '.pdf') plt.close() fitting_results['params'] = fitting_results['params'].tolist() fitting_results.pop('fitted_data') fitting_results.pop('ax') fitting_results['delta'] = delta.tolist() fitting_results['energy'] = energy.tolist() fitting_results['mag'] = mag.tolist() rmd.filedump(fitting_results, 'fitting_results.json') # higher level fitting_results.json if os.path.isfile('../fitting_results.json'): fitting_results_summary = rmd.fileload('../fitting_results.json') else: fitting_results_summary = {} fitting_results_summary[test_type] = fitting_results rmd.filedump(fitting_results_summary, '../fitting_results.json') shutil.copy(test_type + '.pdf', '..') os.chdir('..')
Not a VASP run script that requires a job submission. You can directly use it as python INPUT/process_elastic_stress_strain.py INPUT/run_elastic_stress_strain.yaml to read a specs file at INPUT/run_elastic_stress_strain.yaml, which is the file you used to actually run the routine script run_elastic_stress_strain.py before this. """ # pre-config run_specs, filename = rmd.get_run_specs_and_filename() rmd.chdir(rmd.get_run_dir(run_specs)) rmd.filedump(run_specs, filename) rmd.init_stdout() # read settings structure = rmd.get_structure(run_specs) # elastic strain_list = [i for i in rmd.fileload('strain_list.json')] stress_list = [] for idx, strain in enumerate(strain_list): vasprun = mg.io.vasp.Vasprun(str(idx) + '/vasprun.xml') stress_list.append( elasticity.stress.Stress(vasprun.ionic_steps[-1]['stress']) / -10) rmd.filedump([i.tolist() for i in stress_list], 'stress_list.json') elastic_tensor = elasticity.elastic.ElasticTensor.from_strain_stress_list(
skip_test_run: True begin: -1 end: 50 sample_point_num: 5 In this case, an intial run will take action and obtain the fitting parameters and find the correct volumes corresponding to the given pressure range. A second run is done using those volume values. the tag 'skip_test_run' tells the code to just use the fitting_params.json in the working directory without doing the test run. """ run_specs, filename = rmd.get_run_specs_and_filename() rmd.chdir(rmd.get_run_dir(run_specs)) rmd.filedump(run_specs, filename) rmd.init_stdout() incar = rmd.read_incar(run_specs) is_properties = None if os.path.isfile(('../properties.json')): is_properties = True properties = rmd.fileload('../properties.json') if 'ISPIN' in incar: is_mag = incar['ISPIN'] == 2 elif is_properties: is_mag = rmd.detect_is_mag(properties['mag']) if is_mag: incar.update({'ISPIN': 2}) else:
run_specs, filename = rmd.get_run_specs_and_filename() rmd.chdir(rmd.get_run_dir(run_specs)) cryst_sys = run_specs['elastic']['cryst_sys'] is_properties = None if os.path.isfile(('../properties.json')): is_properties = True properties = rmd.fileload('../properties.json') # higher priority for run_specs if 'poscar' in run_specs: structure = rmd.get_structure(run_specs) elif os.path.isfile('../POSCAR'): structure = mg.Structure.from_file('../POSCAR') rmd.insert_elem_types(run_specs, structure) test_type_list, strain_list, delta_list = rmd_e.get_test_type_strain_delta_list(cryst_sys) fitting_results_summary = rmd.fileload('fitting_results.json') # fitting_results_summary['c11+2c12'] = {} # fitting_results_summary['c11+2c12']['params'] = [properties['B0'] * structure.volume / 160.2 * 9/2.] combined_econst_array = [fitting_results_summary[test_type]['params'][0] for test_type in test_type_list] combined_econst_array = np.array(combined_econst_array) * 160.2 / structure.volume solved = rmd_e.solve(cryst_sys, combined_econst_array) rmd.filedump(solved, 'elastic.json') if is_properties: properties['elastic'] = solved rmd.filedump(properties, '../properties.json')
elastic: cryst_sys: cubic test_type: c11-c12 The 'test_type' tag defines the name of the strain set, whose mathematical form is detailed in run_module_elastic.py. After this kind of VASP run for for all the independent strain sets, you need to use the process script process_elastic_solve.py to obtain the elastic constants. """ run_specs, filename = rmd.get_run_specs_and_filename() rmd.chdir(rmd.get_run_dir(run_specs)) rmd.filedump(run_specs, filename) cryst_sys = run_specs['elastic']['cryst_sys'] test_type_input = run_specs['elastic']['test_type'] rmd.infer_from_json(run_specs) structure = rmd.get_structure(run_specs) incar = rmd.read_incar(run_specs) kpoints = rmd.read_kpoints(run_specs, structure) is_mag = incar['ISPIN'] == 2 if 'ISPIN' in incar else False test_type_list, strain_list, delta_list = rmd_e.get_test_type_strain_delta_list(cryst_sys) for test_type, strain, delta in zip(test_type_list, strain_list, delta_list): if test_type == test_type_input: rmd.chdir(test_type)
elastic: cryst_sys: cubic test_type: c11-c12 The 'test_type' tag defines the name of the strain set, whose mathematical form is detailed in run_module_elastic.py. After this kind of VASP run for for all the independent strain sets, you need to use the process script process_elastic_solve.py to obtain the elastic constants. """ run_specs, filename = rmd.get_run_specs_and_filename() rmd.chdir(rmd.get_run_dir(run_specs)) rmd.filedump(run_specs, filename) cryst_sys = run_specs['elastic']['cryst_sys'] test_type_input = run_specs['elastic']['test_type'] rmd.infer_from_json(run_specs) structure = rmd.get_structure(run_specs) incar = rmd.read_incar(run_specs) kpoints = rmd.read_kpoints(run_specs, structure) is_mag = incar['ISPIN'] == 2 if 'ISPIN' in incar else False test_type_list, strain_list, delta_list = rmd_e.get_test_type_strain_delta_list( cryst_sys) for test_type, strain, delta in zip(test_type_list, strain_list, delta_list):
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