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))
Exemple #4
0
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