Ejemplo n.º 1
0
def run_single_point():
    logger = setup_logger(output_filename="dielectrics.log")
    structure = VaspReader(input_location='./POSCAR').read_POSCAR()
    vasp = Vasp(**single_point_pbe)
    vasp.set_crystal(structure)
    vasp.execute()
    if vasp.completed:
        logger.info("PBE self-consistent run completed properly.")
    else:
        raise Exception(
            "PBE self-consistent run failed to converge, will stop proceeding")
Ejemplo n.º 2
0
def get_total_energies(db, dir=None):
    all_zips = glob.glob(dir + "/*.zip")
    for zip in all_zips:
        kvp = {}
        data = {}
        kvp['uid'] = zip.replace(".zip", '').replace('/', '_')
        archive = zipfile.ZipFile(zip)

        atoms = None
        total_energy = None

        has_contcar = False
        for name in archive.namelist():
            if 'OSZICAR' in name:
                oszicar = archive.read(name)
                oszicar_reader = VaspReader(
                    file_content=str(oszicar).split('\\n'))
                total_energy = oszicar_reader.get_free_energies_from_oszicar(
                )[-1]
                kvp['total_energy'] = total_energy

            if 'CONTCAR' in name:
                with open('CONTCAR_temp', 'w') as f:
                    for l in str(archive.read(name)).split('\\n'):
                        f.write(l + '\n')
                has_contcar = True

        if not has_contcar:
            for name in archive.namelist():
                if 'POSCAR' in name:
                    with open('CONTCAR_temp', 'w') as f:
                        for l in str(archive.read(name)).split('\\n'):
                            f.write(l + '\n')

        crystal = ase.io.read('CONTCAR_temp', format='vasp')
        f.close()
        os.remove('CONTCAR_temp')

        if (crystal is not None) and (total_energy is not None):
            print(kvp['uid'], total_energy)
            populate_db(db, crystal, kvp, data)
Ejemplo n.º 3
0
folders = glob.glob('*' + halo + '*')

_sigma_100K = []
_sigma_300K = []

_compositions = []

_sigma_ref_300K = []

for folder in ['../CsSnI_Pnma', '../CsPbI_Pnma']:
    print(folder)
    #if not os.path.isdir(folder): continue
    os.chdir(folder)

    # get the compositions
    crystal = VaspReader(input_location="./phonon/POSCAR").read_POSCAR()
    _d = crystal.all_atoms_count_dictionaries()
    scorer = AnharmonicScore(md_frames='./vasprun_md.xml',
                             ref_frame='./phonon/POSCAR',
                             atoms=None,
                             unit_cell_frame='./phonon/POSCAR')
    __sigmas, _ = scorer.structural_sigma(return_trajectory=True)
    _sigma_ref_300K.append(__sigmas[2000:])

    os.chdir(cwd)

for folder in folders:
    if not os.path.isdir(folder): continue
    os.chdir(folder)

    # get the compositions
    def __init__(self, ref_frame=None,
                 unit_cell_frame=None,
                 md_frames=None,
                 potim=1,
                 force_constants=None,
                 supercell=[1, 1, 1],
                 primitive_matrix=[[1, 0, 0], [0, 1, 0], [0, 0, 1]],
                 atoms=None,
                 include_third_order=False,
                 third_order_fc='./phono3py/fc3.hdf5',
                 include_fourth_order=False,
                 fourth_order_fc=None,
                 force_sets_filename='FORCE_SETS',
                 mode_resolved=False):
        self.mode_resolved = mode_resolved

        if isinstance(ref_frame, Crystal):
            self.ref_frame = ref_frame
        elif ('POSCAR' in ref_frame) or ('CONTCAR' in ref_frame):
            print(ref_frame)
            print("initialising reference frame from POSCAR ")
            self.ref_frame = VaspReader(input_location=ref_frame).read_POSCAR()
            self.ref_coords = np.array([[a.scaled_position.x, a.scaled_position.y, a.scaled_position.z] for a in
                                        self.ref_frame.asymmetric_unit[0].atoms])

        self.atom_masks = None
        if atoms is not None:
            self.atom_masks = [id for id, atom in enumerate(self.ref_frame.asymmetric_unit[0].atoms) if
                               atom.label in atoms]

        if isinstance(md_frames,list):
            self.md_frames = md_frames # require the vasprun.xml containing the MD data
        elif isinstance(md_frames,str):
            self.md_frames = [md_frames]

        self.get_dft_md_forces()
        self.get_all_md_atomic_displacements()

        if isinstance(force_constants, str):
            try:
                self.phonon = phonopy.load(supercell_matrix=supercell,  # WARNING - hard coded!
                                      primitive_matrix=primitive_matrix,
                                      unitcell_filename=unit_cell_frame,
                                      force_constants_filename=force_constants)
                print("Use supercell " + str(supercell))
                print("Use primitive matrix " + str(primitive_matrix) + " done")
            except:
                self.phonon = phonopy.load(supercell_matrix=supercell,  # WARNING - hard coded!
                                      primitive_matrix='auto',
                                      unitcell_filename=unit_cell_frame,
                                      force_constants_filename=force_constants)
            print("INPUT PHONOPY force constant shape ", np.shape(self.phonon.force_constants))

            #TODO - if the input supercell is not [1,1,1], then it will need to be expanded into the correct supercell shape here!

            new_shape = np.shape(self.phonon.force_constants)[0] * np.shape(self.phonon.force_constants)[2]
            self.force_constant = np.zeros((new_shape, new_shape))
            self.force_constant = self.phonon.force_constants.transpose(0, 2, 1, 3).reshape(new_shape, new_shape)

        elif (force_constants is None):
            """
            Loading directly from SPOSCAR (supercell structure) and FORCESET to avoid problem of the need for
            reconstructing the force constants for supercells from primitive cells
            """
            print("Here try to use FORCE_SETS")

            # if we want to get the eigenvector on all atoms in the supercell, we need to specify the primitive matrix
            # as the identity matrix, making the phonopy to treat the supercell as the primitive, rather than generate them
            # automatically
            if not self.mode_resolved:
                self.phonon  = phonopy.load(supercell_filename=ref_frame, log_level=1, force_sets_filename=force_sets_filename)
            else:
                self.phonon  = phonopy.load(supercell_filename=ref_frame, log_level=1, force_sets_filename=force_sets_filename,primitive_matrix=[[1, 0, 0], [0, 1, 0], [0, 0, 1]])
            self.phonon.produce_force_constants()

            print("INPUT PHONOPY force constant shape ", np.shape(self.phonon.force_constants))
            new_shape = np.shape(self.phonon.force_constants)[0] * np.shape(self.phonon.force_constants)[2]
            self.force_constant = np.zeros((new_shape, new_shape))
            self.force_constant = self.phonon.force_constants.transpose(0, 2, 1, 3).reshape(new_shape, new_shape)
        elif isinstance(force_constants, np.ndarray):
            new_shape = np.shape(force_constants)[0] * np.shape(force_constants)[2]
            self.force_constant = np.zeros((new_shape, new_shape))
            self.force_constant = force_constants.transpose(0, 2, 1, 3).reshape(new_shape, new_shape)

        print("force constant reshape ", np.shape(self.force_constant))
        print("Force constants ready")
        self.time_series = [t * potim for t in range(len(self.all_displacements))]

        self.force_constant_3 = None
        self.include_third_oder = include_third_order
        if self.include_third_oder:
            if isinstance(third_order_fc, str):
                if os.path.isfile(third_order_fc):
                    print("Found third order force constants")
                    import h5py
                    f = h5py.File(third_order_fc)  # './phono3py/fc3.hdf5'
                    raw_force_constant_3 = np.array(f['fc3'])
            elif isinstance(third_order_fc, np.ndarray):
                raw_force_constant_3 = third_order_fc

            s = np.shape(raw_force_constant_3)[0] * 3
            self.force_constant_3 = raw_force_constant_3.transpose([0, 3, 1, 4, 2, 5]).reshape(s, s, s)
            print("Reshaped 3rd order force constant is ", np.shape(self.force_constant_3))

        self.force_constant_4 = None
        self.include_fourth_order = include_fourth_order
        if self.include_fourth_order:
            if isinstance(fourth_order_fc, np.ndarray):
                raw_force_constant_4 = fourth_order_fc
            s = np.shape(raw_force_constant_4)[0] * 3
            self.force_constant_4 = raw_force_constant_4.transpose([0, 4, 1, 5, 2, 6, 3, 7]).reshape(s, s, s, s)

        if self.mode_resolved:
            self.prepare_phonon_eigs()
    'LWAVE': False,
    'LCHARG': False,
    'LREAL': 'Auto',
    'NELM': 150,
    'NSW': 0,
    'NCORE': 48,
    'use_gw': True,
    'Gamma_centered': True,
    'MP_points': [1, 1, 1],
    'executable': 'vasp_gam'
}

pwd = os.getcwd()

# get the trajectory
all_frames = VaspReader(args.traj).read_XDATCAR()

if not args.batch:
    output = 'gap_dynamics.dat'
else:
    output = 'gap_dynamics_' + str(args.part) + '.dat'

# figure out if this is a continuing calculation
if not os.path.exists(pwd + '/' + output):
    o = open(pwd + '/' + output, 'w+')
    o.write('Frame\t VBM \t CBM \t E_f \t E_g\n')
    o.close()
    last = 0
else:
    o = open(pwd + '/' + output, 'r')
    for l in o.readlines():
Ejemplo n.º 6
0
def composition_eq_point_curve():
    cwd_1 = os.getcwd()
    labels = {
        0: 'Cs(Pb$_{x}$Sn$_{1-x})$Cl$_3$',
        1: 'Cs(Pb$_{x}$Sn$_{1-x})$Br$_3$',
        2: 'Cs(Pb$_{x}$Sn$_{1-x})$I$_3$'
    }
    colors = {
        0: '#000000',  # hex code for black
        1: '#dd0000',  # hex code for electric red
        2: '#ffce00'  # hex code for tangerine yellow
    }
    for counter, X in enumerate(['Cl', 'Br', 'I']):
        data_dict = {}
        for dir in [
                r for r in glob.glob(os.getcwd() + "/*" + str(X) + "*")
                if '.pdf' not in r
        ]:
            os.chdir(dir)
            print(dir)
            cwd_2 = os.getcwd()
            data = []
            directories = glob.glob(os.getcwd() + "/disp_111_*_0_05")
            if 'CsSnBr3_cubic' in dir:
                directories = glob.glob(os.getcwd() + "/disp_Sn_111_*_0_05")
            for sub_dir in directories:
                os.chdir(sub_dir)
                print(sub_dir)
                energy = VaspReader(input_location='./OSZICAR'
                                    ).get_free_energies_from_oszicar()[-1]
                crystal = VaspReader(input_location='./POSCAR').read_POSCAR()
                energy = energy / crystal.total_num_atoms()
                info = pickle.load(open('info.p', 'rb'))
                info['energy'] = energy
                data.append(info)
                os.chdir(cwd_2)
            os.chdir(cwd_1)
            displacements = list(sorted([d['displacement'] for d in data]))

            energy = []
            for _dis in displacements:
                for d in data:
                    if d['displacement'] == _dis:
                        energy.append(d['energy'])
            energy = [e - energy[0] for e in energy]

            x = np.array(displacements)
            y = np.array(energy)

            from scipy.optimize import curve_fit
            popt, pcov = curve_fit(pes, x, y)
            x = [0 + (0.6 / 100) * i for i in range(100)]
            y = pes(np.array(x), *popt)
            a = popt[0]
            b = popt[1]
            if 2 * a / (4 * b) > 0:
                min_x = 0
            else:
                min_x = math.sqrt(-2 * a / (4 * b))
            concentration = data[0]['concentration']
            data_dict[1.0 - concentration] = min_x
        os.chdir(cwd_1)
        x = list(sorted(data_dict.keys()))
        plt.plot(x, [data_dict[_x] for _x in x],
                 'o-',
                 c=colors[counter],
                 label=labels[counter],
                 ms=12,
                 lw=3)
    plt.legend()
    plt.xlabel('$x$ in Cs(Pb$_{x}$Sn$_{1-x}$)X$_{3}$')
    plt.ylabel('Minima on PES ($x_{\min}$, \AA)')
    plt.tight_layout()
    plt.savefig('xeq_comp_summary.pdf')
Ejemplo n.º 7
0
def make_distorted_structure(poscar,
                             direction='111',
                             max_displacement=0.6,
                             number_of_points=15,
                             lattice_deformation=0,
                             atom_to_displace=['Sn', 'Pb']):
    for counter, delta_d in enumerate([
            0 + max_displacement / number_of_points * k
            for k in range(number_of_points)
    ]):
        crystal = VaspReader(input_location=poscar).read_POSCAR()
        # expand or shrink the lattice parameters
        crystal = deform_crystal_by_lattice_expansion_coefficients(
            crystal, def_fraction=[lattice_deformation for _ in range(3)])

        d = [int(_d) for _d in list(direction)]
        displacement_vector = cVector3D(d[0], d[1], d[2]).normalise()

        # just displace the first atom that is the element that we want to displace
        _displace_vec = displacement_vector.vec_scale(delta_d)

        # _next = True

        for mol in crystal.asymmetric_unit:
            for atom in mol.atoms:
                if (atom.label in atom_to_displace):  # and (_next is True):
                    print(atom.label)
                    atom.position = atom.position + _displace_vec
                    # _next = False

        try:
            n = crystal.all_atoms_count_dictionaries()['Sn']
        except KeyError:
            n = 0

        folder_name = 'disp' + '_' + str(direction) + '_' + str(
            n) + '_str_' + str(counter) + '_a_def_' + str(
                lattice_deformation).replace('.', '_')
        cwd = os.getcwd()
        try:
            os.makedirs(cwd + '/' + folder_name)
        except:
            pass

        os.chdir(cwd + '/' + folder_name)

        _dict = crystal.all_atoms_count_dictionaries()

        if 'Sn' not in _dict.keys():
            _dict['Sn'] = 0
        if 'Pb' not in _dict.keys():
            _dict['Pb'] = 0

        system_dict = {
            'atom_to_displace': atom_to_displace,
            'concentration': _dict['Sn'] / (_dict['Sn'] + _dict['Pb']),
            'displacement': delta_d,
            'id': counter,
            'direction': direction,
            'deformation': lattice_deformation
        }
        pickle.dump(system_dict, open('info.p', 'wb'))

        VaspWriter().write_structure(crystal, 'POSCAR')
        os.chdir(cwd)
Ejemplo n.º 8
0
def get_this_pes(directory=os.getcwd()):
    cmap = matplotlib.cm.get_cmap('YlOrRd')

    cwd = os.getcwd()
    data = []
    for dir in glob.glob(directory + "/disp_*"):
        os.chdir(dir)
        try:
            energy = VaspReader(input_location='./OSZICAR'
                                ).get_free_energies_from_oszicar()[-1]
            crystal = VaspReader(input_location='./POSCAR').read_POSCAR()
            energy = energy / crystal.total_num_atoms()
            info = pickle.load(open('info.p', 'rb'))
            info['energy'] = energy
            data.append(info)
        except:
            pass
        os.chdir(cwd)

    deformations = set([d['deformation'] for d in data])
    deformations = list(sorted(deformations))
    max_def = max(deformations) + 0.0001
    max_displacement = 0

    min_x = []
    min_y = []

    for id, _def in enumerate(deformations):
        displacement = [
            d['displacement'] for d in data if d['deformation'] == _def
        ]
        displacement = list(sorted(displacement))

        energy = []
        for dis in displacement:
            for d in data:
                if (d['deformation'] == _def) and (d['displacement'] == dis):
                    energy.append(d['energy'])
        energy = [e - energy[0] for e in energy]

        x = np.array(displacement)
        y = np.array(energy)
        from scipy.optimize import curve_fit
        popt, pcov = curve_fit(pes, x, y)

        x = [0 + (0.6 / 100) * i for i in range(100)]
        y = pes(np.array(x), *popt)

        a = popt[0]
        b = popt[1]

        if 2 * a / (4 * b) > 0:
            min_x.append(0)
            min_y.append(0)
        else:
            min_x.append(math.sqrt(-2 * a / (4 * b)))
            min_y.append(pes(math.sqrt(-2 * a / (4 * b)), *popt))

        if id % 2 == 0:
            plt.plot(x,
                     y,
                     '-',
                     c=cmap((0.05 + _def) / (2 * max_def)),
                     label=str(_def * 100) + '\%',
                     lw=2)
        else:
            plt.plot(x, y, '-', c=cmap((0.05 + _def) / (2 * max_def)), lw=2)

        max_displacement = max(x)

    plt.ticklabel_format(style='sci', axis='y', scilimits=(0, 0))
    plt.plot([0, max_displacement], [0, 0], 'k--')
    plt.plot(min_x, min_y, 'o-', c='k', lw=3.5)
    plt.legend()
    plt.ylim([-0.01, 0.0150])
    plt.xlim([0, max_displacement])
    plt.xlabel('B-Cation Displacement $\Delta d$ (\AA)')
    plt.ylabel('$E-E_{\Delta d=0}$ (eV/atom)')
    plt.tight_layout()
    plt.savefig('pes.pdf')
Ejemplo n.º 9
0
def pressure_eq_point_curve():
    cwd = os.getcwd()
    labels = {
        0: 'CsPbBr$_3$',
        1: 'Cs(Pb$_{0.5}$Sn$_{0.5})$Br$_3$',
        2: 'CsSnBr$_3$'
    }
    colors = {
        0: '#000000',  # hex code for black
        1: '#dd0000',  # hex code for electric red
        2: '#ffce00'  # hex code for tangerine yellow
    }
    for counter, sys in enumerate([
            'CsPbBr3_cubic', 'mixed_CsPbSnBr3_SC_1_1_1_CsPbSnBr3_5_str_17',
            'CsSnBr3_cubic'
    ]):
        os.chdir(sys)
        this_dir = os.getcwd()
        data = []
        for dir in glob.glob("./disp_*"):

            os.chdir(dir)

            try:
                energy = VaspReader(input_location='./OSZICAR'
                                    ).get_free_energies_from_oszicar()[-1]
                crystal = VaspReader(input_location='./POSCAR').read_POSCAR()
                energy = energy / crystal.total_num_atoms()
                info = pickle.load(open('info.p', 'rb'))
                info['energy'] = energy
                data.append(info)
            except:
                pass
            os.chdir(this_dir)
        deformations = set([d['deformation'] for d in data])
        deformations = list(sorted(deformations))

        min_x = []

        for id, _def in enumerate(deformations):
            displacement = [
                d['displacement'] for d in data if d['deformation'] == _def
            ]
            displacement = list(sorted(displacement))

            energy = []
            for dis in displacement:
                for d in data:
                    if (d['deformation'] == _def) and (d['displacement']
                                                       == dis):
                        energy.append(d['energy'])
            energy = [e - energy[0] for e in energy]

            x = np.array(displacement)
            y = np.array(energy)
            from scipy.optimize import curve_fit
            popt, pcov = curve_fit(pes, x, y)

            a = popt[0]
            b = popt[1]

            if 2 * a / (4 * b) > 0:
                min_x.append(0)
            else:
                min_x.append(math.sqrt(-2 * a / (4 * b)))

        plt.plot(deformations,
                 min_x,
                 'o--',
                 label=labels[counter],
                 ms=10,
                 c=colors[counter])

        _deformations = []
        _min_x = []
        for t in range(len(min_x)):
            if (min_x[t] > 0):
                _deformations.append(deformations[t])
                _min_x.append(min_x[t])
        x = np.array(_deformations)
        y = np.array(_min_x)

        from scipy import interpolate
        f = interpolate.interp1d(x, y)
        x = np.array([
            min(_deformations) + k *
            (max(_deformations) - min(_deformations)) / 100 for k in range(100)
        ])
        y = f(x)

        from scipy.optimize import curve_fit

        popt, pcov = curve_fit(square, y, x, maxfev=2000)
        a = popt[0]
        b = popt[1]
        _y = np.array([(max(y) + 0.1 * max(y)) * k / 100 for k in range(100)])
        _x = square(_y, *popt)
        print(_x[0])
        plt.plot(_x, _y, '-', lw=2, c=colors[counter])

        os.chdir(cwd)
    plt.xlim([0.015, 0.052])
    plt.xlabel('Lattice Deformation $\delta $')
    plt.ylabel('Minima on PES ($x_{\min}$, \AA)')
    plt.legend()
    plt.tight_layout()
    plt.savefig("xeq_pressure_summary_Br.pdf")
Ejemplo n.º 10
0
def get_pes_across_composition(X='Cl'):
    cmap = matplotlib.cm.get_cmap('coolwarm')
    cwd_1 = os.getcwd()
    data_dict = {}
    min_x = []
    min_y = []
    for dir in [
            r for r in glob.glob(os.getcwd() + "/*" + str(X) + "*")
            if '.pdf' not in r
    ]:
        os.chdir(dir)
        cwd_2 = os.getcwd()
        data = []
        for sub_dir in glob.glob(os.getcwd() + "/disp_111_*_0_05"):
            os.chdir(sub_dir)
            print(sub_dir)
            energy = VaspReader(input_location='./OSZICAR'
                                ).get_free_energies_from_oszicar()[-1]
            crystal = VaspReader(input_location='./POSCAR').read_POSCAR()
            energy = energy / crystal.total_num_atoms()
            info = pickle.load(open('info.p', 'rb'))
            info['energy'] = energy
            data.append(info)
            os.chdir(cwd_2)
        os.chdir(cwd_1)

        displacements = list(sorted([d['displacement'] for d in data]))
        energy = []
        for _dis in displacements:
            for d in data:
                if d['displacement'] == _dis:
                    energy.append(d['energy'])
        energy = [e - energy[0] for e in energy]

        x = np.array(displacements)
        y = np.array(energy)
        from scipy.optimize import curve_fit
        popt, pcov = curve_fit(pes, x, y)
        x = [0 + (0.6 / 100) * i for i in range(100)]
        y = pes(np.array(x), *popt)

        a = popt[0]
        b = popt[1]

        if 2 * a / (4 * b) > 0:
            min_x.append(0)
            min_y.append(0)
        else:
            min_x.append(math.sqrt(-2 * a / (4 * b)))
            min_y.append(pes(math.sqrt(-2 * a / (4 * b)), *popt))

        data_dict[1.0 - data[0]['concentration']] = {'x': x, 'y': y}

    for k in list(sorted(data_dict.keys())):
        plt.plot(data_dict[k]['x'],
                 data_dict[k]['y'],
                 '-',
                 c=cmap(k),
                 label=str(k))
    # plt.legend(loc=2)
    plt.ticklabel_format(style='sci', axis='y', scilimits=(0, 0))
    plt.plot(min_x, min_y, 'o', c='#00743F')

    max_displacemnt = 0.6
    plt.xlim([0, max_displacemnt])
    plt.plot([0, max_displacemnt], [0, 0], 'k--')

    plt.xlabel('B-Cation Displacement $\Delta d$ (\AA)')
    plt.ylabel('$E-E_{\Delta d=0}$ (eV/atom)')
    plt.tight_layout()
    plt.savefig(X + "_B_111_landscape.pdf")