Exemple #1
0
def neb_analysis(cl,
                 show,
                 up=None,
                 push2archive=None,
                 old_behaviour=None,
                 results_dic=None,
                 fitplot_args=None,
                 style_dic=None,
                 params=None):
    """
    Analyse traectories and polarons

    params
        mep_shift_vector
    """
    def determing_rms_for_surrounding_atoms(sts):
        # change of rms on each step compared to first structure
        #here first and last structures should correspond to first and last images

        st1 = sts[0]

        st_interp = interpolate(sts[0], sts[-1], 1)[0]
        rms_list = []

        for st in sts:
            rms = rms_pos_diff(st_interp, st)
            rms_list.append(rms)
            print('rms is {:.3f}'.format(rms))

        print('d rms is {:.3f}'.format(abs(rms_list[3] - rms_list[0])))

        rms_change = abs(min(rms_list) - max(rms_list))

        return rms_change

    def determing_born_barrier(sts):
        #here first and last structures should correspond to first and last images
        local_born_e = []
        i = find_moving_atom(sts[0], sts[-1])

        for st in sts:
            local_born_e.append(site_repulsive_e(st, i))

        # import matplotlib.pyplot as plt
        # plt.plot(local_born_e)
        # plt.show()

        return abs(min(local_born_e) - max(local_born_e))

    if params is None:
        params = {}

    if results_dic is None:

        results_dic = {}

    calc = header.calc
    path2mep_s = cl.project_path_cluster + '/' + cl.dir + '/mep.eps'
    itise = cl.id[0] + '.' + cl.id[1]
    # print(cl.ldauu)
    # sys.exit()
    name_without_ext = 'mep.' + itise + '.U' + str(max(cl.ldauu))
    path2mep_l = cl.dir + name_without_ext + '.eps'
    # print(path2mep_l)
    if not os.path.exists(path2mep_l) or '2' in up:
        ''
        get_from_server(
            files=path2mep_s,
            to_file=path2mep_l,
            addr=cl.cluster_address,
        )
        movie_to = cl.dir + '/movie.xyz'
        get_from_server(
            files=cl.project_path_cluster + '/' + cl.dir + '/movie.xyz',
            to_file=movie_to,
            addr=cl.cluster_address,
        )

        if os.path.exists(movie_to):
            makedir('figs/' + name_without_ext + '.xyz')
            shutil.copyfile(movie_to, 'figs/' + name_without_ext + '.xyz')

    # trying to get one image closest to the saddle point
    if old_behaviour and cl.version == 2:  #old behaviour, now created automatically in add callc
        im = cl.set.vasp_params['IMAGES']
        # if im % 2 > 0: #odd
        #     i = im//2 + 1
        # else:
        #     i = im/2
        # if choose_image:
        #     i = choose_image

        for i in range(im):
            i += 1
            cl_i = copy.deepcopy(cl)
            cl_i.version += i
            cl_i.id = (cl.id[0], cl.id[1], cl_i.version)
            cl_i.name = str(cl_i.id[0]) + '.' + str(cl_i.id[1]) + '.' + str(
                cl_i.id[2])
            # print cl_i.name
            cl_i.path["output"] = cl_i.dir + '0' + str(i) + "/OUTCAR"
            # for i in range():

            cl_i.associated_outcars = [
                aso[2:] for aso in cl_i.associated_outcars
            ]

            # print cl_i.path["output"]
            cl_i.state = '2. Ready to read outcar'
            # if not os.path.exists(cl_i.path["output"]):
            #     load = 'o'
            outst2 = ("%s" % cl_i.name).ljust(name_field_length)
            if readfiles:
                print(outst2 + '|' + cl_i.read_results(
                    loadflag, show=show, choose_outcar=choose_outcar))
            else:
                print_and_log(outst2 + ' | File was not read')

            if cl_i.id in calc:  #move creation of calcs with images to add_neb
                ''
                # print_and_log('Please test code below this message to save prev calcs')
                # if cl_i != calc[cl_i.id]
                #     if hasattr(calc[cl_i.id], 'prev') and calc[cl_i.id].prev:
                #         prevlist = calc[cl_i.id].prev
                #     else:
                #         prevlist = [calc[cl_i.id]]
                #     cl_i.prev = prevlist
                #     calc[cl_i.id] = cl_i
            else:
                calc[cl_i.id] = cl_i

    # print path2mep_l
    if 0:
        if os.path.exists(path2mep_l):
            # get_from_server(file = path2mep_s, to = path2mep_l, addr = cluster_address)

            runBash('evince ' + path2mep_l)
        else:
            a = glob.glob(cl.dir + '*mep*')
            if a:
                runBash('evince ' + a[0])

    cl1 = calc[cl.id[0], cl.id[1], 1]

    cl2 = calc[cl.id[0], cl.id[1], 2]

    atom_num = find_moving_atom(cl1.end, cl2.end)
    # cl1.poscar()
    # cl2.poscar()

    # print('atom_num',atom_num)
    # sys.exit()

    #prepare lists
    ni = cl.set.vasp_params['IMAGES']
    vlist = [1] + list(range(3, ni + 3)) + [2]
    # print( vlist)
    mep_energies = []
    atom_pos = []

    pols = []
    sts = []
    sts_loc = []
    dAO2 = []  # A-(O,F) distance for each image
    dAO4 = []  # A-(O,F) distance for each image
    dAO6 = []
    dAO6harm = []
    dAO6dev = []

    for v in vlist:
        cli = calc[cl.id[0], cl.id[1], v]
        # if v == 1:
        #     cli = db['NaVP2O7_a.su.s101015v100.n5Na1v1ms.ifn.1mls.1']

        # print(cl.id[0], cl.id[1], v, cli.state)
        if '4' not in cli.state and 'un' not in up:
            printlog('Attention! res_loop(): analys_type == neb, Calc', cli.id,
                     'is not finished; return')
            return {}, []
        # print cli.id
        # cli.end = return_to_cell(cli.end)
        # mep_energies.append(  min(cli.list_e_sigma0)   ) #use minimum energy - not very good, sometimes unconverged energy could be lower!

        e0 = cli.energy_sigma0
        if params and params.get(
                'neb_penult_e'
        ):  # allows to take  e from the previous relaxation step in case the calculation was aborted
            e0 = cli.list_e_sigma0[-2]

        mep_energies.append(e0)  #use last energy
        atom_pos.append(cli.end.xcart[atom_num])

        # Find polaron positions
        if 'polaron' in show:  # if 1 cause error for nomag calc
            pol, mag = find_polaron(cli.end, atom_num)
            if pol:
                for key in pol:
                    if np.any(pol[key]):
                        for n in pol[key]:
                            if n not in pols:
                                pols.append(n)
            else:
                ''
                # print('Mag_moments on trans,', mag.round(1))

        if 0 or 'neb_geo' in show:
            #visualization of path
            # print(atom_num)
            st = copy.deepcopy(cli.end)
            # print('moving_atom', st.xcart[atom_num])
            info = st.nn(atom_num, 15, from_one=False, silent=1)

            st.moving_atom_i = atom_num
            st_loc = info['st']

            # print(st_loc.xcart)
            # st_loc = st_loc.shift

            if v == vlist[0]:

                st1 = copy.deepcopy(st)

                vec = st.center_on(atom_num)
                # vec = np.asarray([0.,0.,0.])

                if params is not None and 'mep_shift_vector' in params:
                    # vec += np.array([0.11,0.11,0]) # path4
                    # print(params['mep_shift_vector'])
                    vec += np.array(params['mep_shift_vector'])  # path4

            # print(vec)
            st_loc = st_loc.shift_atoms(vec)
            if 0:
                st_loc.write_xyz()
            # st.write_cif('xyz/'+st.name)
            if 0:
                st.shift_atoms(vec).write_xyz()

            sts_loc.append(st_loc)

            st1 = st1.add_atom(st.xred[atom_num], 'Rb')

            sts.append(st.shift_atoms(vec))

            if 0 or 'neb_geo2' in show:
                printlog('\n\nVersion {:}:'.format(v), imp='y')
                info1 = st.nn(atom_num,
                              2,
                              from_one=False,
                              silent=1,
                              more_info=1)
                print('Av.         dist  A-2(O,F) {:.3f} A'.format(
                    info1['av(A-O,F)']))
                # print('Av. squared dist  A-2(O,F) {:.3f} A'.format(info1['avsq(A-O,F)']))
                dAO2.append(info1['av(A-O,F)'])

                info12 = st.nn(atom_num, 3, from_one=False, silent=1)
                print('Average distance  A-3(O,F) {:.2f} A'.format(
                    info12['av(A-O,F)']))

                info2 = st.nn(atom_num, 4, from_one=False, silent=1)
                print('Average distance  A-4(O,F) {:.2f} A'.format(
                    info2['av(A-O,F)']))
                dAO4.append(info2['av(A-O,F)'])

                info3 = st.nn(atom_num,
                              6,
                              from_one=False,
                              silent=1,
                              more_info=1)
                print('Average_distance  A-6(O,F) {:.2f} A '.format(
                    info3['av(A-O,F)']))
                print('Av. harm.   dist  A-6(O,F) {:.2f} A'.format(
                    info3['avharm(A-O,F)']))
                print('Average_deviation A-6(O,F) {:.1f} mA'.format(
                    info3['avdev(A-O,F)']))
                dAO6.append(info3['av(A-O,F)'])
                dAO6dev.append(info3['avdev(A-O,F)'])
                dAO6harm.append(info3['avharm(A-O,F)'])

    if 'neb_rms' in show:
        rms_change = determing_rms_for_surrounding_atoms(sts)
        results_dic['rms_change'] = rms_change

    if 'neb_born' in show:
        results_dic['born_barrier'] = determing_born_barrier(sts)
        print('Born barrier is {:.2f} eV '.format(results_dic['born_barrier']))

    # print(results_dic['rms_change'])
    # print('show is', show)
    # sys.exit()

    # print('flag ', 'neb_noxyz' not in show, show)
    if 'neb_noxyz' not in show and sts:
        write_xyz(sts=sts)  # write traectory
        write_xyz(sts=sts_loc)  # write traectory

        if 'jmol' in params:
            write_xyz(sts=sts, jmol=1, jmol_args=params['jmol'])  # write jmol

        st1 = st1.shift_atoms(vec)
        st1.name += '_all'
        # st1.write_cif('xyz/'+st1.name)
        st1.write_xyz()

    if dAO2:  # find maximum change of distance during migration
        dAO2_change = abs(min(dAO2) - max(dAO2))
        results_dic['dAO2_change'] = dAO2_change
    if dAO4:  # find maximum change of distance during migration
        dAO4_change = abs(min(dAO4) - max(dAO4))
        results_dic['dAO4_change'] = dAO4_change
    if dAO6:  #
        dAO6_change = abs(min(dAO6) - max(dAO6))
        results_dic['dAO6_change'] = dAO6_change
    if dAO6harm:  #
        results_dic['dAO6harm_change'] = abs(min(dAO6harm) - max(dAO6harm))
    if dAO6dev:  #
        results_dic['dAO6dev_change'] = abs(min(dAO6dev) - max(dAO6dev))

    results_dic[
        'sts_loc'] = sts_loc  # list of local structures, each structure contains dlist - distances from central cation to anions, and ellist - types of elements
    results_dic[
        'sts'] = sts  # list of mep structures, each structure contains moving_atom_i - number of moving atom

    if len(pols) > 0:
        print(
            'During migration of alkali ions polarons are detected on atoms:',
            pols)
    elif len(pols) > 1:
        printlog(
            'Attention! polaron is moving during migration! Obtained barrier is ambiguous'
        )
    else:
        printlog(
            'Compare magnetic moments above! In principle should be the same!')

    # print np.array(atom_pos)

    #test if the distances between points are not spoiled by PBC
    nbc = range(-1, 2)
    jj = 0
    for x in atom_pos:

        x2 = atom_pos[jj + 1]
        # x = np.array(x)
        # x2 = np.array(x2)
        r = cl.end.rprimd
        d1, _ = image_distance(x, x2, r, order=1)  #minimal distance
        x2_gen = (x2 + (r[0] * i + r[1] * j + r[2] * k) for i in nbc
                  for j in nbc for k in nbc)  #generator over PBC images
        x2c = copy.deepcopy(x2)
        ii = 0
        while np.linalg.norm(x -
                             x2c) > d1:  #find the closest PBC image position
            if ii > 100:
                break
            ii += 1
            x2c = next(x2_gen)
        atom_pos[jj + 1] = x2c
        jj += 1
        if jj == len(
                atom_pos
        ) - 1:  # the last point is not needed, we could not use slice since we need to use changed atom_pos in place
            break
        # print np.linalg.norm(x - x2c), d1

    _, diff_barrier = plot_mep(atom_pos,
                               mep_energies,
                               plot=0,
                               show=0,
                               fitplot_args=fitplot_args,
                               style_dic=style_dic)

    results_dic['barrier'] = diff_barrier

    middle_image = len(vlist) // 2
    results_dic['dEm1'] = mep_energies[middle_image] - mep_energies[0]

    cl1.barrier = diff_barrier
    cl2.barrier = diff_barrier

    results_dic['atom_pos'] = [list(pos) for pos in atom_pos]
    results_dic['mep_energies'] = mep_energies

    if 'mep' in show:
        if 'mepp' in show:
            show_flag = True
        else:
            show_flag = False
        # sys.exit()

        plot_mep(atom_pos,
                 mep_energies,
                 image_name='figs/' + name_without_ext + '_my.eps',
                 show=show_flag,
                 fitplot_args=fitplot_args,
                 style_dic=style_dic)

    if push2archive:
        path2saved, _ = plot_mep(atom_pos,
                                 mep_energies,
                                 image_name='figs/' + name_without_ext + '_my',
                                 fitplot_args=fitplot_args,
                                 style_dic=style_dic)
        push_figure_to_archive(local_figure_path=path2saved,
                               caption=description_for_archive)

        if 0:  #copy files according to chosen outcar to run nebresults locally
            wd = cl_i.dir
            out_i = cl_i.associated_outcars[choose_outcar - 1]
            out_1 = calc[cl.id[0], cl.id[1],
                         1].associated_outcars[choose_outcar - 1]
            out_2 = calc[cl.id[0], cl.id[1],
                         2].associated_outcars[choose_outcar - 1]
            # print out_1
            # print out_2
            shutil.copyfile(wd + out_1, wd + '00/OUTCAR')
            shutil.copyfile(wd + out_2, wd + '04/OUTCAR')
            for d in ['01/', '02/', '03/']:
                shutil.copyfile(wd + d + out_i, wd + d + 'OUTCAR')

                # print wd+d+out_i

    return results_dic
Exemple #2
0
def fit_a(conv, n, description_for_archive, analysis_type, show, push2archive):
    """Fit equation of state for bulk systems.

    The following equation is used::

       sjeos (default)
           A third order inverse polynomial fit 10.1103/PhysRevB.67.026103

                           2      3        -1/3
       E(V) = c + c t + c t  + c t ,  t = V
               0   1     2      3

       taylor
           A third order Taylor series expansion about the minimum volume

       murnaghan
           PRB 28, 5480 (1983)

       birch
           Intermetallic compounds: Principles and Practice,
           Vol I: Principles. pages 195-210

       birchmurnaghan
           PRB 70, 224107

       pouriertarantola
           PRB 70, 224107

       vinet
           PRB 70, 224107

       antonschmidt
           Intermetallics 11, 23-32 (2003)

       p3
           A third order polynomial fit

        Use::

           eos = EquationOfState(volumes, energies, eos='sjeos')
           v0, e0, B = eos.fit()
           eos.plot()

    """
    # e, v, emin, vmin       = plot_conv( conv[n], calc,  "fit_gb_volume2")

    alist = []
    vlist = []
    etotlist = []
    magn1 = []
    magn2 = []
    alphas = []
    for id in conv[n]:
        cl = db[id]
        st = cl.end
        alist.append(cl.end.rprimd[0][0])
        etotlist.append(cl.energy_sigma0)
        vlist.append(cl.end.vol)
        magn1.append(cl.magn1)
        magn2.append(cl.magn2)
        alpha, beta, gamma = st.get_angles()
        alphas.append(alpha)
        print('alpha, energy: {:4.2f}, {:6.3f}'.format(alpha,
                                                       cl.energy_sigma0))

    fit_and_plot(U1=(alphas, etotlist, 'o-r'),
                 image_name='figs/angle',
                 ylabel='Total energy, eV',
                 xlabel='Angle, deg',
                 xlim=(89, 92.6))

    if ase_flag:
        if 'angle' in analysis_type:
            eos = EquationOfState(alphas, etotlist, eos='sjeos')
        else:
            eos = EquationOfState(vlist, etotlist, eos='sjeos')
        # import inspect

        # print (inspect.getfile(EquationOfState))

        v0, e0, B = eos.fit()
        #print "c = ", clist[2]
        printlog('''
        v0 = {0} A^3
        a0 = {1} A
        E0 = {2} eV
        B  = {3} eV/A^3'''.format(v0, v0**(1. / 3), e0, B),
                 imp='Y')

        savedpath = 'figs/' + cl.name + '.png'
        makedir(savedpath)

        cl.B = B * 160.218
        # plt.close()
        # plt.clf()
        # plt.close('all')
        if 'fit' in show:
            mpl.rcParams.update({'font.size': 14})

            eos.plot(savedpath, show=True)
            printlog('fit results are saved in ', savedpath, imp='y')
        else:
            printlog('To use fitting install ase: pip install ase')
    # plt.clf()

    if push2archive:
        push_figure_to_archive(local_figure_path=savedpath,
                               caption=description_for_archive)

    return