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
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
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
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
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
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)
# # 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()
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)
#!/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)
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],
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():
def sort_atoms(self, row): return sort(row.toatoms())
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