def test_decahedron(): p = 3 # Number of atoms along edges of icosahedron-like fivefold structure q = 4 # number of "repetitive" layers between icosahedron-like endings r = 2 # Number of atoms cut off corners of icosahedron-like structure deca = Decahedron(sym, p, q, r) # Does anyone know the formula for how many atoms there are supposed to be? # It "looks good" so just assert things are as they apparently should be: assert len(deca) == 520 coordination = coordination_numbers(deca) internal_atoms = sum(coordination == fcc_maxcoordination) next_smaller_deca = Decahedron(sym, p - 1, q - 1, r) assert internal_atoms == len(next_smaller_deca)
def decahedron_grid(element, lattice_constant, size, heigth): atoms = Decahedron(symbol=element, p=size, q=heigth, r=0, latticeconstant=lattice_constant) atoms.rotate(360. / 10., 'z') atoms.set_pbc(True) atoms.center(vacuum=5.) return atoms
def makeMotif(motif_inputs, latticeconstant, remove_atoms=[]): if isinstance(motif_inputs, int) or len(motif_inputs) == 1: if isinstance(motif_inputs, int): motif_inputs = [motif_inputs] cluster = Icosahedron(symbol, motif_inputs[0], latticeconstant=latticeconstant) name = 'Ico' elif len(motif_inputs) == 2: cluster = Octahedron(symbol, motif_inputs[0], motif_inputs[1], latticeconstant=latticeconstant) name = 'Octa' elif len(motif_inputs) == 3: cluster = Decahedron(symbol, motif_inputs[0], motif_inputs[1], motif_inputs[2], latticeconstant=latticeconstant) name = 'Deca' else: print "Error" import pdb pdb.set_trace() exit() remove_atoms.sort(reverse=True) if any(remove_atoms.count(x) > 1 for x in remove_atoms): print 'You have got two of the same atom entered in to this list, check this.' print 'remove_atoms = ' + str(remove_atoms) import pdb pdb.set_trace() exit() for remove_atom_index in remove_atoms: del cluster[remove_atom_index] name += '_' + symbol + str(len(cluster)) motif_details = '' for motif_input in motif_inputs: motif_details += str(motif_input) + '_' motif_details = motif_details[:-1] name += '_' + motif_details if not remove_atoms == []: name += '_atoms_removed_' + str(len(remove_atoms)) + '_cluster_' counter = 1 while True: if not name + str(counter) + '.traj' in os.listdir('.'): name += str(counter) break counter += 1 ASE_write(name + '.traj', cluster, 'traj') return name
def write_decahedral_cluster(element,e_coh,maximum_size,manual_mode,filename_suffix,input_information_file,folder,sort_manual_mode_by='base details'): print('============================================================') print('Starting Obtaining Decahedral Delta Energies') print('no atoms\tp\tq\tr') P_START = 2; Q_ORIGINAL = 1; R_ORIGINAL = 0 p = P_START # p is the atom length along the 100_face_normal_to_5_fold_axis q = Q_ORIGINAL # q is the atom length along the 100_face_parallel_to_5_fold_axis r = R_ORIGINAL # r is the marks_reenterance_depth #previous_value_of_r = -1 all_deca_details = [] while True: no_atoms = no_of_atoms_to_make_deca(p,q,r) if (r == R_ORIGINAL and q == Q_ORIGINAL) and (no_atoms > maximum_size): break previous_value_of_r = r # From now on, at some point r (and potenitally p and q) will be modified to reflect that for the next cluster to sample if no_atoms <= maximum_size: print('Make decahedral cluster: '+str(no_atoms) + '\t\tp: ' + str(p) + ' \tq: ' + str(q) + ' \tr: ' + str(r))# + '\t,Calculate: ' + str(no_atoms < maximum_size) + '\t,previous r: ' + str(previous_value_of_r) #--------------------------------------------------------------------------------- # Make cluster cluster = Decahedron(element,p=p,q=q,r=r) post_creating_cluster(cluster) name = 'Deca_'+str(p)+'_'+str(q)+'_'+str(r) save_cluster_to_folder(folder,name,filename_suffix,manual_mode,cluster) #--------------------------------------------------------------------------------- # make data for details deca_parameters = (p,q,r) deca_details = (no_atoms, deca_parameters) all_deca_details.append(deca_details) #--------------------------------------------------------------------------------- r += 1 # r is now the value of r for the next cluster that will be made using this algorithm. if (r > q + 3): r = 0; q += 1 else: r = 0; q += 1 # r and q are changed to reflect the next cluster if (q > p + 3) or (previous_value_of_r == 0 and r == 0): q = 1; p += 1 # p and q are changed to reflect the next cluster print('============================================================') with open(input_information_file,'a') as input_file: input_file.write('Decahedron\n') if sort_manual_mode_by == 'no of atoms': all_deca_details.sort(key=lambda x:x[0]) elif sort_manual_mode_by == 'base details': all_deca_details.sort(key=lambda x:x[1]) for no_atoms, details in all_deca_details: no_atoms = str(no_atoms) details = '('+', '.join([str(detail) for detail in details])+')' input_file.write(no_atoms+' '*(atom_writing-len(no_atoms))+details+' '*(details_writing-len(details))+'\n')
delete() print '---------------------------' def optimise(cluster_name): cluster = ASE_read(cluster_name + '.traj') cluster_optimised = RunMinimisation(cluster).get_cluster() cluster_name_opt = cluster_name + '_Opt' ASE_write(cluster_name_opt + '.traj', cluster_optimised) return cluster_name_opt symbol = 'Au' r0 = 2.8840 latticeconstant = r0 * (2.0)**0.5 cluster_main = Decahedron(symbol, 3, 3, 0, latticeconstant=latticeconstant) cluster_main_optimised = RunMinimisation(cluster_main).get_cluster() cluster_main_optimised.set_calculator(None) ''' def rotate_top(angle,atom_to_remove,name): angle = radians(float(angle)) angle = float(angle) cluster = copy.deepcopy(cluster_main) rotate_around_x = cluster[3].x; rotate_around_y = cluster[3].y; first_layer_to_rotate = [19,23,7,11,15] second_layer_to_rotate = [27,8,54,24,51,48,20,45,42,16,39,36,12,33,30] for index in (first_layer_to_rotate+second_layer_to_rotate): old_x = cluster[index].x - rotate_around_x; old_y = cluster[index].y - rotate_around_y new_x = old_x*cos(angle) - old_y*sin(angle) + (rotate_around_x) new_y = old_x*sin(angle) + old_y*cos(angle) + (rotate_around_y) cluster[index].x = new_x; cluster[index].y = new_y
from ase.cluster.decahedron import Decahedron from ase.io import write p = 15 # natoms on 100 face normal to 5-fold axis q = 1 # natoms 0n 100 parallel to 5-fold axis r = 0 # depth of the Marks re-entrance? atoms = Decahedron('Cu', p, q, r) print('#atoms = {}'.format(len(atoms))) #write('images/decahedron.png', atoms) write('decahedron-%03d.xyz'%p, atoms) """ p = 15 6 nm 2815 p = 45 20 nm 75945 p = 80 32 nm 426680 """
#!/usr/bin/env python from ase import Atoms, Atom from ase.calculators.aims import Aims from ase.cluster.decahedron import Decahedron from ase.optimize.basin import BasinHopping from ase.units import kB from ase.optimize import LBFGS atoms = Decahedron('Pt', p=2, # natoms on 100 face normal to 5-fold axis q=1, # natoms 0n 100 parallel to 5-fold axis r=0) # depth of the Marks re-entrance? calc = Aims(label='cluster/pt-decahedron-2-1-bh', xc='pbe', spin='none', relativistic = 'atomic_zora scalar', sc_accuracy_etot=1e-5, sc_accuracy_eev=1e-3, sc_accuracy_rho=1e-4, sc_accuracy_forces=1e-3) atoms.set_calculator(calc) bh = BasinHopping(atoms = atoms, temperature=100 * kB, # 'temperature' to overcome barriers dr=0.5, # maximal stepwidth optimizer=LBFGS, # optimizer to find local minima fmax=0.1 )
def __init__(self, motif, motif_details, element=None, local_optimiser=None, e_coh=None, no_atoms=None, delta_energy=None, debug=False, get_energy=False): if debug: print('cluster: ' + str(cluster)) print('no_atoms: ' + str(no_atoms)) print('local_optimiser: ' + str(local_optimiser)) print('e_coh: ' + str(e_coh)) print('delta_energy: ' + str(delta_energy)) self.motif = motif self.motif_details = motif_details self.get_energy = get_energy # Calculate the delta energy of the clusters if not (element is None and local_optimiser is None and e_coh is None) and (no_atoms is None and delta_energy is None): if motif == 'Icosahedron': if isinstance(motif_details, list): noshells = motif_details[0] else: noshells = motif_details from ase.cluster.icosahedron import Icosahedron cluster = Icosahedron(element, noshells=noshells) elif motif == 'Octahedron': length = motif_details[0] cutoff = motif_details[1] from ase.cluster.octahedron import Octahedron cluster = Octahedron(element, length=length, cutoff=cutoff) elif motif == 'Decahedron': p = motif_details[0] q = motif_details[1] r = motif_details[2] from ase.cluster.decahedron import Decahedron cluster = Decahedron(element, p=p, q=q, r=r) else: print( 'Error in Get_Interpolation_Data.py, in class Cluster, in def __init__' ) print( 'No valid motif type has been entered, must be either Icosahedron, Octahedron, Decahedron.' ) print('Check this.') print('motif = ' + str(motif)) import pdb pdb.set_trace() exit() self.post_creating_cluster(cluster) self.no_atoms = len(cluster) cluster = local_optimiser(cluster) if self.get_energy: energy = cluster.get_potential_energy() self.delta_energy = get_Delta_Energy(energy, cluster, e_coh) elif (element is None and local_optimiser is None and e_coh is None ) and not (no_atoms is None and delta_energy is None): self.no_atoms = no_atoms self.delta_energy = delta_energy else: print( 'Error in Get_Interpolation_Data.py, in class Cluster, in def __init__' ) print('Error in Cluster') print('motif: ' + str(motif)) print('motif_details: ' + str(motif_details)) print('element: ' + str(element)) print('local_optimiser: ' + str(local_optimiser)) print('e_coh: ' + str(e_coh)) print('no_atoms: ' + str(no_atoms)) print('delta_energy: ' + str(delta_energy)) exit()
#!/usr/bin/env python from ase import Atoms, Atom from ase.calculators.aims import Aims, AimsCube from ase.cluster.decahedron import Decahedron from ase.io import write import numpy as np import os np.set_printoptions(precision=3, suppress=True) atoms = Decahedron('Pt', p=2, # natoms on 100 face normal to 5-fold axis q=2, # natoms 0n 100 parallel to 5-fold axis r=0) # depth of the Marks re-entrance? calc = Aims(label='cluster/pt-decahedron-2-2-relax', xc='pbe', spin='none', relativistic = 'atomic_zora scalar', sc_accuracy_rho=1e-4, sc_accuracy_eev=1e-2, sc_accuracy_etot=1e-5, sc_iter_limit=500, relax_geometry = 'bfgs 1.e-2') atoms.set_calculator(calc) print('energy = {0} eV'.format(atoms.get_potential_energy())) print('Forces') print('=======') print(atoms.get_forces())
def clusters(): yield Icosahedron(sym, 2) yield Octahedron(sym, length=3, cutoff=1) yield Decahedron(sym, 2, 3, 3)
def test_smallest_decahedron(): assert len(Decahedron(sym, 1, 1, 0)) == 1