def voids(atoms_in): """Find location and size of voids in a given structure. Returns the voids as 'X' atoms. The atoms' charge is misused to contain the voids' radius. """ trials = 6 # XXX do not hardwire atoms = atoms_in.copy() # append moving atom atoms.append(Atom('X')) atoms.set_calculator(RepulsivePotential()) voids_a = Atoms() voids_a.set_cell(atoms.get_cell()) voids_a.set_pbc(atoms.get_pbc()) positions = atoms.get_positions() for pos in positions[:-1]: for c in range(trials): positions[-1] = pos + 0.1 * np.random.uniform(-1, 1, size=3) atoms.set_positions(positions) # XXX do not hardwire relax = FIRE(atoms, logfile=None ) # XXX do not hardwire relax.run(fmax=0.001, steps=100) # get minimal distance Rmin = 100000 for b in range(len(atoms) - 1): R = atoms.get_distance(b, -1, mic=True) if R < Rmin: Rmin = R # check if new or better voids_a.append(Atom('X', atoms.get_positions()[-1], charge=Rmin)) voids_a.set_positions(voids_a.get_positions(wrap=True)) remove = [] last = len(voids_a) - 1 for ia, a in enumerate(voids_a[:-1]): d = voids_a.get_distance(ia, -1, mic=True) if d < a.charge or d < Rmin: if a.charge > Rmin: remove.append(last) else: remove.append(ia) remove.sort() if last not in remove: p = voids_a.get_positions()[-1] print('found new void at [%g,%g,%g], R=%g' % (p[0], p[1], p[2], Rmin)) for a in remove[::-1]: if a != last: p = voids_a.get_positions()[a] print('removing void at [%g,%g,%g], R=%g' % (p[0], p[1], p[2], voids_a[a].charge)) voids_a.pop(a) return voids_a
def Minimisation_Function(cluster): cluster.pbc = False # Perform the local optimisation method on the cluster. # Parameter sequence: [p, q, a, xi, r0] Pt_parameters = {'Pt': [10.71, 3.845, 0.27443, 2.6209, 2.77]} Gupta_parameters = Pt_parameters cutoff = 1000 calculator = Gupta(Gupta_parameters, cutoff=cutoff, debug=False) cluster.set_calculator(calculator) original_cluster = cluster.copy() dyn = FIRE(cluster, logfile=None) #startTime = time.time(); converged = False try: dyn.run(fmax=0.01, steps=5000) converged = dyn.converged() if not converged: cluster_name = 'issue_cluster.xyz' errorMessage = 'The optimisation of cluster ' + str( original_cluster) + ' did not optimise completely.\n' errorMessage += 'The cluster of issue before optimisation has been saved as: ' + str( cluster_name) write(cluster_name, original_cluster) raise Exception(errorMessage) except Exception as exception_message: cluster_name = 'issue_cluster.xyz' errorMessage = 'The optimisation of cluster ' + str( original_cluster) + ' did not optimise completely.\n' errorMessage += 'The cluster of issue before optimisation has been saved as: ' + str( cluster_name) + '\n' errorMessage += exception_message write(cluster_name, original_cluster) raise Exception(errorMessage) #endTime = time.time() return cluster
def get_dynamics(atoms, mcfm_pot, T=300): # ------ Set up logfiles traj_interval = 10 thermoPrintstatus_log = open("log_thermoPrintstatus.log", "w") outputTrajectory = open("log_trajectory.xyz", "w") mcfmError_log = open("log_mcfmError.log", "w") # ------ Let optimiser use the base potential and relax the per atom energies mcfm_pot.qm_cluster.flagging_module.ema_parameter = 0.1 mcfm_pot.qm_cluster.flagging_module.qm_flag_potential_energies =\ np.ones((len(atoms), 2), dtype=float) * 1001 # ------ Minimize positions opt = FIRE(atoms) optimTrajectory = open("log_optimizationTrajectory.xyz", "w") opt.attach(trajectory_writer, 1, atoms, optimTrajectory, writeResults=True) opt.run(fmax=0.05, steps=1000) # ------ Define ASE dyamics sim_T = T * units.kB MaxwellBoltzmannDistribution(atoms, 2 * sim_T) timestep = 5e-1 * units.fs friction = 1e-2 dynamics = Langevin(atoms, timestep, sim_T, friction, fixcm=False) dynamics.attach(mcfm_thermo_printstatus, 100, 100, dynamics, atoms, mcfm_pot, logfile=thermoPrintstatus_log) dynamics.attach(trajectory_writer, traj_interval, atoms, outputTrajectory, writeResults=False) dynamics.attach(mcfm_error_logger, 100, 100, dynamics, atoms, mcfm_pot, logfile=mcfmError_log) return dynamics
def Minimisation_Function(cluster, collection, cluster_dir): cluster.pbc = False rCut = 1000 #sigma = 1; epsilon = 1; lj_calc = LennardJones(sigma=sigma, epsilon=epsilon,rc=rCut) elements = [atomic_numbers[cluster[0].symbol]] sigma = [1] epsilon = [1] lj_calc = LennardJones(elements, epsilon, sigma, rCut=rCut, modified=True) cluster.set_calculator(lj_calc) dyn = FIRE(cluster, logfile=None) startTime = time.time() converged = False try: dyn.run(fmax=0.01, steps=5000) converged = dyn.converged() if not converged: errorMessage = 'The optimisation of cluster ' + str( cluster_dir) + ' did not optimise completely.' print(errorMessage, file=sys.stderr) print(errorMessage) except Exception: print('Local Optimiser Failed for some reason.') endTime = time.time() # Write information about the algorithm Info = {} Info["INFO.txt"] = '' Info["INFO.txt"] += ("No of Force Calls: " + str(dyn.get_number_of_steps()) + '\n') Info["INFO.txt"] += ("Time (s): " + str(endTime - startTime) + '\n') #Info.write("Cluster converged?: " + str(dyn.converged()) + '\n') return cluster, converged, Info
def test_fire(): a = bulk('Au') a *= (2, 2, 2) a[0].x += 0.5 a.set_calculator(EMT()) opt = FIRE(a, dtmax=1.0, dt=1.0, maxmove=100.0, downhill_check=False) opt.run(fmax=0.001) e1 = a.get_potential_energy() n1 = opt.nsteps a = bulk('Au') a *= (2, 2, 2) a[0].x += 0.5 a.set_calculator(EMT()) reset_history = [] def callback(a, r, e, e_last): reset_history.append([e - e_last]) opt = FIRE(a, dtmax=1.0, dt=1.0, maxmove=100.0, downhill_check=True, position_reset_callback=callback) opt.run(fmax=0.001) e2 = a.get_potential_energy() n2 = opt.nsteps assert abs(e1 - e2) < 1e-6 assert n2 < n1 assert (np.array(reset_history) > 0).all
def relax(atoms, cellbounds=None): # Performs a variable-cell relaxation of the structure calc = EMT() atoms.set_calculator(calc) converged = False niter = 0 while not converged and niter < 10: if cellbounds is not None: cell = atoms.get_cell() if not cellbounds.is_within_bounds(cell): niggli_reduce(atoms) cell = atoms.get_cell() if not cellbounds.is_within_bounds(cell): # Niggli reduction did not bring the unit cell # within the specified bounds; this candidate should # be discarded so we set an absurdly high energy finalize(atoms, 1e9) return ecf = ExpCellFilter(atoms) dyn = FIRE(ecf, maxmove=0.2, logfile=None, trajectory=None) dyn.run(fmax=1e-3, steps=100) converged = dyn.converged() niter += 1 dyn = FIRE(atoms, maxmove=0.2, logfile=None, trajectory=None) dyn.run(fmax=1e-2, steps=100) e = atoms.get_potential_energy() f = atoms.get_forces() s = atoms.get_stress() finalize(atoms, energy=e, forces=f, stress=s)
def get_elastic_constants(pot_path=None, calculator=None, delta=1e-2, symbol="W"): """ return lattice parameter, and cubic elastic constants: C11, C12, 44 using matscipy function pot_path - path to the potential symbol : string Symbol of the element to pass to ase.lattuce.cubic.SimpleCubicFactory default is "W" for tungsten """ unit_cell = bulk(symbol) if (pot_path is not None) and (calculator is None): # create lammps calculator with the potential lammps = LAMMPSlib(lmpcmds=["pair_style eam/fs", "pair_coeff * * %s W" % pot_path], atom_types={'W': 1}, keep_alive=True) calculator = lammps unit_cell.set_calculator(calculator) # simple calculation to get the lattice constant and cohesive energy # alat0 = W.cell[0][1] - W.cell[0][0] sf = StrainFilter(unit_cell) # or UnitCellFilter(W) -> to minimise wrt pos, cell opt = FIRE(sf) opt.run(fmax=1e-4) # max force in eV/A alat = unit_cell.cell[0][1] - unit_cell.cell[0][0] # print("a0 relaxation %.4f --> %.4f" % (a0, a)) # e_coh = W.get_potential_energy() # print("Cohesive energy %.4f" % e_coh) Cij, Cij_err = fit_elastic_constants(unit_cell, symmetry="cubic", delta=delta) Cij = Cij/GPa # unit conversion to GPa elasticMatrix3x3 = Cij[:3, :3] # average of diagonal elements: C11, C22, C33 C11 = elasticMatrix3x3.diagonal().mean() # make mask to extract non diagonal elements mask = np.ones((3, 3), dtype=bool) np.fill_diagonal(mask, False) # average of all non diagonal elements from 1 to 3 C12 = elasticMatrix3x3[mask].mean() # average of diagonal elements from 4 till 6: C44, C55, C66, C44 = Cij[3:, 3:].diagonal().mean() # A = 2.*C44/(C11 - C12) if (pot_path is not None) and (calculator is None): lammps.lmp.close() return alat, C11, C12, C44
def adjust_z_axis(self, cluster): if self.surface == None: return ''' surface_constraints = [] for atom in self.surface: surface_constraints.append(MyConstraint(atom.index,(0,0,1))) ''' surface_constraints = [] #surface_constraints.append(ExternalForce(0, 0, 10)) all_bonds = [] all_angles = [] all_dihedrals = [] for index_1 in range(len(self.surface)): for index_2 in range(index_1+1,len(self.surface)): bonds_distance = get_distance(self.surface[index_1],self.surface[index_2]) bond = [bonds_distance, [index_1,index_2]] all_bonds.append(bond) """ for index_3 in range(index_2+1,len(self.surface)): angle_indices = [[index_1,index_2,index_3],[index_3,index_1,index_2],[index_2,index_3,index_1]] for angle_indice in angle_indices: angle = [self.surface.get_angle(*angle_indice) * pi / 180, angle_indice] all_angles.append(angle) ''' for index_4 in range(index_3+1,len(self.surface)): dihedral_indices = [[index_1,index_2,index_3,index_4],[index_1,index_2,index_3,index_4],[index_1,index_2,index_3,index_4]] for dihedral_indice in dihedral_indices: dihedral = [self.surface.get_dihedral(*dihedral_indice) * pi / 180, dihedral_indice] all_dihedrals.append(dihedral) ''' """ surface_constraints.append(FixInternals(bonds=all_bonds, angles=all_angles, dihedrals=all_dihedrals)) #self.surface.set_constraint(surface_constraints) c = FixAtoms(indices=range(len(self.surface),len(self.surface)+len(cluster))) cluster_constraints = [c] #cluster.set_constraint(cluster_constraints) for atom in self.surface: atom.z -= 40.0 system = self.surface + cluster system.set_calculator(EMT()) system.set_constraint(surface_constraints+cluster_constraints) dyn = FIRE(system) converged = False import pdb; pdb.set_trace() try: dyn.run(fmax=0.01,steps=5000) converged = dyn.converged() if not converged: import os name = os.path.basename(os.getcwd()) errorMessage = 'The optimisation of cluster ' + name + ' did not optimise completely.' print(errorMessage, file=sys.stderr) print(errorMessage) except: print('Local Optimiser Failed for some reason.') import pdb; pdb.set_trace()
def test_mirror(): from ase.build import molecule from ase.constraints import MirrorForce, FixBondLength, MirrorTorque from ase.constraints import ExternalForce from ase.optimize import FIRE from ase.calculators.emt import EMT atoms = molecule('cyclobutene') dist = atoms.get_distance(0, 1) con1 = MirrorForce(2, 3, max_dist=5., fmax=0.05) con2 = FixBondLength(0, 1) atoms.set_constraint([con1, con2]) atoms.calc = EMT() opt = FIRE(atoms) opt.run(fmax=0.05) assert round(dist - atoms.get_distance(0, 1), 5) == 0 atoms = molecule('butadiene') # Break symmetry atoms[0].position[2] += 0.2 dist = atoms.get_distance(1, 2) con1 = MirrorTorque(0, 1, 2, 3, fmax=0.05) con2 = ExternalForce(9, 4, f_ext=0.1) atoms.set_constraint([con1, con2]) atoms.calc = EMT() opt = FIRE(atoms) opt.run(fmax=0.05, steps=300)
def Minimisation_Function(cluster, collection, cluster_name): cluster.pbc = False #################################################################################################################### # Perform the local optimisation method on the cluster. # Parameter sequence: [p, q, a, xi, r0] Gupta_parameters = {'Cu': [10.960, 2.2780, 0.0855, 1.224, 2.556]} cluster.set_calculator(Gupta(Gupta_parameters, cutoff=1000, debug=False)) dyn = FIRE(cluster, logfile=None) startTime = time.time() converged = False try: dyn.run(fmax=0.01, steps=5000) converged = dyn.converged() if not converged: errorMessage = 'The optimisation of cluster ' + str( cluster_name) + ' did not optimise completely.' print(errorMessage, file=sys.stderr) print(errorMessage) except: print('Local Optimiser Failed for some reason.') endTime = time.time() #################################################################################################################### # Write information about the algorithm Info = {} Info["INFO.txt"] = '' Info["INFO.txt"] += ("No of Force Calls: " + str(dyn.get_number_of_steps()) + '\n') Info["INFO.txt"] += ("Time (s): " + str(endTime - startTime) + '\n') #Info["INFO.txt"] += ("Cluster converged?: " + str(dyn.converged()) + '\n') #################################################################################################################### return cluster, converged, Info
def getPath(Reac,Prod,gl): xyzfile3 = open(("IRC3.xyz"), "w") Path = [] Path.append(Reac.copy()) for i in range(0,30): image = Reac.copy() image = tl.setCalc(image,"DOS/", gl.lowerMethod, gl.lowerLevel) Path.append(image) image = Prod.copy() image = tl.setCalc(image,"DOS/", gl.lowerMethod, gl.lowerLevel) Path.append(image) neb1 = NEB(Path,k=1.0,remove_rotation_and_translation = True) try: neb1.interpolate('idpp',optimizer="MDMin",k=1.0) except: neb1.interpolate() optimizer = FIRE(neb1) optimizer.run(fmax=0.07, steps = 500) neb2 = NEB(Path,k=1.0, climb=True, remove_rotation_and_translation = True ) optimizer = FIRE(neb2) optimizer.run(fmax=0.07, steps = 1500) for i in range(0,len(Path)): tl.printTraj(xyzfile3, Path[i]) xyzfile3.close() return Path
def relax_defect_cell(self, ats, output_name='defect_cell_relaxed.xyz', force_tol=0.0001, relax_cell=False): """ Accepts atoms object with an attached calculator.Minimize forces. Args: ats (:obj:`Atoms`): Atoms with defect to relax. output_name (str, optional): Filename to print relaxed atoms structure to. force_tol (float, optional): Force tolerance to stop relaxation. relax_cell (bool, optional): Relax lattice parameters. Returns: :class:`Atoms`: A relaxed Atoms object. """ from ase.optimize import FIRE if relax_cell: strain_mask = [1, 1, 1, 0, 0, 0] ucf = UnitCellFilter(ats, strain_mask) opt = FIRE(ucf) else: strain_mask = [0, 0, 0, 0, 0, 0] ucf = UnitCellFilter(ats, strain_mask) opt = FIRE(ucf) opt.run(fmax=force_tol) ats.write(output_name) return ats
def solve(self): #Create the initial particle from the defining string/number atoms self.particle = NanoClass.genParticle(self.definingString, int(self.numberOfAtoms)) self.reCenter() self.bestEnergy = self.particle.get_potential_energy() self.bestParticle = deepcopy(self.particle) # berendsen = NVTBerendsen(self.particle, 2.5 * units.fs, 2000, taut=0.5*100*units.fs) berendsen = Langevin(self.particle, 5 * units.fs, units.kB * 2000, 0.005) dyn = FIRE(atoms=self.particle) MaxwellBoltzmannDistribution(self.particle,2000*units.kB) CALCULATIONS=100 for i in range(CALCULATIONS): if i%1==0: pDone=float(i)/CALCULATIONS self.setStatusDone(str(math.floor(pDone*100))+"% | "+self.remainingTime(pDone)) self.checkTimeout() self.setSolution(self.getAnswer()) MaxwellBoltzmannDistribution(self.particle,2000*units.kB) self.particle.get_potential_energy() berendsen.run(500) dyn.run() self.reCenter() testEnergy = self.particle.get_potential_energy() if (testEnergy < self.bestEnergy): self.bestEnergy = testEnergy self.bestParticle = deepcopy(self.particle) elif ((testEnergy + .5) > self.bestEnergy): self.particle = NanoClass.genParticle(self.definingString, int(self.numberOfAtoms)) MaxwellBoltzmannDistribution(self.particle,2000*units.kB) self.particle.get_potential_energy() if (testEnergy < self.bestEnergy): self.bestEnergy = testEnergy self.bestParticle = deepcopy(self.particle) return self.getAnswer()
def Minimisation_Function(cluster): cluster.pbc = False # Perform the local optimisation method on the cluster. # Parameter sequence: [p, q, a, xi, r0] #Au_parameters = {'Au': [10.229, 4.0360, 0.2061, 1.7900, 2.884]} r0 = 4.07/(2.0 ** 0.5) Au_parameters = {'Au': [10.53, 4.30, 0.2197, 1.855, r0]} # Baletto Gupta_parameters = Au_parameters cutoff = 1000 calculator = Gupta(Gupta_parameters, cutoff=cutoff, debug=False) cluster.set_calculator(calculator) original_cluster = cluster.copy() dyn = FIRE(cluster,logfile=None) converged = False try: dyn.run(fmax=0.01,steps=5000) converged = dyn.converged() if not converged: cluster_name = 'issue_cluster.xyz' errorMessage = 'The optimisation of cluster ' + str(original_cluster) + ' did not optimise completely.\n' errorMessage += 'The cluster of issue before optimisation has been saved as: '+str(cluster_name) write(cluster_name,original_cluster) raise Exception(errorMessage) except Exception as exception_message: cluster_name = 'issue_cluster.xyz' errorMessage = 'The optimisation of cluster ' + str(original_cluster) + ' did not optimise completely.\n' errorMessage += 'The cluster of issue before optimisation has been saved as: '+str(cluster_name)+'\n' errorMessage += exception_message write(cluster_name,original_cluster) raise Exception(errorMessage) return cluster
def Minimisation_Function(cluster,collection,cluster_name): #################################################################################################################### cluster.pbc = False #################################################################################################################### # Perform the local optimisation method on the cluster. # Parameter sequence: [p, q, a, xi, r0] #Gupta_parameters = {'Au': [10.529999999999999, 4.2999999999999998, 0.21970000000000001, 1.855, 2.8779245994292486]} Gupta_parameters = {'Pd': [10.867, 3.742, 0.1746, 1.718, 2.7485], 'Au': [10.229, 4.036, 0.2061, 1.79, 2.884], ('Au','Pd'): [10.54, 3.89, 0.19, 1.75, 2.816]} cluster.set_calculator(Gupta(Gupta_parameters, cutoff=1000, debug=False)) dyn = FIRE(cluster,logfile=None) startTime = time.time(); converged = False try: dyn.run(fmax=0.01,steps=5000) converged = dyn.converged() if not converged: errorMessage = 'The optimisation of cluster ' + str(cluster_name) + ' did not optimise completely.' print(errorMessage, file=sys.stderr) print(errorMessage) except Exception: print('Local Optimiser Failed for some reason.') endTime = time.time() #################################################################################################################### # Write information about the algorithm Info = {} Info["INFO.txt"] = '' Info["INFO.txt"] += ("No of Force Calls: " + str(dyn.get_number_of_steps()) + '\n') Info["INFO.txt"] += ("Time (s): " + str(endTime - startTime) + '\n') #Info["INFO.txt"] += ("Cluster converged?: " + str(dyn.converged()) + '\n') #################################################################################################################### return cluster, converged, Info
def minimize_energy(atoms, nstep, pressure_interval=10): bulkmodulus = 140e9 / 1e5 # Bulk modulus of typical metal (Cu), in bar. dyn = FIRE(atoms) unstress = Inhomogeneous_NPTBerendsen(atoms, 50*units.fs, 0, taup=5000*units.fs, compressibility=1/bulkmodulus) dyn.attach(unstress.scale_positions_and_cell, interval=10) dyn.run(steps=nstep)
def solve(self): self.setStatusDone("Initializing configuration...") self.particle = NanoClass.genParticle(self.definingString, int(self.numberOfAtoms)) self.reCenter() self.bestEnergy = self.particle.get_potential_energy() self.bestParticle = self.particle.copy() berendsen = Langevin(self.particle, 5*units.fs, units.kB*2000,0.005) dyn = FIRE(atoms=self.particle) dyn.run(500) MaxwellBoltzmannDistribution(self.particle,2000*units.kB) MAXIMUM_ITERATIONS = 20 ITERATION = 0 BEST_POTENTIAL_ENERGY = 999999 BEST_PARTICLE = None queue = [( self.particle.get_potential_energy(), self.particle)] pDone=float(ITERATION)/MAXIMUM_ITERATIONS self.setStatusDone(str(math.floor(pDone*100))+"% | "+self.remainingTime(pDone)) self.checkTimeout() current_particle = self.bestParticle.copy() calc = EMT() current_particle.set_calculator(calc) self.setSolution(self.getAnswer(current_particle, current_particle.get_potential_energy())) while ITERATION < MAXIMUM_ITERATIONS: new_parent = heappop(queue)[1].copy() calc = EMT() new_parent.set_calculator(calc) #print new_parent.get_positions() #print new_parent.get_potential_energy() for x in range(5): new_child = self.create_child_from(new_parent) potential_energy = copy.deepcopy(new_child.get_potential_energy()) heappush(queue, (potential_energy, new_child)) if potential_energy < BEST_POTENTIAL_ENERGY: #print "--------------- NEW BEST FOUND ---------------" #print "POTENTIAL ENERGY = ", potential_energy BEST_POTENTIAL_ENERGY = potential_energy self.bestParticle = new_child #print new_child.positions pDone=float(ITERATION)/MAXIMUM_ITERATIONS self.setStatusDone(str(math.floor(pDone*100))+"% | "+self.remainingTime(pDone)) self.checkTimeout() self.setSolution(self.getAnswer(self.bestParticle, BEST_POTENTIAL_ENERGY)) ITERATION += 1 return self.getAnswer(self.bestParticle, BEST_POTENTIAL_ENERGY)
def minimize_energy(atoms, nstep, pressure_interval=10): bulkmodulus = 140e9 / 1e5 # Bulk modulus of typical metal (Cu), in bar. dyn = FIRE(atoms) unstress = Inhomogeneous_NPTBerendsen(atoms, 50 * units.fs, 0, taup=5000 * units.fs, compressibility=1 / bulkmodulus) dyn.attach(unstress.scale_positions_and_cell, interval=10) dyn.run(steps=nstep)
def _optimize(self): """Perform an optimization.""" self._atoms.set_momenta(np.zeros(self._atoms.get_momenta().shape)) geo_opt = FIRE(self._atoms) geo_opt.run(fmax=5e-02) ecf = ExpCellFilter(self._atoms) opt = self._optimizer(ecf, trajectory='qn%05i.traj' % self._counter, logfile='qn%05i.log' % self._counter) self._log('msg', 'Optimization: qn%05i' % self._counter) opt.run(fmax=self._fmax) self._log('ene')
def calc_gap(): oraxis = '0,0,1' pot_param = PotentialParameters() ener_per_atom = pot_param.gs_ener_per_atom() selected_grains = GrainBoundary.select().where( GrainBoundary.orientation_axis == oraxis).where( GrainBoundary.boundary_plane != oraxis) f = open('./locenviron/gap_energies.dat', 'a') for gb in selected_grains.order_by(GrainBoundary.angle)[2:]: subgbs = (gb.subgrains.select( GrainBoundary, SubGrainBoundary).where(SubGrainBoundary.potential == 'PotBH.xml').join(GrainBoundary).dicts()) subgbs = [ (16.02 * (subgb['E_gb'] - float(subgb['n_at'] * ener_per_atom['PotBH.xml'])) / (2.0 * subgb['area']), subgb) for subgb in subgbs ] subgbs.sort(key=lambda x: x[0]) try: print subgbs[0][1]['path'] continue target_dir = os.path.join('./grain_boundaries', subgbs[0][1]['path']) struct_file = os.path.join(target_dir, subgbs[0][1]['gbid']) + '_traj.xyz' print struct_file ats = AtomsReader(struct_file)[-1] pot = Potential('IP GAP', param_filename='gp33b.xml') ats.set_calculator(pot) print subgbs[0][1]['n_at'], subgbs[0][1]['area'] strain_mask = [0, 0, 1, 0, 0, 0] ucf = UnitCellFilter(ats, strain_mask) opt = FIRE(ucf) FORCE_TOL = 0.1 opt.run(fmax=FORCE_TOL) gap_en = ats.get_potential_energy() print gap_en print round(gb.angle * (180.0 / 3.14159), 3), round( subgbs[0][0], 3), 16.02 * (gap_en - float( subgbs[0][1]['n_at'] * ener_per_atom['gp33b.xml'])) / ( 2.0 * subgbs[0][1]['area']) print >> f, round(gb.angle * (180.0 / 3.14159), 3), round( subgbs[0][0], 3), 16.02 * (gap_en - float( subgbs[0][1]['n_at'] * ener_per_atom['gp33b.xml'])) / ( 2.0 * subgbs[0][1]['area']) ats.write('./locenviron/{}.xyz'.format(subgbs[0][1]['gbid'])) except IndexError: print '\t', round(gb.angle * (180.0 / 3.14159), 3), subgbs
def _calc_quick(atoms, supercell=(1, 1, 1), delta=0.01): """Calculates the Hessian for a given atoms object just like :func:`calc`, *but*, it uses symmetry to speed up the calculation. Depending on the calculator being used, it is possible that the symmetrized result may be different from the full result with all displacements, done manually by :func:`calc`. Args: atoms (matdb.atoms.Atoms): atomic structure of the *primitive*. supercell (list): or `tuple` or :class:`numpy.ndarray` specifying the integer supercell matrix. delta (float): displacement in Angstroms of each atom when computing the phonons. Returns: numpy.ndarray: Hessian matrix that has dimension `(natoms*3, natoms*3)`, where `natoms` is the number of atoms in the *supercell*. """ #We need to make sure we are at the zero of the potential before ratoms = atoms.copy() try: with open("phonons.log", 'w') as f: with redirect_stdout(f): print(ratoms.get_forces()) minim = FIRE(ratoms) minim.run(fmax=1e-4, steps=100) except: #The potential is unstable probably. Issue a warning. msg.warn( "Couldn't optimize the atoms object. Potential may be unstable.") primitive = matdb_to_phonopy(ratoms) phonon = Phonopy(primitive, conform_supercell(supercell)) phonon.generate_displacements(distance=delta) supercells = phonon.get_supercells_with_displacements() pot = atoms.get_calculator() assert pot is not None forces = [] for scell in supercells: matoms = phonopy_to_matdb(scell) #Call a manual reset of the calculator so that we explicitly recalculate #the forces for the current atoms object. pot.reset() matoms.set_calculator(pot) forces.append(matoms.get_forces()) phonon.set_forces(forces) phonon.produce_force_constants() return unroll_fc(phonon._force_constants)
def test_symmetry_sparse(self): """ Test the symmetry of the dense Hessian matrix """ atoms = FaceCenteredCubic('H', size=[2,2,2], latticeconstant=2.37126) calc = Polydisperse(InversePowerLawPotential(1.0, 1.4, 0.1, 3, 1, 2.22)) atoms.set_masses(masses=np.repeat(1.0, len(atoms))) atoms.set_array("size", np.random.uniform(1.0, 2.22, size=len(atoms)), dtype=float) atoms.set_calculator(calc) dyn = FIRE(atoms) dyn.run(fmax=1e-5) H = calc.hessian_matrix(atoms) H = H.todense() self.assertArrayAlmostEqual(np.sum(np.abs(H-H.T)), 0, tol=1e-5)
def test_combine_mm2(): # More biased initial positions for faster test. Set # to false for a slower, harder test. fast_test = True atoms = make_4mer() atoms.constraints = FixBondLengths([(3 * i + j, 3 * i + (j + 1) % 3) for i in range(int(len(atoms) // 3)) for j in [0, 1, 2]]) atoms.calc = TIP3P(np.Inf) tag = '4mer_tip3_opt.' opt = FIRE(atoms, logfile=tag + 'log', trajectory=tag + 'traj') opt.run(fmax=0.05) tip3_pos = atoms.get_positions() sig = np.array([sigma0, 0, 0]) eps = np.array([epsilon0, 0, 0]) rc = np.Inf idxes = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], list(range(6)), list(range(9)), list(range(6, 12))] for ii, idx in enumerate(idxes): atoms = make_4mer() if fast_test: atoms.set_positions(tip3_pos) atoms.constraints = FixBondLengths([(3 * i + j, 3 * i + (j + 1) % 3) for i in range(len(atoms) // 3) for j in [0, 1, 2]]) atoms.calc = CombineMM(idx, 3, 3, TIP3P(rc), TIP3P(rc), sig, eps, sig, eps, rc=rc) tag = '4mer_combtip3_opt_{0:02d}.'.format(ii) opt = FIRE(atoms, logfile=tag + 'log', trajectory=tag + 'traj') opt.run(fmax=0.05) assert ((abs(atoms.positions - tip3_pos) < 1e-8).all()) print('{0}: {1!s:>28s}: Same Geometry as TIP3P'.format( atoms.calc.name, idx))
def test_hessian_random_structure(self): """ Test the computation of the Hessian matrix """ atoms = FaceCenteredCubic('H', size=[2,2,2], latticeconstant=2.37126) calc = Polydisperse(InversePowerLawPotential(1.0, 1.4, 0.1, 3, 1, 2.22)) atoms.set_masses(masses=np.repeat(1.0, len(atoms))) atoms.set_array("size", np.random.uniform(1.0, 2.22, size=len(atoms)), dtype=float) atoms.set_calculator(calc) dyn = FIRE(atoms) dyn.run(fmax=1e-5) H_analytical = calc.hessian_matrix(atoms) H_analytical = H_analytical.todense() H_numerical = fd_hessian(atoms, dx=1e-5, indices=None) H_numerical = H_numerical.todense() self.assertArrayAlmostEqual(H_analytical, H_numerical, tol=self.tol)
def Minimisation_Function(cluster, calculator): cluster.pbc = False cluster.set_calculator(calculator) from ase.optimize import FIRE dyn = FIRE(cluster, logfile=None) try: dyn.run(fmax=0.01, steps=5000) converged = dyn.converged() if not converged: errorMessage = 'The optimisation of cluster ' + str( cluster_name) + ' did not optimise completely.' print(errorMessage, file=sys.stderr) print(errorMessage) except Exception: print('Local Optimiser Failed for some reason.') return cluster
def optimizeMolecule(molecule,NMoves,creationString): bestEnergy = 0. totalMinimaFound = 0 sinceLastFind = 0 calc = QSC() molecule.set_calculator(calc) for i in range(NMoves): molecule = newMove(molecule) molecule = preventExplosions(molecule) molecule.center() sinceLastFind += 1 # do a last optimization of the structure dyn = FIRE(molecule) dyn.run(steps = 2000) newEnergy = molecule.get_potential_energy() if (newEnergy < bestEnergy): optimizedMolecule = molecule bestEnergy = newEnergy line = str(totalMinimaFound) + " " + str(molecule.get_potential_energy()) + " " + str(i) +"\n" print line f = open('EnergyList.txt','a') f.write(line) f.close() minimaList = PickleTrajectory(str(creationString),mode='a') minimaList.write(optimizedMolecule) totalMinimaFound += 1 minimaList.close() sinceLastFind = 0 elif (sinceLastFind < 200): break minimaList.close() minimaList = PickleTrajectory(str(creationString),mode='r') atomslist = [atom for atom in minimaList] ase.io.write('movie.xyz',atomslist,format='xyz') # write a movie file of our dynamics minimaList.close() return optimizedMolecule
def _optimize(self): """Perform an optimization.""" # del self._atoms.constraints self._atoms.set_momenta(np.zeros(self._atoms.get_momenta().shape)) geo_opt = FIRE(self._atoms) geo_opt.run(fmax=self._fmax2) ecf = ExpCellFilter(self._atoms) opt = self._optimizer(ecf, trajectory='qn%05i.traj' % self._counter, logfile='qn%05i.log' % self._counter) self._log('msg', 'Optimization: qn%05i' % self._counter) opt.run(fmax=self._fmax) self._log('ene') # del self._atoms.constraints tri_mat, coord_transform = convert_cell_4NPT(self._atoms.get_cell()) self._atoms.set_positions([np.matmul(coord_transform, position) for position in self._atoms.get_positions()]) self._atoms.set_cell(tri_mat.transpose())
def optimse_Cu(cluster): Cu_parameters = {'Cu': [10.960, 2.2780, 0.0855, 1.2240, 2.556]} cluster.set_calculator(Gupta(Cu_parameters, cutoff=1000, debug=True)) dyn = FIRE(cluster) try: import time startTime = time.time() dyn.run(fmax=0.01, steps=5000) endTime = time.time() if not dyn.converged(): import os name = os.path.basename(os.getcwd()) errorMessage = 'The optimisation of cluster ' + name + ' did not optimise completely.' print >> sys.stderr, errorMessage print errorMessage except: print('Local Optimiser Failed for some reason.')
def solve(self): #Create the initial particle from the defining string/number atoms temp = 1750 mintemp = 150 self.particle = genParticle(self.definingString,int(self.numberOfAtoms)) if (len(self.particle) < 16): temp = 1250 maxtemp = temp berendsen = Langevin(self.particle, 2.5 * units.fs, units.kB * temp, 0.02) # the 5.0 * units.fs is used instead of 0.1 * units.fs b/c it makes the program run faster MaxwellBoltzmannDistribution(self.particle,units.kB * temp) self.bestEnergy = self.particle.get_potential_energy() self.bestParticle = deepcopy(self.particle) self.reCenter() self.getAnswer() while (temp > mintemp): berendsen = Langevin(self.particle, 2.5 * units.fs, units.kB * temp, 0.02) berendsen.run(100) testEnergy = self.particle.get_potential_energy() self.bestEnergy = self.particle.get_potential_energy() self.bestParticle = deepcopy(self.particle) self.reCenter() self.getAnswer() temp -= 10 if (temp % 50 == 0): self.bestEnergy = self.particle.get_potential_energy() self.bestParticle = deepcopy(self.particle) self.reCenter() self.checkTimeout() self.setSolution(self.getAnswer()) pDone=float(maxtemp - temp)/(maxtemp-mintemp) self.setStatusDone(str(math.floor(pDone*100))+"% | "+self.remainingTime(pDone)) elif (temp <= mintemp): dyn = FIRE(atoms=self.particle) dyn.run(fmax=0.01) self.bestEnergy = self.particle.get_potential_energy() self.bestParticle = deepcopy(self.particle) self.reCenter() self.setSolution(self.getAnswer()) pDone=float(temp)/(maxtemp-mintemp) self.setStatusDone(str(math.floor(pDone*100))+"% | "+self.remainingTime(pDone)) return self.getAnswer()
def main(): from time import time #t0 = time() #write('POSCAR', make_pamam(4)) #t1 = time() #print t1-t0 from ase.io import read print 'reading structure' atoms = read('PAMAM-G4.xyz') print 'building bonds' bonds = connect_bonds(atoms) calc = VSEPR(atoms, bonds) atoms.set_calculator(calc) t0 = time() opt = FIRE(atoms, trajectory='opt.traj') opt.run(fmax=1e-3, steps=1000) t1 = time() print 'time:',t1-t0
def make_methylamine(): # Construct Methylamine. atoms = ase.Atoms('NH2CH3') # Define connectivity. atoms_bonds = [ [0,1], [0,2], [0,3], [3,4], [3,5], [3,6] ] # Displace atoms so that they aren't on top of each other. atoms.rattle(0.001) # Construct VSEPR calculator. calculator = VSEPR(atoms, atoms_bonds) atoms.set_calculator(calculator) atoms.center() # Run optimization. opt = FIRE(atoms) opt.run() return atoms
def test_hessian_divide_by_masses(self): """ Test the computation of the Hessian matrix """ atoms = FaceCenteredCubic('H', size=[2,2,2], latticeconstant=2.37126) atoms.set_array("size", np.random.uniform(1.0, 2.22, size=len(atoms)), dtype=float) masses_n = np.random.randint(1, 10, size=len(atoms)) atoms.set_masses(masses=masses_n) calc = Polydisperse(InversePowerLawPotential(1.0, 1.4, 0.1, 3, 1, 2.22)) atoms.set_calculator(calc) dyn = FIRE(atoms) dyn.run(fmax=1e-5) D_analytical = calc.hessian_matrix(atoms, divide_by_masses=True) D_analytical = D_analytical.todense() H_analytical = calc.hessian_matrix(atoms) H_analytical = H_analytical.todense() masses_nc = masses_n.repeat(3) H_analytical /= np.sqrt(masses_nc.reshape(-1,1)*masses_nc.reshape(1,-1)) self.assertArrayAlmostEqual(H_analytical, D_analytical, tol=self.tol)
def test_unitcellfilterpressure(): a0 = bulk('Cu', cubic=True) # perturb the atoms s = a0.get_scaled_positions() s[:, 0] *= 0.995 a0.set_scaled_positions(s) # perturb the cell a0.cell[...] += np.random.uniform(-1e-2, 1e-2, size=9).reshape((3, 3)) atoms = a0.copy() atoms.calc = LennardJones() ucf = UnitCellFilter(atoms, scalar_pressure=10.0 * GPa) # test all derivatives f, fn = gradient_test(ucf) assert abs(f - fn).max() < 1e-6 opt = FIRE(ucf) opt.run(1e-3) # check pressure is within 0.1 GPa of target sigma = atoms.get_stress() / GPa pressure = -(sigma[0] + sigma[1] + sigma[2]) / 3.0 assert abs(pressure - 10.0) < 0.1 atoms = a0.copy() atoms.calc = LennardJones() ecf = ExpCellFilter(atoms, scalar_pressure=10.0 * GPa) # test all deritatives f, fn = gradient_test(ecf) assert abs(f - fn).max() < 1e-6 opt = LBFGSLineSearch(ecf) opt.run(1e-3) # check pressure is within 0.1 GPa of target sigma = atoms.get_stress() / GPa pressure = -(sigma[0] + sigma[1] + sigma[2]) / 3.0 assert abs(pressure - 10.0) < 0.1
def surface_energy(surface, calc, accuracy=0.00001, shake=0.1, seed=1): """ calculates the energy of the surface (without dividing by the area or subtracting bulk) Note: we will calculate the bulk energy for one atom and multiply by number of atoms to save time in calculation """ symbol = surface.get_chemical_symbols()[0] surface.set_calculator(calc) e_surface = surface.get_potential_energy() print "unrelaxed energy:", e_surface # rattle surface atoms a bit, to relax, get relaxed energy surface.rattle(stdev=shake,seed=seed) dyn = FIRE(surface) dyn.run(fmax=accuracy) e_relaxed_surface = surface.get_potential_energy() return e_surface, e_relaxed_surface
def breedParticles(self, particle1, particle2): index = 0; mindistance = 0; bestatom = None; for atom in particle1: mindistance = 1000000.; bestatom = None; if(random.random() < 0.5): for atom2 in particle2: if(atom2.symbol == atom.symbol and (atom.position[0] - atom2.position[0])**2 + (atom.position[1] - atom2.position[1])**2 + (atom.position[2] - atom2.position[2])**2 < mindistance**2): mindistance = ((atom.position[0] - atom2.position[0])**2 + (atom.position[1] - atom2.position[1])**2 + (atom.position[2] - atom2.position[2])**2)**0.5; bestatom = deepcopy(atom2); atom.x = bestatom.position[0] + random.gauss(0.,0.25); atom.y = bestatom.position[1] + random.gauss(0.,0.25); atom.z = bestatom.position[2] + random.gauss(0.,0.25); particle1.get_potential_energy() sys.stdout = f dyn = FIRE(atoms=particle1) dyn.run() sys.stdout = std_outpath return particle1;
def relax(self): """Relax the atoms return the relaxed energy. This function leaves the atoms unchanged (it changes them but restores the positions). If a single atoms moves "too much" the relaxation is rejected. """ if self.atoms.get_calculator().__class__.__name__ == 'adscalc': self.atoms.get_calculator().use_adsorbates(False) energy_before = self.atoms.get_potential_energy() #print "unrelaxed energy: "+str(energy) old_pos = self.atoms.get_positions() for i in range(3): dyn = FIRE(atoms=self.atoms,logfile=None) dyn.run(fmax=0.05, steps=2000) reten=self.atoms.get_potential_energy() # Sanity check. nblist = self.atoms.get_calculator().get_neighbor_list() r = self.atoms.get_positions() - old_pos dr = np.zeros((len(self.atoms),3)) for i in range(len(self.atoms)): nblist_i = nblist[i] dr[i] = r - r[nblist_i].sum(axis=0)/len(nblist[i]) dr = np.sqrt( (dr*dr).sum(axis=1).max() ) # dr is now how far the most mobile atom has moved # relative to its neighbors. # Now, identify how far it is reasonable that it has moved. x = old_pos[0] - old_pos[nblist[0]] acceptable = np.sqrt( (x*x).sum(axis=1).min() ) assert acceptable > 0.01 if dr > 0.5 * acceptable: reten = energy_before # Reject # Restore the atoms self.atoms.set_positions(old_pos) if self.atoms.get_calculator().__class__.__name__ == 'adscalc': self.atoms.get_calculator().use_adsorbates(True) return energy_before, reten
def Minimisation_Function(cluster,collection,cluster_dir): #################################################################################################################### # Read the BeforeOpt file and record the elements, the # number of each element in the cluster and their positions #cluster = ase_read("BeforeOpt",format='vasp') cluster.pbc = False #################################################################################################################### #Construct atoms using the ASE class "Atoms". #################################################################################################################### # Perform the local optimisation method on the cluster. # Parameter sequence: [p, q, a, xi, r0] rCut = 1000 #sigma = 1; epsilon = 1; lj_calc = LennardJones(sigma=sigma, epsilon=epsilon,rc=rCut) elements = [atomic_numbers[cluster[0].symbol]]; sigma = [1]; epsilon = [1]; lj_calc = LennardJones(elements, epsilon, sigma, rCut=rCut, modified=True) cluster.set_calculator(lj_calc) dyn = FIRE(cluster,logfile=None) startTime = time.time(); converged = False try: dyn.run(fmax=0.01,steps=5000) converged = dyn.converged() if not converged: import os name = os.path.basename(os.getcwd()) errorMessage = 'The optimisation of cluster ' + name + ' did not optimise completely.' print(errorMessage, file=sys.stderr) print(errorMessage) except: print('Local Optimiser Failed for some reason.') endTime = time.time() #ase_write('AfterOpt.traj',cluster) #################################################################################################################### # Write information about the algorithm Info = {} Info["INFO.txt"] = '' Info["INFO.txt"] += ("No of Force Calls: " + str(dyn.get_number_of_steps()) + '\n') Info["INFO.txt"] += ("Time (s): " + str(endTime - startTime) + '\n') #Info.write("Cluster converged?: " + str(dyn.converged()) + '\n') #################################################################################################################### return cluster, converged, Info
def relax(self): """Relax the atoms return the relaxed energy. This function leaves the atoms unchanged (it changes them but restores the positions). If a single atoms moves "too much" the relaxation is rejected. """ if self.atoms.get_calculator().__class__.__name__ == 'adscalc': self.atoms.get_calculator().use_adsorbates(False) energy_before = self.atoms.get_potential_energy() #print "unrelaxed energy: "+str(energy) old_pos = self.atoms.get_positions() for i in range(3): dyn = FIRE(atoms=self.atoms, logfile=None) dyn.run(fmax=0.05, steps=2000) reten = self.atoms.get_potential_energy() # Sanity check. nblist = self.atoms.get_calculator().get_neighbor_list() r = self.atoms.get_positions() - old_pos dr = np.zeros((len(self.atoms), 3)) for i in range(len(self.atoms)): nblist_i = nblist[i] dr[i] = r - r[nblist_i].sum(axis=0) / len(nblist[i]) dr = np.sqrt((dr * dr).sum(axis=1).max()) # dr is now how far the most mobile atom has moved # relative to its neighbors. # Now, identify how far it is reasonable that it has moved. x = old_pos[0] - old_pos[nblist[0]] acceptable = np.sqrt((x * x).sum(axis=1).min()) assert acceptable > 0.01 if dr > 0.5 * acceptable: reten = energy_before # Reject # Restore the atoms self.atoms.set_positions(old_pos) if self.atoms.get_calculator().__class__.__name__ == 'adscalc': self.atoms.get_calculator().use_adsorbates(True) return energy_before, reten
def Minimisation_Function(cluster, collection, cluster_dir): #################################################################################################################### # Read the BeforeOpt file and record the elements, the # number of each element in the cluster and their positions #cluster = ase_read("BeforeOpt",format='vasp') cluster.pbc = False #################################################################################################################### #Construct atoms using the ASE class "Atoms". #################################################################################################################### # Perform the local optimisation method on the cluster. # Parameter sequence: [p, q, a, xi, r0] Gupta_parameters = {'Cu': [10.960, 2.2780, 0.0855, 1.224, 2.556]} cluster.set_calculator(Gupta(Gupta_parameters, cutoff=1000, debug=False)) dyn = FIRE(cluster, logfile=None) startTime = time.time() converged = False try: dyn.run(fmax=0.01, steps=5000) converged = dyn.converged() if not converged: import os name = os.path.basename(os.getcwd()) errorMessage = 'The optimisation of cluster ' + name + ' did not optimise completely.' #print sys.stderr >> errorMessage print(errorMessage) except: print('Local Optimiser Failed for some reason.') endTime = time.time() #ase_write('AfterOpt.traj',cluster) #################################################################################################################### # Write information about the algorithm Info = {} Info["INFO.txt"] = '' Info["INFO.txt"] += ("No of Force Calls: " + str(dyn.get_number_of_steps()) + '\n') Info["INFO.txt"] += ("Time (s): " + str(endTime - startTime) + '\n') #Info.write("Cluster converged?: " + str(dyn.converged()) + '\n') #################################################################################################################### return cluster, converged, Info
def surface_energy(surface, calc, accuracy=0.00001, shake=0.1, seed=1): """ calculates the energy of the surface (without dividing by the area or subtracting bulk) Note: we will calculate the bulk energy for one atom and multiply by number of atoms to save time in calculation """ symbol = surface.get_chemical_symbols()[0] surface.set_calculator(calc) pos_unrelaxed = surface.positions[:] e_surface = surface.get_potential_energy() print "unrelaxed energy:", e_surface # rattle surface atoms a bit, to relax, get relaxed energy surface.rattle(stdev=shake, seed=seed) dyn = FIRE(surface) dyn.run(fmax=accuracy) e_relaxed_surface = surface.get_potential_energy() pos_relaxed = surface.positions[:] return e_surface, e_relaxed_surface, pos_unrelaxed, pos_relaxed
def relax_structure(atoms, relax_fmax=0.05, traj_interval=None): """ Relax atoms object. If it contains a 'fixed_mask' array, then run constrained relaxation """ arel = atoms.copy() try: fix_mask = atoms.get_array("fixed_mask") print("Running relaxation with %d constrained atoms" % fix_mask.sum()) const = FixAtoms(mask=fix_mask) arel.set_constraint(const) except: print("No constraints specified, running relaxation") arel.set_calculator(calc) opt = FIRE(arel) # LBFGS(arel) # if traj_interval is not None: from quippy.io import AtomsWriter out = AtomsWriter("traj-relax_structure.xyz") trajectory_write = lambda: out.write(QAtoms(arel, charge=None)) opt.attach(trajectory_write, interval=traj_interval) opt.run(fmax=relax_fmax) return arel
atoms.set_calculator(params.calc) # Save frames to the trajectory every `traj_interval` time steps traj_file = open('traj-m-6r.xyz', 'w') minimiser = FIRE(atoms, restart='hess.traj') def trajectory_write(): ase.io.extxyz.write_xyz(traj_file, atoms) # swap is an array of atom indices that have to be sent in opposite direction wrt # what thin_strip_displacement_y would do. swap = np.loadtxt('swap_topbottom_atoms.csv') for i in range(1000): minimiser.run(fmax=params.relax_fmax) trajectory_write() # Find initial position of crack tip #crack_pos = find_tip_stress_field(crack_slab, calc=params.calc) #print 'Found crack tip at position %s' % crack_pos atoms.info['strain'] = get_strain(atoms) strain = atoms.info['strain'] print("Strain: %f" % strain) # update atomic positions displacement = thin_strip_displacement_y( atoms.positions[:, 0], atoms.positions[:, 1], params.strain_rate * params.timestep, left + params.crack_seed_length, left + params.crack_seed_length +
sys.path.insert(0, '.') import params a = params.cryst.copy() # ***** Find eqm. lattice constant ****** # find the equilibrium lattice constant by minimising atoms wrt virial # tensor given by SW pot (possibly replace this with parabola fit in # another script and hardcoded a0 here) a.set_calculator(params.calc) if hasattr(params, 'relax_bulk') and params.relax_bulk: print('Minimising bulk unit cell...') opt = FIRE(StrainFilter(a, mask=[1, 1, 1, 0, 0, 0])) opt.run(fmax=params.bulk_fmax) a0 = a.cell[0, 0] print('Lattice constant %.3f A\n' % a0) a.set_calculator(params.calc) # ******* Find elastic constants ******* # Get 6x6 matrix of elastic constants C_ij C = measure_triclinic_elastic_constants(a, optimizer=FIRE, fmax=params.bulk_fmax) print('Elastic constants (GPa):') print((C / units.GPa).round(0)) print('')
########################################################### atoms = makeBimetallic('POSCAR',100,78,79,0.5) calc = QSC() atoms.set_calculator(calc) minimaList = PickleTrajectory('Pt75Au25.traj',mode='a') for i in range(NMoves): numbertomove = numpy.random.randint(len(atoms)) atoms = moveAtoms(numbertomove,atoms) atoms.center() atoms = preventExplosions(atoms) # do a last optimization of the structure dyn = FIRE(atoms) dyn.run() newEnergy = atoms.get_potential_energy() if (newEnergy < bestEnergy): bestEnergy = newEnergy line = str(totalMinimaFound) + " " + str(atoms.get_potential_energy()) + " " + str(i) +"\n" print line f = open('EnergyList.txt','a') f.write(line) f.close() minimaList.write(atoms) totalMinimaFound += 1 sinceLastFind = 0 elif (sinceLastFind < 200): # if we haven't found a new minimum in 200 tries, start over atoms = ase.io.read('POSCAR') calc = QSC() atoms.set_calculator(calc)
def opt(atoms, bonds): atoms.rattle() calculator = VSEPR(atoms, bonds) atoms.set_calculator(calculator) opt = FIRE(atoms, dtmax=0.5, logfile='/dev/null', trajectory='opt.traj') opt.run(fmax=0.1)
mol = Cluster([Atom('H'), Atom('H',[1,0,0]), Atom('H',[.5,.5,.5])], cell = [2,2,2], pbc=True) def set_calculators(all=False): c=GPAW(h=.3, convergence={'eigenstates':0.1, 'energy' : 0.1, 'density' : 0.01}, txt=txt) # c = EMT() n = len(images) if not all: n -= 2 neb.set_calculators([c] * n) images = [mol] for i in range(4): images.append(images[0].copy()) images[-1].positions[2, 1] = 2 - images[0].positions[2, 1] neb = SingleCalculatorNEB(images) neb.interpolate() for image in images: print(image[2].position) set_calculators(True) dyn = FIRE(neb, trajectory='mep.traj') dyn.insert_observer(set_calculators) print(dyn.run(fmax=8.))
print 'Running WITH EAM as embedded cluster' qm_pot_file = os.path.join(pot_dir, 'PotBH_fakemod.xml') print qm_pot_file mm_init_args = 'IP EAM_ErcolAd do_rescale_r=T r_scale=1.01' # Classical potential qm_pot = Potential(mm_init_args, param_filename=qm_pot_file, cutoff_skin=cutoff_skin) qmmm_pot = set_qmmm_pot(atoms, atoms.params['CrackPos'], mm_pot, qm_pot) strain_atoms = fix_edges(atoms) print 'Setup dynamics' #If input_file is crack.xyz the cell has not been thermalized yet. #Otherwise it will recover temperature from the previous run. print 'Attaching trajectories to dynamics' trajectory = AtomsWriter(traj_file) #Only wriates trajectory if the system is in the LOTFDynamicas #Interpolation atoms.wrap() atoms.set_cutoff(3.0) atoms.calc_connect() print 'Running Crack Simulation' RELAXATION = False if RELAXATION: dynamics = FIRE(atoms) dynamics.attach(pass_trajectory_context(trajectory, dynamics), traj_interval, dynamics) dynamics.run(fmax=0.1) else: dynamics = LOTFDynamics(atoms, timestep, extrapolate_steps) dynamics.attach(pass_trajectory_context(trajectory, dynamics), traj_interval, dynamics) nsteps = 2000 dynamics.run(nsteps)
mol = Cluster([Atom('H'), Atom('H',[1,0,0]), Atom('H',[.5,.5,.5])], cell = [2,2,2], pbc=True) def set_calculators(all=False): c=GPAW(h=.3, convergence={'eigenstates':0.1, 'energy' : 0.1, 'density' : 0.01}, txt=txt) # c = EMT() n = len(images) if not all: n -= 2 neb.set_calculators([c] * n) images = [mol] for i in range(4): images.append(images[0].copy()) images[-1].positions[2, 1] = 2 - images[0].positions[2, 1] neb = SingleCalculatorNEB(images) neb.interpolate() for image in images: print image[2].position set_calculators(True) dyn = FIRE(neb, trajectory='mep.traj') dyn.insert_observer(set_calculators) print dyn.run(fmax=8.)
f_ext = 0.2 atom1 = 0 atom2 = 1 atom3 = 2 fmax = 0.001 atoms = Atoms('H3', positions=[(0, 0, 0), (0.751, 0, 0), (0, 1., 0)]) atoms.set_calculator(EMT()) # Without external force opt = FIRE(atoms) opt.run(fmax=fmax) dist1 = atoms.get_distance(atom1, atom2) # With external force con1 = ExternalForce(atom1, atom2, f_ext) atoms.set_constraint(con1) opt = FIRE(atoms) opt.run(fmax=fmax) dist2 = atoms.get_distance(atom1, atom2) # Distance should increase due to the external force assert dist2 > dist1 # Combine ExternalForce with FixBondLength # Fix the bond on which the force acts con2 = FixBondLength(atom1, atom2)
import numpy as np from ase.calculators.emt import EMT from ase.build import bulk from ase.optimize import FIRE a = bulk('Au') a *= (2, 2, 2) a[0].x += 0.5 a.set_calculator(EMT()) opt = FIRE(a, dtmax=1.0, dt=1.0, maxmove=100.0, downhill_check=False) opt.run(fmax=0.001) e1 = a.get_potential_energy() n1 = opt.nsteps a = bulk('Au') a *= (2, 2, 2) a[0].x += 0.5 a.set_calculator(EMT()) reset_history = [] def callback(a, r, e, e_last): reset_history.append([e - e_last])
cell = surf_cell.get_cell() A = cell[0][0]*cell[1][1] gamma = (surf_ener- len(surf_cell)*ener_per_atom)/A print '2*gamma ev/A2', gamma print '2*gamma J/m2', gamma/(units.J/units.m**2) j_dict = {'or_axis':or_axis, 'bp':bp, 'gamma':gamma} with open('gbfrac.json','w') as f: json.dump(j_dict, f) out = AtomsWriter('{0}'.format('{0}_surf.xyz'.format(gbid))) out.write(Atoms(surf_cell)) out.close() frac_cell = gb_frac.build_tilt_sym_frac() #Unit cell for grain boundary fracture cell: print frac_cell.get_cell().round(2) frac_cell = Atoms(frac_cell) frac_cell = del_atoms(frac_cell) #Relax grainboundary crack cell unit cell: pot = Potential('IP EAM_ErcolAd', param_filename='Fe_Mendelev.xml') frac_cell.set_calculator(pot) slab_opt = FIRE(frac_cell) slab_opt.run(fmax = (0.02*units.eV/units.Ang)) #Print frac_cell to file: out = AtomsWriter('{0}'.format('frac_cell.xyz'.format(gbid))) out.write(Atoms(frac_cell)) out.close()
C 7.150130182125531 4.155384186721486 4.537328602062397 H 3.218154657585170 4.565210696328925 3.522601038049320 H 3.077656122062729 6.375092902842770 3.826039498180272 H 5.478464901706067 6.370680001794822 4.422235395756437 H 5.320549047980879 3.220584852467720 3.974551561510350 H 7.723359150977955 3.224855971783890 4.574146712279462 H 7.580803493981530 5.034479218283977 4.877211530909463 """ h = 0.3 atoms = Cluster(read_xyz(StringIO.StringIO(butadiene))) atoms.minimal_box(3.0, h) atoms.set_calculator(GPAW(h=h)) if 0: dyn = FIRE(atoms) dyn.run(fmax=0.05) atoms.write("butadiene.xyz") vibname = "fcvib" vib = Vibrations(atoms, name=vibname) vib.run() # Modul a = FranckCondon(atoms, vibname, minfreq=250) # excited state forces F = np.array( [ [-2.11413, 0.07317, -0.91682], [3.23569, -0.74520, 0.76758], [-3.44847, 0.63846, -0.81080],
image.constraints.append(constraint) # Displace last image: for i in xrange(1,8,1): images[-1].positions[-i] += (d/2, -h1/3, 0) write('initial.traj', images[0]) # Relax height of Ag atom for initial and final states: for image in [images[0], images[-1]]: QuasiNewton(image).run(fmax=0.01) if 0: write('initial.pckl', image[0]) write('finial.pckl', image[-1]) # Interpolate positions between initial and final states: neb.interpolate() for image in images: print image.positions[-1], image.get_potential_energy() traj = PickleTrajectory('mep.traj', 'w') dyn = FIRE(neb, dt=0.1) #dyn = MDMin(neb, dt=0.1) #dyn = QuasiNewton(neb) dyn.attach(neb.writer(traj)) dyn.run(fmax=0.01,steps=150) for image in images: print image.positions[-1], image.get_potential_energy()
def test_J_integral(self): """ Check if the J-integral returns G=2*gamma """ if not atomistica: print 'Atomistica not available. Skipping test.' nx = 128 for calc, a0, C11, C12, C44, surface_energy, bulk_coordination in [ ( atomistica.DoubleHarmonic(k1=1.0, r1=1.0, k2=1.0, r2=math.sqrt(2), cutoff=1.6), clusters.sc('He', 1.0, [nx,nx,1], [1,0,0], [0,1,0]), 3, 1, 1, 0.05, 6 ), # ( atomistica.Harmonic(k=1.0, r0=1.0, cutoff=1.3, shift=False), # clusters.fcc('He', math.sqrt(2.0), [nx/2,nx/2,1], [1,0,0], # [0,1,0]), # math.sqrt(2), 1.0/math.sqrt(2), 1.0/math.sqrt(2), 0.05, 12) ]: print '{} atoms.'.format(len(a0)) crack = CubicCrystalCrack(C11, C12, C44, [1,0,0], [0,1,0]) x, y, z = a0.positions.T r2 = min(np.max(x)-np.min(x), np.max(y)-np.min(y))/4 r1 = r2/2 a = a0.copy() a.center(vacuum=20.0, axis=0) a.center(vacuum=20.0, axis=1) ref = a.copy() r0 = ref.positions a.set_calculator(calc) print 'epot = {}'.format(a.get_potential_energy()) sx, sy, sz = a.cell.diagonal() tip_x = sx/2 tip_y = sy/2 k1g = crack.k1g(surface_energy) g = a.get_array('groups') old_x = tip_x+1.0 old_y = tip_y+1.0 while abs(tip_x-old_x) > 1e-6 and abs(tip_y-old_y) > 1e-6: a.set_constraint(None) ux, uy = crack.displacements(r0[:,0], r0[:,1], tip_x, tip_y, k1g) a.positions[:,0] = r0[:,0] + ux a.positions[:,1] = r0[:,1] + uy a.positions[:,2] = r0[:,2] a.set_constraint(ase.constraints.FixAtoms(mask=g==0)) opt = FIRE(a, logfile=None) opt.run(fmax=1e-3) old_x = tip_x old_y = tip_y tip_x, tip_y = crack.crack_tip_position(a.positions[:,0], a.positions[:,1], r0[:,0], r0[:,1], tip_x, tip_y, k1g, mask=g!=0) print tip_x, tip_y # Get atomic strain i, j = neighbour_list("ij", a, cutoff=1.3) deformation_gradient, residual = \ atomic_strain(a, ref, neighbours=(i, j)) # Get atomic stresses # Note: get_stresses returns the virial in Atomistica! virial = a.get_stresses() virial = Voigt_6_to_full_3x3_stress(virial) # Compute J-integral epot = a.get_potential_energies() eref = np.zeros_like(epot) for r1, r2 in [(r1, r2), (r1/2, r2/2), (r1/2, r2)]: print 'r1 = {}, r2 = {}'.format(r1, r2) J = J_integral(a, deformation_gradient, virial, epot, eref, tip_x, tip_y, r1, r2) print '2*gamma = {0}, J = {1}'.format(2*surface_energy, J)
images.append(image) images.append(final) # Define the NEB and make a linear interpolation # with removing translational # and rotational degrees of freedom neb = NEB(images, remove_rotation_and_translation=remove_rotation_and_translation) neb.interpolate() # Test used these old defaults which are not optimial, but work # in this particular system neb.idpp_interpolate(fmax=0.1, optimizer=BFGS) qn = FIRE(neb, dt=0.005, maxmove=0.05, dtmax=0.1) qn.run(steps=20) # Switch to CI-NEB, still removing the external degrees of freedom # Also spesify the linearly varying spring constants neb = NEB(images, climb=True, remove_rotation_and_translation=remove_rotation_and_translation) qn = FIRE(neb, dt=0.005, maxmove=0.05, dtmax=0.1) qn.run(fmax=fmax) images = neb.images nebtools = NEBTools(images) Ef_neb, dE_neb = nebtools.get_barrier(fit=False) nsteps_neb = qn.nsteps if remove_rotation_and_translation: Ef_neb_0 = Ef_neb