Example #1
0
def fixOverlap(clus_to_fix):
    """
    Support function to fix any overlaps that may arise due to the mutations by radially moving the atoms that have overlap
    """
    natoms = len(clus_to_fix)
    CoM(clus_to_fix)
    for i in range(natoms):
        for j in range(i):
            r1 = np.array(clus_to_fix[j].position)
            r2 = np.array(clus_to_fix[i].position)
            rij = r2 - r1
            distance = np.sqrt(np.dot(rij, rij))
            dmin = (covalent_radii[clus_to_fix[i].number] +
                    covalent_radii[clus_to_fix[j].number]) * 0.9
            if distance < 0.9 * dmin:
                a = np.dot(r2, r2)
                b = np.dot(r1, r2)
                c = np.dot(r1, r1) - dmin**2
                alpha = 1.000001 * (b + np.sqrt(b * b - a * c)) / a
                clus_to_fix[i].x *= alpha
                clus_to_fix[i].y *= alpha
                clus_to_fix[i].z *= alpha
    clus_to_fix.center(vacuum=9)
    clus_to_fix_sorted = sort(clus_to_fix)
    clus_to_fix_sorted.pbc = (True, True, True)
    clus_to_fix_sorted.calc = EMT()
    dyn = BFGS(clus_to_fix_sorted, logfile=None)
    dyn.run(fmax=0.05, steps=1000)
    return clus_to_fix_sorted
Example #2
0
def fixOverlap(clus_to_fix):
   '''
   Support function to fix any overlaps that may arise due to the mutations by radially moving the atoms that have overlap
   '''
   natoms = len(clus_to_fix)
   #com = clus_to_fix.get_center_of_mass()
   #clus_to_fix.center(about = com)
   CoM(clus_to_fix)
   for i in range(natoms):
	   for j in range(i):
		   r1 = np.array(clus_to_fix[j].position)
		   r2 = np.array(clus_to_fix[i].position)
		   rij = r2 - r1
		   distance = np.sqrt(np.dot(rij, rij))
		   dmin = (covalent_radii[clus_to_fix[i].number] + covalent_radii[clus_to_fix[j].number])*0.7
		   if distance < 0.8 * dmin:
			   a = np.dot(r2, r2)
			   b = np.dot(r1, r2)
			   c = np.dot(r1, r1) - dmin**2
			   alpha = 1.000001 * (b + np.sqrt(b * b - a * c)) / a
			   clus_to_fix[i].x *= alpha
			   clus_to_fix[i].y *= alpha
			   clus_to_fix[i].z *= alpha
   clus_to_fix.center(vacuum=9)
   clus_to_fix_sorted = sort(clus_to_fix)
   clus_to_fix_sorted.pbc = (True, True, True)
   return clus_to_fix_sorted
Example #3
0
def parse_traj(structure_file):
    from ase.build import sort
    from ase.io.trajectory import Trajectory
    data = []
    out_traj = Trajectory(structure_file)

    for traj in out_traj:
        structure = sort(traj)
        energy = traj.get_potential_energy()
        force = traj.get_forces()
        try:
            # PyXtal_FF: XX  YY  ZZ  XY  XZ  YZ
            # ASE      : xx  yy  zz  yz  xz  xy
            # eV/A^3 to GPa
            stress = -(traj.get_stress() / units.GPa)[[0, 1, 2, 5, 4, 3]]
        except:
            stress = None
        xjson = {
            'structure': structure,
            'energy': energy,
            'force': force,
            'stress': stress,
            'group': 'random'
        }
        data.append(xjson)

    return data
Example #4
0
def store_asestructure(ase_structure, extras, structure_group, dryrun):
    ase_structure = sort(ase_structure)
    ase_structure.set_tags(
        [0] *
        len(ase_structure))  #force AiiDA to use the same kind for each element

    # convert any instances of vacancy internal symbol use back to user symbol use
    for key in extras:
        if extras[key] == VACANCY_INTERNAL_SYMBOL:
            extras[key] = VACANCY_USER_SYMBOL

        if key == 'matrix_elements':
            extras[key] = [
                (lambda x: x
                 if x != VACANCY_INTERNAL_SYMBOL else VACANCY_USER_SYMBOL)(x)
                for x in extras[key]
            ]

    # delete all the vacancy sites prior to storage
    del ase_structure[[
        x.index for x in ase_structure if x.symbol == VACANCY_INTERNAL_SYMBOL
        or x.symbol == VACANCY_USER_SYMBOL
    ]]

    alreadyin_group = checkif_structure_alreadyin_group(
        ase_structure, structure_group)

    if alreadyin_group:
        print(("skiping structure, already stored in group: {}".format(
            ase_structure)))
        return

    if dryrun:
        print(("structure: {}".format(ase_structure)))
        print(("extras: {}".format(extras)))
    else:
        print(("storing structure: {}".format(ase_structure)))
        aiida_structure = StructureData()
        aiida_structure.set_ase(ase_structure)
        aiida_structure_stored = aiida_structure.store()
        for key in extras:
            aiida_structure_stored.set_extra(key, extras[key])

        aiida_structure_stored.set_extra("num_atoms", len(ase_structure))
        aiida_structure_stored.set_extra("chem_formula",
                                         ase_structure.get_chemical_formula())

        structure_group.add_nodes(aiida_structure_stored)
        print(("{} stored".format(aiida_structure_stored)))

    return
Example #5
0
def slab_indices(slab0, slab1, mask=None):
    """Match the indices of similar atoms between two slabs."""
    n = len(slab0)
    if mask is None:
        mask = np.arange(n)
    matching = np.arange(n)

    ipos = slab0.positions[mask]
    fpos = slab1.positions[mask]

    d = get_distances(ipos, fpos, cell=slab0.cell, pbc=slab0.pbc)[1]

    matching[mask] = np.argmin(d, axis=1)
    atoms = sort(slab0, matching)

    return atoms
Example #6
0
def parse_traj(structure_file):
    from ase.build import sort
    from ase.io.trajectory import Trajectory
    data = []
    out_traj = Trajectory(structure_file)
    for traj in out_traj:
        structure = sort(traj)
        energy = traj.get_potential_energy()
        force = traj.get_forces()
        xjson = {
            'structure': structure,
            'energy': energy,
            'force': force,
            'stress': None,
            'group': 'random'
        }
        data.append(xjson)
    return data
def random_alloy_structure(
        num_structure=10,
        host='Au',
        impurity='Pd',
        a_host=4.0853,
        a_impurity=3.8907,
        concentration_impurity=0.5):  #TODO list : controlled by output
    random_st = []
    for i in range(num_structure):
        seed = 3001223 + i * 100  # should be gently controlled TODO list : finding best number
        latticeconstant = a_host * (
            1 - concentration_impurity) + a_impurity * concentration_impurity
        model = fcc111(host,
                       size=(3, 3, 4),
                       a=latticeconstant,
                       vacuum=6.0,
                       orthogonal=False
                       )  #TODO list : surface structure controlled by output
        c = FixAtoms(mask=[x > 2 for x in model.get_tags()])
        model.set_constraint(c)

        elements = model.get_chemical_symbols()
        num_atom = model.get_number_of_atoms()

        num_impurity = np.round(num_atom * concentration_impurity)
        np.random.seed(seed)

        j = 0
        while j < int(num_impurity):
            r = np.random.rand()
            n = int(np.round(r * num_atom))
            if elements[n] == host:
                elements[n] = impurity
                j = j + 1

        model.set_chemical_symbols(elements)
        model = sort(model)
        write('POSCAR_' + str(i), model, format='vasp', direct=True)
Example #8
0
#
#  INPUT: CIF filename (note that data_ must be the first 5 characters)
# OUTPUT: POSCAR file containing the same information as in the CIF
#
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

import sys
import os
from ase import Atoms
from ase.io import read, write
from ase.build import sort

filename = sys.argv[1].split('.')[0]

structure = read(sys.argv[1], format='cif')
sorted_structure = sort(structure)
write(filename + '.POSCAR', sorted_structure, format='vasp')

# To create for ASE not including the list of atoms after line 5...

f = open(filename + '.POSCAR', 'r')
contents = f.readlines()
f.close

contents.insert(5, contents[0])

f = open(filename + '.POSCAR', 'w')
contents = "".join(contents)
f.write(contents)
f.close()
Example #9
0
host='Au'      #metal 1#
impurity='Pd'  #metal 2#

latticeconstant=3.8907*0.25+4.0782*0.75  #Pd=3.8907; Au=4.0782, if Pd%=0.25, then is 3.8907*0.25+4.0782*0.75 #  Rh= 3.8034  ;  Pt= 3.9242 ; Cu= 3.6149 ; Ag= 4.0853
concentration_impurity=0.25  #the composition of metal 2#

model=fcc100(host, size=(4,4,4), a=latticeconstant, vacuum=6.0, orthogonal=True)
c = FixAtoms(mask=[x >2   for x in model.get_tags()])
model.set_constraint(c)

elements=model.get_chemical_symbols()
num_atom=model.get_number_of_atoms()

num_impurity=np.round(num_atom*concentration_impurity)


np.random.seed(seed)

i=0
while i < int(num_impurity):
    r=np.random.rand()
    n=int(np.round(r*num_atom))
    if elements[n]==host:
        elements[n]=impurity
        i=i+1


model.set_chemical_symbols(elements)
model=sort(model)
write('POSCAR',model,format='vasp',direct=True)
    lammps = LAMMPSlib(lmp=lmp, lmpcmds=parameters, mol=True)
    struc.set_calculator(lammps)
    box = mushybox(struc)

    dyn = FIRE(box)
    dyn.run(fmax=0.00, steps=1100)

    #dyn = BFGS(box)
    #dyn.run(fmax=0.01, steps=200)

    #dyn = BFGS(box)
    #dyn.run(fmax=0.01, steps=200)
    Eng = struc.get_potential_energy() * 96 / len(struc) * 3
    Vol = struc.get_volume() / len(struc) * 3
    stress = np.max(struc.get_stress())
    struc = sort(struc)
    try:
        spg = get_symmetry_dataset(struc, symprec=1e-1)['number']
    except:
        spg = 1
    struc.write(out_folder + '/' + str(i) + ".vasp", format='vasp', vasp5=True)
    logging.info(
        '{:4d} Spg: {:4d} Eng: {:8.4f} Vol: {:8.4f} Stress: {:5.2f}'.format(
            i, spg, Eng, Vol, stress))
    abc = struc.get_cell_lengths_and_angles()
    abc = [int(i * 1000) / 1000 for i in abc]
    #data['ID'].append(i)
    data['Sym'].append(spg)
    data['Eng'].append(Eng)
    data['abc'].append(abc)
    data['Volume'].append(Vol)
Example #11
0
#!/usr/bin/env python

from ase.io import read, vasp
from ase.build import sort, surface

unitcell = sort(read('POSCAR'))

slab = surface(unitcell, indices=(1, 1, 0), layers=4, vacuum=10)

vasp.write_vasp('POSCAR_slab', sort(slab), vasp5=True, direct=True)
Example #12
0
                    pbc=True)
    return p_struc


def get_perturbed_struc(struc, p0, p1, eps):
    s_new = struc.copy()
    pos = s_new.positions
    pos[p0, p1] += eps
    cell = 17.22 * np.eye(3)
    p_struc = Atoms(s_new.symbols.numbers, positions=pos, cell=cell, pbc=True)
    return p_struc


# NaCl Cluster
nacl = bulk('NaCl', crystalstructure='rocksalt', a=5.691694, cubic=True)
nacl = sort(nacl, tags=[0, 4, 1, 5, 2, 6, 3, 7])
nacl.set_pbc((0, 0, 0))
nacl = get_rotated_struc(nacl, angle=1)

# Descriptors Parameters
eps = 1e-8
rc = 6.00
nmax, lmax = 2, 2
ead_params = {'L': lmax, 'eta': [0.36, 0.036], 'Rs': [1.2, 2.1]}
acsf_params = {
    'G2': {
        'eta': [0.36, 0.036],
        'Rs': [1.2, 2.1]
    },
    'G4': {
        'eta': [0.36, 0.036],
Example #13
0
        f.writelines('    N_atoms(after) : %d' %
                     (slab_super.get_global_number_of_atoms()))

        fix_id_list = []
        for atom in slab_super:
            if atom.position[2] < (layer_position[-3] + 0.1):
                fix_id_list.append(atom.index)

        f.writelines('    N_atoms(fixed) : %d\n' % (len(fix_id_list)))

        slab_super.set_constraint(FixAtoms(indices=fix_id_list))

        for atom in slab_super:
            atom.position[2] -= layer_position[0]

        slab_sorted = sort(slab_super)
        view(slab_sorted)
        """
        INCAR
        """
        INCAR = Incar.from_file(file_path + 'INCAR')

        INCAR['ISIF'] = 2
        INCAR['ISMEAR'] = 0
        INCAR['ISYM'] = 0
        INCAR['IDIPOL'] = 3
        INCAR['NCORE'] = 16

        # Hubbard U setting
        elements = []
        for element in bulk_opt.get_chemical_symbols():
Example #14
0
 def sort_atoms(self, row):
     return sort(row.toatoms())
Example #15
0
delta_z = delta_z_factor * molecule_length - inorganic_z_distance

if (sup == 'y'):
    inorganic_upper.positions[:,2] += delta_z

inorganic_all = inorganic_bottom + inorganic_upper

##### Check which MA's and N's belong to the upper and bottom parts

if(n > 1):
    for i in range(len(MA)):
        
        MA_comz = organic[MA[i]].get_center_of_mass()[2]
        
        if(MA_comz < average_z):
            bottom_MA += sort(organic[MA[i]])
        if(MA_comz > average_z):
            upper_MA += sort(organic[MA[i]])
    if (sup == 'y'):
        upper_MA.positions[:,2] += delta_z


if(len(upper_MA) != len(bottom_MA)):
    print('Warning: different number of atoms in bottom and upper MA. Is this expected?')

##### Get rotation matrices

original = mol.get_positions()

new_mol_positions = np.empty((len(N_com), len(mol), 3))
def make_system(name, h, a, n, m):
    print('running...')
    """Function that takes in the height, h, the spacing of the adsorbate, a,
    the number of positive pole down molecules, n, and the number of negative
    pole down molecules, m."""
    """name specifies the type of base layer: graphene or mos2"""
    d = 0.92791085  #this value is from the relaxed HF molecule in a vacuum
    mol = Atoms('HF', positions=[(0, 0, 0), (0, 0, d)])
    """mol is the dipole molecule. d indicates the bond length"""
    if name == 'graphene':
        num = a * (n + m) / 4.26
        """number of unit cells. 4.26 represents the cell length in angstroms"""
        global gnr
        gnr = graphene_nanoribbon(1,
                                  int(math.ceil(num)),
                                  type='armchair',
                                  vacuum=17.5,
                                  saturated=False,
                                  sheet=True)
        """creates a graphene sheet with 10 A of vacuum on the top and bottom"""
        size = gnr.get_cell()
        cellwidth = size[0][0]
        cellheight = size[1][1]
        celllength = size[2][2]
        spacing = celllength / (n + m)
        """gets the cell dimensions"""
        mol.rotate(270, (1, 0, 0))
        for i in range(n):
            add_adsorbate(gnr,
                          mol,
                          height=(-i) * spacing,
                          position=(cellwidth / 2, cellheight / 2 + h + d),
                          mol_index=1)
        """adds n HF molecules at a separation h from the graphene"""
        mol.rotate(180, (1, 0, 0))
        for j in range(m):
            add_adsorbate(gnr,
                          mol,
                          height=-(j + n) * spacing,
                          position=(cellwidth / 2, cellheight / 2 + h),
                          mol_index=1)
            """adds m HF molecules in the opposite orientation"""
        write('graph' + str(n) + 'up' + str(m) + 'down_center.cif', gnr)
        write('graph' + str(n) + 'up' + str(m) + 'down_center.pwi', gnr)

    elif name == 'BN':
        num = a * (n + m) / 3
        global BN
        BN = Atoms('BN',
                   positions=[(0, 1.405056151, 12.5),
                              (1.2561747111, 0.7252528076, 12.5)])
        dim = [(2.5123494221, 0, 0), (-1.256174711, 2.1757584227, 0),
               (0, 0, 25)]
        BN.set_cell(dim)
        BN = BN.repeat((int(math.ceil(num)), 2, 1))
        dimensions = BN.get_cell()
        BN.set_cell([dimensions[0][0], (dimensions[1][1]), dimensions[2][2]])
        cellwidth = dimensions[0][0]
        spacing = cellwidth / (n + m)
        for i in range(n):

            add_adsorbate(BN,
                          mol,
                          height=h,
                          position=(i * spacing, dimensions[1][1] / 2),
                          mol_index=0)
        mol.rotate(180, (1, 0, 0))
        for j in range(m):
            add_adsorbate(BN,
                          mol,
                          height=h + d,
                          position=((j + n) * spacing, dimensions[1][1] / 2),
                          mol_index=0)
        BN = sort(BN)
        write('BN.cif', BN)
        write(str(n) + 'up' + str(m) + 'down.pwi', BN)
    elif name == 'mos2':
        """#this code runs for the MoS2 system
        num=a*(n+m)/3.17
        global mos2
        mos2=mx2(formula='MoS2', kind='2H', a=3.18, thickness=1, size=(int(math.ceil(num)),1, 1),
             vacuum=10)
        #mx2 makes an MoS2 system
        dim=mos2.get_cell()
        cellwidth=dim[0][0]
        cellheight=dim[1][1]
        celllength=dim[2][2]
        spacing=cellwidth/(n+m)
        #mos2.set_cell([(dim[0][0],0,0),(0,dim[1][1],0),(0,0,dim[2][2])],scale_Atoms=True)
        #truncates the unit cell to be cubic
        for i in range(n):
            add_adsorbate(mos2, mol, height=cellwidth+h,position=((-i)*spacing,cellheight/2
                                                                  ),mol_index=1)
            adds adsorbates to the MoS2
        mol.rotate(180,(1,0,0))
        for j in range(m):
            add_adsorbate(mos2, mol, height=cellwidth+h-d,position=(-(j+n)*spacing,
                                            cellheight/2),mol_index=1)
        write('mos2.cif',mos2)
        #write('mos2.pwi',mos2)"""
    print('complete')
                        x_list.append(atom.index)
                    
                INCAR['MAGMOM'][x_list[0]:(x_list[-1]+1)] = [-5.0, -5.0, 5.0, -5.0, 5.0, 5.0, -5.0, 5.0, 5.0, -5.0, -5.0, 5.0]
                """
                magm = []
                for m, g in itertools.groupby(INCAR['MAGMOM'], lambda x: float(x)):
                    magm.append("{}*{}".format(len(tuple(g)), m))
        
                f.writelines('%03d_%s_%s\n' % (idx + 1.0, formula, adsorbate_names[ads_idx]))
                f.writelines('\tformula: %s\n' % (slab.get_chemical_formula()))
                f.writelines(['\tMAGMOM: ', str(magm), '\n'])
                     
            #   for i in range(len(INCAR['MAGMOM'])):
            #       print(sorted(slab.get_chemical_symbols())[i]," ",INCAR['MAGMOM'][i])
               
                slab_sorted = sort(slab)
                del slab[[atom.index > 51 for atom in slab]]

                # correction for mpi        
                INCAR['NCORE'] = 16

                if 'H' in elements:
                    INCAR['LDAUL'].append(-1)
                    INCAR['LDAUU'].append(0.0)
                    INCAR['LDAUJ'].append(0.0)
            
                    LDAUL_dic = dict(zip(elements, INCAR['LDAUL']))
                    LDAUU_dic = dict(zip(elements, INCAR['LDAUU']))
                    LDAUJ_dic = dict(zip(elements, INCAR['LDAUJ']))
            
                    INCAR['LDAUL'] = [LDAUL_dic[x] for x in sorted(elements)]
    print('    N_atoms(after) : %d' % slab_super.get_global_number_of_atoms())

    fix_id_list = []
    for atom in slab_super:
        if atom.position[2] < (layer_position[-3] + 0.1):
            fix_id_list.append(atom.index)

    print('    N_atoms(fixed) : %d\n' % len(fix_id_list))

    slab_super.set_constraint(FixAtoms(indices=fix_id_list))

    for atom in slab_super:
        atom.position[2] -= layer_position[0]

    model = sort(slab_super)
    #   view(model)
    elements = model.get_chemical_symbols()

    # MAGMOM settings
    mag_dict = {}
    for el in elements:
        if el in TM_elements:
            mag_dict[el] = 5.0  # ferromagnetic
        else:
            mag_dict[el] = 0.6
#   print(mag_dict)
    magmoms = [mag_dict[el] for el in elements]  # Edit here if AFM or NM

    # Hubbard U setting
    ldau = False