Пример #1
0
def gridded_energies(basename,
                     program,
                     suffix,
                     i_index,
                     j_index=None,
                     gridded=False,
                     relax=True):
    '''Read in energies from several supercells with sizes specified by <i_array>
    and <j_index>. If <j_index> == None, use <i_index> for both indices (ie. x
    and y). If <store_names> is True, keep track of output filenames for 
    '''

    energy_values = []
    if j_index is None:
        # set equal to <i_index>
        j_index = np.copy(i_index)
    elif type(j_index) == int:
        # if gridded is True, this axis will be of length one
        if gridded:
            j_index = [j_index]
        else:  # not gridded -> supplying indices raw
            # zip needs an iterable object
            j_index = j_index * np.ones(len(i_index), dtype=int)

    # read in supercell energies
    if gridded:
        for i in i_index:
            for j in j_index:
                cellname = '{}.{}.{}'.format(basename, i, j)
                Eij, units = atm.extract_energy('{}.{}'.format(
                    cellname, suffix),
                                                program,
                                                relax=relax)

                # record supercell energy
                energy_values.append([i, j, Eij, cellname])
    else:  # not gridded
        # check that i_index and j_index have the same length
        if len(i_index) != len(j_index):
            raise ValueError("i and j indices must have the same length.")

        for i, j in zip(i_index, j_index):
            cellname = '{}.{}.{}'.format(basename, i, j)
            Eij, units = atm.extract_energy('{}.{}'.format(cellname, suffix),
                                            program,
                                            relax=relax)

            if 'ry' in units.lower():  # convert to eV
                Eij = 13.60569172

            energy_values.append([i, j, Eij, cellname])

    return energy_values
Пример #2
0
def dislocationEnergySections(gulpName, outStream, currentRI):
    '''Constructs energy curve for dislocation using RI, RII, and BOTH
    output files from single point calculations. Outputs results to <outName>.
    '''
                                  
    # list of simulation regions
    simulations = ('RI', 'RII', 'BOTH')
    
    energies = dict()

    # extract energies of each individual single point calculation
    # energy of dislocated cell...
    for cellType in ('dislocated', 'perfect'):
        # create a subdictionary to hold energies of individual calculations
        energies[cellType] = dict()
        for region in simulations:
            E, units = atm.extract_energy('{}.{}.{}.gout'.format(gulpName, 
                                   cellType, region), 'gulp', relax=False)
            energies[cellType][region] = E
         
        # compute region I - region II interaction energy for polymer <cellType>    
        energies[cellType]['RIRII'] = (energies[cellType]['BOTH'] -
                    energies[cellType]['RI'] - energies[cellType]['RII'])
        # compute total energy of region I (ERI + 0.5*Einteraction)
        energies[cellType]['Etot'] = (energies[cellType]['RI'] + 
                                    0.5*energies[cellType]['RIRII'])
    
    # calculate energy of dislocation                
    eDis = energies['dislocated']['Etot'] - energies['perfect']['Etot']
        
    return eDis
def read_migration_energies(energy_dict, npoints, in_subdirectory=False):
    '''Reads in energies calculated for points along migration paths.
    '''

    heights = []
    for pair in energy_dict.keys():
        path_energies = []
        for n in range(npoints):
            prefix = 'disp.{}.{}'.format(n, pair)
            if not in_subdirectory:
                E = util.extract_energy('{}.gout'.format(prefix), 'gulp')[0]
            else:
                E = util.extract_energy('{}/{}.gout'.format(prefix, prefix),
                                        'gulp')[0]

            path_energies.append(E)

        path_energies = np.array(path_energies)
        path_energies -= path_energies[0]
        Eh = get_barrier(path_energies)

        # produce output
        outstream = open('disp.{}.barrier.dat'.format(pair), 'w')
        # write the components of (a) the initial site, (b) the final site, and
        # (c) the vector from one to the other
        x0 = energy_dict[pair]['x0']
        x1 = energy_dict[pair]['x1']
        dx = x1 - x0
        outstream.write('# x0: {:.3f} {:.3f} {:.3f}\n'.format(
            x0[0], x0[1], x0[2]))
        outstream.write('# x1: {:.3f} {:.3f} {:.3f}\n'.format(
            x1[0], x1[1], x1[2]))
        outstream.write('# dx: {:.3f} {:.3f} {:.3f}\n'.format(
            dx[0], dx[1], dx[2]))

        # write energies at each point along the migration path
        for z, E in zip(energy_dict[pair]['grid'], path_energies):
            outstream.write('{} {:.6f}\n'.format(z, E))

        outstream.close()

        # get the indices of start and final sites
        i, j = [int(index) for index in pair.split('.')[-2:]]
        heights.append([i, j, x1[0], x1[1], Eh, path_energies[-1]])

    return np.array(heights)
Пример #4
0
def get_energies(basename, site_info, program='gulp', suffix='gout'):
    '''Extracts energies of defected simulation cells from GULP output files.
    '''

    # extract energy from GULP output files corresponding to each index in
    # <site_info>
    energies = []
    for site in site_info:
        simname = '{}.{}.{}'.format(basename, int(site[0]), suffix)
        E, units = atm.extract_energy(simname, program)
        energies.append(E)

    return energies
Пример #5
0
def dislocation_energy_edge(base_name, outStream, currentRI, newRI, E_atoms):
    '''Calculate energy using atomic energies. As the edge dislocation setup code
    is non-conservative, the use of this method is mandatory for edge dislocations.
    '''
                                  
    # list of simulation regions
    simulations = ('RI', 'RII', 'BOTH')
    
    energies = dict()
    
    # extract energies from single point calculations
    ERI, units = atm.extract_energy('{}.RI.gout'.format(base_name), 'gulp', relax=False)
    ERII, units = atm.extract_energy('{}.RII.gout'.format(base_name), 'gulp', relax=False)
    EBoth, units = atm.extract_energy('{}.BOTH.gout'.format(base_name), 'gulp', relax=False)
    total_E_RI = ERI + 0.5*(EBoth - (ERI+ERII))
    
    # calculate energy of equivalent number of atoms in perfect crystal
    E_perfect = 0.0        
    for atom in newRI:
        E_perfect += E_atoms[atom.getSpecies()]
            
    eDis = total_E_RI - E_perfect
    
    return eDis
def read_migration_barrier(sitename, npoints, program='gulp'):
    '''Extracts the energies for points along the migration path of an individual
    defect near a dislocation line. The variable <program> is future-proofing.
    '''

    energies = []
    for i in range(npoints):
        energies.append(
            util.extract_energy('disp.{}.{}.gout'.format(i, sitename),
                                program)[0])

    # shift energies so that the undisplaced defect is at 0 eV
    energies = np.array(energies)
    energies -= energies.min()

    # reorder barrier so that the index of the minimum energy point is 0
    return energies
Пример #7
0
def get_gsf_energy(base_name, program, suffix, i, j=None, indir=False, relax=True,
                                                                       gnorm=10.):
    '''Extracts calculated energy from a generalized stacking fault calculation
    using the regular expression <energy_regex> corresponding to the code used
    to calculate the GSF energy.

    Set argument indir to True if mkdir was True in gsf_setup.
    '''
    
    # construct name of GSF file
    name_format = '{}.{}'.format(base_name, i)
    if j is not None: # gamma surface, need x and y indices
        name_format += '.{}'.format(j)
        
    # check if individual calculations are in their own directories
    if indir:
        filename = '{}/{}.{}'.format(name_format, name_format, suffix)
    else:
        filename = '{}.{}'.format(name_format, suffix)
        
    # read in energies
    E, units = atm.extract_energy(filename, program, relax=relax, acceptable_gnorm=gnorm)
    
    return E, units