def vasp2xyz(): try: from lxml import etree except ImportError: print "You need to install python-lxml." print "start parse" xml = etree.parse("vasprun.xml") calculations = xml.xpath('//calculation') print 'len(calculations)=', len(calculations) from ase.io.trajectory import PickleTrajectory atoms = io.read('POSCAR') traj = PickleTrajectory('a.traj', 'w', atoms) print "start find forces and positions" allforce = [] allpos = [] def toarr(v): x = v.text.split() return map(float, x) for i, u in enumerate(calculations): print "step : ", i forces = map(toarr, u.xpath('./varray[@name="forces"]/v')) positions = map(toarr, u.xpath( './structure/varray[@name="positions"]/v')) atoms.set_scaled_positions(positions) allforce.append(forces) allpos.append(positions) traj.write() np.save('allforce.npy', allforce) np.save('allpos.npy', allpos) passthru("ase-gui a.traj -o a.xyz ")
def fit_volume(self, name, atoms, data=None): N, x = self.fit cell0 = atoms.get_cell() v = atoms.get_volume() if x > 0: strains = np.linspace(1 - x, 1 + x, N) else: strains = np.linspace(1 + x / v, 1 - x / v, N)**(1./3) energies = [] traj = PickleTrajectory(self.get_filename(name, 'fit.traj'), 'w') for s in strains: atoms.set_cell(cell0 * s, scale_atoms=True) energies.append(atoms.get_potential_energy()) traj.write(atoms) traj.close() if data is not None: data['strains'] = strains data['energies'] = energies else: assert N % 2 == 1 data = {'energy': energies[N // 2], 'strains': strains, 'energies': energies} return data
def fit_volume(self, name, atoms, data=None): N, x = self.fit cell0 = atoms.get_cell() v = atoms.get_volume() if x > 0: strains = np.linspace(1 - x, 1 + x, N) else: strains = np.linspace(1 + x / v, 1 - x / v, N)**(1. / 3) energies = [] traj = PickleTrajectory(self.get_filename(name, 'fit.traj'), 'w') for s in strains: atoms.set_cell(cell0 * s, scale_atoms=True) energies.append(atoms.get_potential_energy()) traj.write(atoms) traj.close() if data is not None: data['strains'] = strains data['energies'] = energies else: assert N % 2 == 1 data = { 'energy': energies[N // 2], 'strains': strains, 'energies': energies } return data
def fit_bond_length(self, name, atoms, data=None): N, x = self.fit d0 = atoms.get_distance(0, 1) distances = np.linspace(d0 * (1 - x), d0 * (1 + x), N) energies = [] traj = PickleTrajectory(self.get_filename(name, 'fit.traj'), 'w') for d in distances: atoms.set_distance(0, 1, d) energies.append(atoms.get_potential_energy()) self.check_occupation_numbers(atoms) traj.write(atoms) traj.close() if data is not None: data['distances'] = distances data['energies'] = energies else: assert N % 2 == 1 data = { 'energy': energies[N // 2], 'distances': distances, 'energies': energies } return data
def write_cp2k_traj_file(self, wrkdir): pos_path = wrkdir + "/" + self.directory + "/" + "cp2k-pos-1.xyz" if os.path.exists(pos_path): traj_path = wrkdir + "/" + self.directory + "/" + self.filename + ".traj" start_atoms = self.get_initial_structure() index = 0 if not os.path.exists(traj_path): result_atoms = ase.io.read(pos_path, index) result_atoms.set_cell(start_atoms.get_cell()) result_atoms.set_pbc(start_atoms.get_pbc()) if start_atoms.constraints is not None: for constraint in start_atoms.constraints: result_atoms.set_constraint(constraint) traj = PickleTrajectory(traj_path, mode="w", atoms=result_atoms) traj.write() index = 1 traj = PickleTrajectory(traj_path, mode="a") while True: try: result_atoms = ase.io.read(pos_path, index) result_atoms.set_cell(start_atoms.get_cell()) result_atoms.set_pbc(start_atoms.get_pbc()) if start_atoms.constraints is not None: for constraint in start_atoms.constraints: result_atoms.set_constraint(constraint) traj.write(result_atoms) index += 1 except: break os.remove(pos_path) else: if self.debug: print "%s does not exist. Not writing anything." % pos_path
def eos(self, atoms, name): opts = self.opts traj = PickleTrajectory(self.get_filename(name, 'traj'), 'w', atoms) eps = 0.01 strains = np.linspace(1 - eps, 1 + eps, 5) v1 = atoms.get_volume() volumes = strains**3 * v1 energies = [] cell1 = atoms.cell for s in strains: atoms.set_cell(cell1 * s, scale_atoms=True) energies.append(atoms.get_potential_energy()) traj.write(atoms) traj.close() eos = EquationOfState(volumes, energies, opts.eos_type) v0, e0, B = eos.fit() atoms.set_cell(cell1 * (v0 / v1)**(1 / 3), scale_atoms=True) data = {'volumes': volumes, 'energies': energies, 'fitted_energy': e0, 'fitted_volume': v0, 'bulk_modulus': B, 'eos_type': opts.eos_type} return data
def breed(particles,objects,gen): sortedIndices = numpy.argsort(numpy.asarray(objects)) particlestobreed = [] explambda = numpy.log(10) / (NPsPerGen - 1) for i in range(len(particles)): trialvar = numpy.random.random() if (trialvar <= numpy.exp(-1 * explambda * i)): particlestobreed.append(particles[sortedIndices[i]]) NewGen = [] for i in range(NPsPerGen): first = numpy.random.randint(len(particlestobreed)) second = numpy.random.randint(len(particlestobreed)) gene1 = numpy.random.randint(2) gene2 = numpy.random.randint(2) if (gene1 == 0): type1 = particlestobreed[first].gene[0] else: type1 = particlestobreed[second].gene[0] if (gene2 == 0): type2 = particlestobreed[first].gene[1] else: type2 = particlestobreed[second].gene[1] if (particlestobreed[first].gene[2] < particlestobreed[second].gene[2]): minval = particlestobreed[first].gene[2] maxval = particlestobreed[second].gene[2] else: minval = particlestobreed[second].gene[2] maxval = particlestobreed[first].gene[2] numbertype1 = numpy.random.randint(minval, maxval + 1) NewGen.append(createparticle(type1,type2,numbertype1)) traj = PickleTrajectory('generation'+str(gen)+ '_' + str(i) + '.traj','w') NewGen[i].gene = (type1,type2,numbertype1) traj.write(ParticleList[i]) traj.close() return NewGen
def accept_move(self): e = self.atoms.get_potential_energy() self.lists['energy'].append(e) self.lists['counts'].append(1) self.lists['coordinations'].append(self.sumcoordinations(self.surfmove.coordinations)) self.lists['types'].append(self.sumcoordinations(self.surfmove.types)) #See sumcoordinations self.lists['vac_coordinations'].append(self.sumcoordinations(self.surfmove.vacant_coordinations)) self.lists['vac_types'].append(self.sumcoordinations(self.surfmove.vacant_types)) if self.mc_step>=self.total_steps/2: if self.id_relax == None: self.id_relax = self.n_accept unrelax_energy, relax_energy = self.relax() self.lists['unrelaxed_energies'].append(unrelax_energy) self.lists['relaxed_energies'].append(relax_energy) e += relax_energy - unrelax_energy if e < self.ground_state_energy: #now store .amc in tmpfn[1] and 0000* in tmpfn[0] tmpfn = self.filename.split(".") traj = PickleTrajectory(tmpfn[0]+".traj", 'w', self.atoms, master=True, backup=False) traj.write() traj.close() #write(filename=tmpfn[0]+".traj",images=self.atoms) self.ground_state_energy = e else: self.lists['unrelaxed_energies'].append(np.nan) self.lists['relaxed_energies'].append(np.nan) self.mc_step += 1 self.n_accept += 1
def vasp2xyz(): try: from lxml import etree except ImportError: print "You need to install python-lxml." print "start parse" xml = etree.parse("vasprun.xml") calculations = xml.xpath('//calculation') print 'len(calculations)=', len(calculations) from ase.io.trajectory import PickleTrajectory atoms = io.read('POSCAR') traj = PickleTrajectory('a.traj', 'w', atoms) print "start find forces and positions" allforce = [] allpos = [] def toarr(v): x = v.text.split() return map(float, x) for i, u in enumerate(calculations): print "step : ", i forces = map(toarr, u.xpath('./varray[@name="forces"]/v')) positions = map(toarr, u.xpath('./structure/varray[@name="positions"]/v')) atoms.set_scaled_positions(positions) allforce.append(forces) allpos.append(positions) traj.write() np.save('allforce.npy', allforce) np.save('allpos.npy', allpos) passthru("ase-gui a.traj -o a.xyz ")
def _test_timestepping(self, t): #XXX DEBUG START if debug and os.path.isfile('%s_%d.gpw' % (self.tdname, t)): return #XXX DEBUG END timestep = self.timesteps[t] self.assertAlmostEqual(self.duration % timestep, 0.0, 12) niter = int(self.duration / timestep) ndiv = 1 #XXX traj = PickleTrajectory('%s_%d.traj' % (self.tdname, t), 'w', self.tdcalc.get_atoms()) t0 = time.time() f = paropen('%s_%d.log' % (self.tdname, t), 'w') print('propagator: %s, duration: %6.1f as, timestep: %5.2f as, ' \ 'niter: %d' % (self.propagator, self.duration, timestep, niter), file=f) for i in range(1, niter + 1): # XXX bare bones propagation without all the nonsense self.tdcalc.propagator.propagate(self.tdcalc.time, timestep * attosec_to_autime) self.tdcalc.time += timestep * attosec_to_autime self.tdcalc.niter += 1 if i % ndiv == 0: rate = 60 * ndiv / (time.time() - t0) ekin = self.tdcalc.atoms.get_kinetic_energy() epot = self.tdcalc.get_td_energy() * Hartree F_av = np.zeros((len(self.tdcalc.atoms), 3)) print('i=%06d, time=%6.1f as, rate=%6.2f min^-1, ' \ 'ekin=%13.9f eV, epot=%13.9f eV, etot=%13.9f eV' \ % (i, timestep * i, rate, ekin, epot, ekin + epot), file=f) t0 = time.time() # Hack to prevent calls to GPAW::get_potential_energy when saving spa = self.tdcalc.get_atoms() spc = SinglePointCalculator(epot, F_av, None, None, spa) spa.set_calculator(spc) traj.write(spa) f.close() traj.close() self.tdcalc.write('%s_%d.gpw' % (self.tdname, t), mode='all') # Save density and wavefunctions to binary gd, finegd = self.tdcalc.wfs.gd, self.tdcalc.density.finegd if world.rank == 0: big_nt_g = finegd.collect(self.tdcalc.density.nt_g) np.save('%s_%d_nt.npy' % (self.tdname, t), big_nt_g) del big_nt_g big_psit_nG = gd.collect(self.tdcalc.wfs.kpt_u[0].psit_nG) np.save('%s_%d_psit.npy' % (self.tdname, t), big_psit_nG) del big_psit_nG else: finegd.collect(self.tdcalc.density.nt_g) gd.collect(self.tdcalc.wfs.kpt_u[0].psit_nG) world.barrier()
def _test_timestepping(self, t): #XXX DEBUG START if debug and os.path.isfile('%s_%d.gpw' % (self.tdname, t)): return #XXX DEBUG END timestep = self.timesteps[t] self.assertAlmostEqual(self.duration % timestep, 0.0, 12) niter = int(self.duration / timestep) ndiv = 1 #XXX traj = PickleTrajectory('%s_%d.traj' % (self.tdname, t), 'w', self.tdcalc.get_atoms()) t0 = time.time() f = paropen('%s_%d.log' % (self.tdname, t), 'w') print >>f, 'propagator: %s, duration: %6.1f as, timestep: %5.2f as, ' \ 'niter: %d' % (self.propagator, self.duration, timestep, niter) for i in range(1, niter+1): # XXX bare bones propagation without all the nonsense self.tdcalc.propagator.propagate(self.tdcalc.time, timestep * attosec_to_autime) self.tdcalc.time += timestep * attosec_to_autime self.tdcalc.niter += 1 if i % ndiv == 0: rate = 60 * ndiv / (time.time()-t0) ekin = self.tdcalc.atoms.get_kinetic_energy() epot = self.tdcalc.get_td_energy() * Hartree F_av = np.zeros((len(self.tdcalc.atoms), 3)) print >>f, 'i=%06d, time=%6.1f as, rate=%6.2f min^-1, ' \ 'ekin=%13.9f eV, epot=%13.9f eV, etot=%13.9f eV' \ % (i, timestep * i, rate, ekin, epot, ekin + epot) t0 = time.time() # Hack to prevent calls to GPAW::get_potential_energy when saving spa = self.tdcalc.get_atoms() spc = SinglePointCalculator(epot, F_av, None, None, spa) spa.set_calculator(spc) traj.write(spa) f.close() traj.close() self.tdcalc.write('%s_%d.gpw' % (self.tdname, t), mode='all') # Save density and wavefunctions to binary gd, finegd = self.tdcalc.wfs.gd, self.tdcalc.density.finegd if world.rank == 0: big_nt_g = finegd.collect(self.tdcalc.density.nt_g) np.save('%s_%d_nt.npy' % (self.tdname, t), big_nt_g) del big_nt_g big_psit_nG = gd.collect(self.tdcalc.wfs.kpt_u[0].psit_nG) np.save('%s_%d_psit.npy' % (self.tdname, t), big_psit_nG) del big_psit_nG else: finegd.collect(self.tdcalc.density.nt_g) gd.collect(self.tdcalc.wfs.kpt_u[0].psit_nG) world.barrier()
def do_calculations(self, formulas): """Perform calculation on molecules, write results to .gpw files.""" atoms = {} for formula in formulas: for symbol in string2symbols(formula.split('_')[0]): atoms[symbol] = None formulas = formulas + atoms.keys() for formula in formulas: if path.isfile(formula + '.gpw'): continue barrier() open(formula + '.gpw', 'w') s = molecule(formula) s.center(vacuum=self.vacuum) cell = s.get_cell() h = self.h s.set_cell((cell / (4 * h)).round() * 4 * h) s.center() calc = GPAW(h=h, xc=self.xc, eigensolver=self.eigensolver, setups=self.setups, basis=self.basis, fixmom=True, txt=formula + '.txt') if len(s) == 1: calc.set(hund=True) s.set_calculator(calc) if formula == 'BeH': calc.initialize(s) calc.nuclei[0].f_si = [(1, 0, 0.5, 0, 0), (0.5, 0, 0, 0, 0)] if formula in ['NO', 'ClO', 'CH']: s.positions[:, 1] += h * 1.5 try: energy = s.get_potential_energy() except (RuntimeError, ConvergenceError): if rank == 0: print >> sys.stderr, 'Error in', formula traceback.print_exc(file=sys.stderr) else: print >> self.txt, formula, repr(energy) self.txt.flush() calc.write(formula) if formula in diatomic and self.calculate_dimer_bond_lengths: traj = PickleTrajectory(formula + '.traj', 'w') d = diatomic[formula][1] for x in range(-2, 3): s.set_distance(0, 1, d * (1.0 + x * 0.02)) traj.write(s)
def mainBasinLoop(symbol1, symbol2, elementN1, elementN2, numberOfType1, numberOfType2, radius, percentType1): """symbol1 and symbol2 should be STRINGS. elementN1 and elementN2 should be ATOMIC NUMBERS of those elements. numberOfType1 and numberOfType2 are the actual # of those atoms in the molecule radius can be a decimal percent should be expressed as a number between 0 and 1. After that, it will create five new sets of 400 molecules, each set being the result of that first set having one of our small perturbations performed on it, which are also then minimized, perturbed, etc., until 50,000 total original orientations have been minimized.""" bigKickResults, round1PE = [], [] global finalList creationString = symbol1 + str(numberOfType1) + symbol2 + str(numberOfType2) creationString2 = creationString + '.traj' baseAtom = nearlySphericalAtom(str(creationString),radius,numberOfType1+numberOfType2) baseAtom.set_pbc((1,1,1)) baseAtom.set_cell((100,100,100)) calc = QSC() baseAtom.set_calculator(calc) baseAtom = makeBimetallic(baseAtom,numberOfType1+numberOfType2,elementN1,elementN2,percentType1) baseAtom = preventExplosions(baseAtom) baseAtom = preventExplosions(baseAtom) for x in range(listLength): bigKickResults.append(baseAtom.copy()) for x in range(listLength/2): bigKickResults[x] = shake(bigKickResults[x]) for x in range(listLength/2, listLength): bigKickResults[x] = switchAtoms(bigKickResults[x]) for x in range(len(bigKickResults)): bigKickResults[x] = optimizeMolecule(bigKickResults[x],FIREMoves,creationString2) round1PE.append(bigKickResults[x].get_potential_energy()) minimumPE = min(round1PE) minimumIndex = round1PE.index(minimumPE) bestAtom = bigKickResults[minimumIndex] minimaList = PickleTrajectory(str(creationString2),mode='a') minimaList.write(bestAtom) minimaList.close() finalList.append(bestAtom.copy()) smallKicks(bigKickResults,0,creationString2) veryBestAtom = returnFinalBestAtom(str(creationString2), str(creationString)) return veryBestAtom
def write_optimized(self, atoms, energy): magmoms = None # XXX we could do better ... forces = np.zeros((len(atoms), 3)) calc = SinglePointCalculator(energy, forces, np.zeros((3, 3)), magmoms, atoms) atoms.set_calculator(calc) filename = '%s%s-optimized.traj' % (self.name, self.tag) traj = PickleTrajectory(filename, 'w', backup=False) traj.write(atoms) traj.close()
def write_mode(self, n, kT=units.kB * 300, nimages=30): """Write mode to trajectory file.""" mode = self.get_mode(n) * sqrt(kT / self.hnu[n]) p = self.atoms.positions.copy() n %= 3 * len(self.indices) traj = PickleTrajectory('%s.%d.traj' % (self.name, n), 'w') calc = self.atoms.get_calculator() self.atoms.set_calculator() for x in np.linspace(0, 2 * pi, nimages, endpoint=False): self.atoms.set_positions(p + sin(x) * mode) traj.write(self.atoms) self.atoms.set_positions(p) self.atoms.set_calculator(calc) traj.close()
def fit_bond_length(self, name, atoms, data): N, x = self.fit assert N % 2 == 1 d0 = atoms.get_distance(0, 1) distances = np.linspace(d0 * (1 - x), d0 * (1 + x), N) energies = [] traj = PickleTrajectory(self.get_filename(name, 'fit.traj'), 'w') for d in distances: atoms.set_distance(0, 1, d) energies.append(atoms.get_potential_energy()) self.check_occupation_numbers(atoms) traj.write(atoms) traj.close() data['distances'] = distances data['energies'] = energies
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 append_equilibrium_trajectory(self, weight, calc, traj, comment=None, label=None, color=None): """ Calculates the V'rep(r) from a given equilibrium trajectory. The trajectory is set of three (or more, albeit not necessary) frames where atoms move near their equilibrium structure. To first approximation, the energies of these frames ARE THE SAME. This method is then equivalent to append_energy_curve method for given trajectory, with a flat energy curve. * Atoms should move as parallel to the fitted bonds as possible. * Amplitude should be small enough (say, 0.01 Angstroms) parameters: =========== weight: fitting weight calc: Hotbit calculator (remember charge and k-points) traj: filename for ASE trajectory (energies need not be defined) comment: fitting comment for par-file (replaced by comment if None) label: plotting label (replaced by comment if None) color: plotting color """ traj1 = PickleTrajectory(traj) atoms2 = traj1[0].copy() calc2 = NullCalculator() atoms2.set_calculator(calc2) tmpfile = '_tmp.traj' traj2 = PickleTrajectory(tmpfile, 'w', atoms2) for atoms1 in traj1: atoms2.set_positions(atoms1.get_positions()) atoms2.set_cell(atoms1.get_cell()) atoms2.get_potential_energy() traj2.write() traj2.close() self.append_energy_curve(weight, calc, tmpfile, comment, label, color) os.remove(tmpfile) if os.path.isfile(tmpfile + '.bak'): os.remove(tmpfile + '.bak')
def fit_volume(self, name, atoms): N, x = self.fit cell0 = atoms.get_cell() strains = np.linspace(1 - x, 1 + x, N) energies = [] traj = PickleTrajectory(self.get_filename(name, 'fit.traj'), 'w') for s in strains: atoms.set_cell(cell0 * s, scale_atoms=True) energies.append(atoms.get_potential_energy()) traj.write(atoms) traj.close() assert N % 2 == 1 data = {'energy': energies[N // 2], 'strains': strains, 'energies': energies} return data
def calculate(self, filename): """Run calculation and write results to file.""" self.log('Calculating', self.name, '...') config = self.atoms.copy() self.set_calculator(config, filename) traj = PickleTrajectory(filename, 'w', backup=False) cell = config.get_cell() self.energies = [] if self.fmax is not None: if (not config.constraints and not config.positions.any(axis=1).all()): # one atom is at (0,0,0) - fix it: mask = np.logical_not(config.positions.any(axis=1)) config.constraints = FixAtoms(mask=mask) dyn = LBFGS(config) dyn.attach(traj, 1, config) dyn.run(fmax=self.fmax) e = config.get_potential_energy() self.post_process(config) self.energies.append(e) elif not config.pbc.any() and len(config) == 2: # This is a dimer. self.bondlengths = [] d0 = config.get_distance(0, 1) for strain in self.strains: d = d0 * strain config.set_distance(0, 1, d) self.bondlengths.append(d) e = config.get_potential_energy() self.energies.append(e) self.post_process(config) traj.write(config) else: self.volumes = [] for strain in self.strains: config.set_cell(strain * cell, scale_atoms=True) self.volumes.append(config.get_volume()) e = config.get_potential_energy() self.energies.append(e) self.post_process(config) traj.write(config) return config
def get_corrugation_energy(atoms, constraints, bond, bottom, top, indent, m): if 'zz' in indent: xset = np.linspace(0., np.sqrt(3)*bond, m) elif 'arm' in indent: xset = np.linspace(0., 3*bond, m) atoms_init = atoms.copy() natoms = 0 for i in range(len(top)): if top[i]: natoms += 1 fix_l = FixedLine(i, [0., 0., 1.]) constraints.append(fix_l) atoms.set_constraint(constraints) def get_epot(x): new_pos = atoms_init.positions.copy() for iat in range(len(atoms)): if top[iat]: new_pos[iat][0] += x atoms.positions = new_pos e, hmin = get_optimal_h(atoms, bottom, top, natoms, False) #print x, e return e, hmin # Start to move the top layer in x direction corr_pot = np.zeros((len(xset), 3)) traj = PickleTrajectory(path + \ 'trajectories/corrugation_trajectory_%s.traj' %(indent), "w", atoms) for i, x in enumerate(xset): traj.write(get_save_atoms(atoms)) e, hmin = get_epot(x) corr_pot[i] = [x, hmin, e] np.savetxt(path + 'datas/corrugation_data_%s.data' %(indent), corr_pot) return corr_pot
def write_mode(self, n=None, kT=units.kB * 300, nimages=30): """Write mode number n to trajectory file. If n is not specified, writes all non-zero modes.""" if n == None: for index, energy in enumerate(self.get_energies()): if abs(energy) > 1e-5: self.write_mode(n=index, kT=kT, nimages=nimages) return mode = self.get_mode(n) * sqrt(kT / abs(self.hnu[n])) p = self.atoms.positions.copy() n %= 3 * len(self.indices) traj = PickleTrajectory('%s.%d.traj' % (self.name, n), 'w') calc = self.atoms.get_calculator() self.atoms.set_calculator() for x in np.linspace(0, 2 * pi, nimages, endpoint=False): self.atoms.set_positions(p + sin(x) * mode) traj.write(self.atoms) self.atoms.set_positions(p) self.atoms.set_calculator(calc) traj.close()
def append_equilibrium_trajectory(self,weight,calc,traj,comment=None,label=None,color=None): """ Calculates the V'rep(r) from a given equilibrium trajectory. The trajectory is set of three (or more, albeit not necessary) frames where atoms move near their equilibrium structure. To first approximation, the energies of these frames ARE THE SAME. This method is then equivalent to append_energy_curve method for given trajectory, with a flat energy curve. * Atoms should move as parallel to the fitted bonds as possible. * Amplitude should be small enough (say, 0.01 Angstroms) parameters: =========== weight: fitting weight calc: Hotbit calculator (remember charge and k-points) traj: filename for ASE trajectory (energies need not be defined) comment: fitting comment for par-file (replaced by comment if None) label: plotting label (replaced by comment if None) color: plotting color """ traj1 = PickleTrajectory(traj) atoms2 = traj1[0].copy() calc2 = NullCalculator() atoms2.set_calculator(calc2) tmpfile = '_tmp.traj' traj2 = PickleTrajectory(tmpfile,'w',atoms2) for atoms1 in traj1: atoms2.set_positions(atoms1.get_positions()) atoms2.set_cell( atoms1.get_cell() ) atoms2.get_potential_energy() traj2.write() traj2.close() self.append_energy_curve(weight,calc,tmpfile,comment,label,color) os.remove(tmpfile) if os.path.isfile(tmpfile+'.bak'): os.remove(tmpfile+'.bak')
def accept_move(self): e = self.atoms.get_potential_energy() self.lists['energy'].append(e) self.lists['counts'].append(1) self.lists['coordinations'].append( self.sumcoordinations(self.surfmove.coordinations)) self.lists['types'].append(self.sumcoordinations( self.surfmove.types)) #See sumcoordinations self.lists['vac_coordinations'].append( self.sumcoordinations(self.surfmove.vacant_coordinations)) self.lists['vac_types'].append( self.sumcoordinations(self.surfmove.vacant_types)) if self.mc_step >= self.total_steps / 2: if self.id_relax == None: self.id_relax = self.n_accept unrelax_energy, relax_energy = self.relax() self.lists['unrelaxed_energies'].append(unrelax_energy) self.lists['relaxed_energies'].append(relax_energy) e += relax_energy - unrelax_energy if e < self.ground_state_energy: #now store .amc in tmpfn[1] and 0000* in tmpfn[0] tmpfn = self.filename.split(".") traj = PickleTrajectory(tmpfn[0] + ".traj", 'w', self.atoms, master=True, backup=False) traj.write() traj.close() #write(filename=tmpfn[0]+".traj",images=self.atoms) self.ground_state_energy = e else: self.lists['unrelaxed_energies'].append(np.nan) self.lists['relaxed_energies'].append(np.nan) self.mc_step += 1 self.n_accept += 1
def get_adhesion_energy(atoms, hmax, bottom, top, indent, m): zmax = np.amax(atoms.positions[bottom][:,2]) natoms = 0 for i in range(len(top)): if top[i]: natoms += 1 def get_epot(z): new_pos = atoms.positions.copy() for iat in range(len(atoms)): if top[iat]: new_pos[iat][2] = z atoms.positions = new_pos e = atoms.get_potential_energy()/natoms print z - zmax, e return e # Start to move the top layer in z direction zrange = np.linspace(h - .7, h + hmax, m) adh_pot = np.zeros((len(zrange), 2)) traj = PickleTrajectory(path + \ 'trajectories/adhesion_trajectory_%s.traj' %(indent), "w", atoms) # Here we lift the top layer: for i, z in enumerate(zrange): traj.write(get_save_atoms(atoms)) adh_pot[i] = [z, get_epot(zmax + z)] np.savetxt(path + 'datas/adhesion_data_%s.data' %(indent), adh_pot) return adh_pot
def breed(particles, objects, gen): sortedIndices = numpy.argsort(numpy.asarray(objects)) particlestobreed = [] explambda = numpy.log(10) / (NPsPerGen - 1) for i in range(len(particles)): trialvar = numpy.random.random() if (trialvar <= numpy.exp(-1 * explambda * i)): particlestobreed.append(particles[sortedIndices[i]]) NewGen = [] for i in range(NPsPerGen): first = numpy.random.randint(len(particlestobreed)) second = numpy.random.randint(len(particlestobreed)) gene1 = numpy.random.randint(2) gene2 = numpy.random.randint(2) if (gene1 == 0): type1 = particlestobreed[first].gene[0] else: type1 = particlestobreed[second].gene[0] if (gene2 == 0): type2 = particlestobreed[first].gene[1] else: type2 = particlestobreed[second].gene[1] if (particlestobreed[first].gene[2] < particlestobreed[second].gene[2]): minval = particlestobreed[first].gene[2] maxval = particlestobreed[second].gene[2] else: minval = particlestobreed[second].gene[2] maxval = particlestobreed[first].gene[2] numbertype1 = numpy.random.randint(minval, maxval + 1) NewGen.append(createparticle(type1, type2, numbertype1)) traj = PickleTrajectory( 'generation' + str(gen) + '_' + str(i) + '.traj', 'w') NewGen[i].gene = (type1, type2, numbertype1) traj.write(ParticleList[i]) traj.close() return NewGen
def fit_bond_length(self, name, atoms, data=None): N, x = self.fit d0 = atoms.get_distance(0, 1) distances = np.linspace(d0 * (1 - x), d0 * (1 + x), N) energies = [] traj = PickleTrajectory(self.get_filename(name, 'fit.traj'), 'w') for d in distances: atoms.set_distance(0, 1, d) energies.append(atoms.get_potential_energy()) self.check_occupation_numbers(atoms) traj.write(atoms) traj.close() if data is not None: data['distances'] = distances data['energies'] = energies else: assert N % 2 == 1 data = {'energy': energies[N // 2], 'distances': distances, 'energies': energies} return data
from numpy import linspace from ase.calculators.fleur import FLEUR from ase.lattice import bulk from ase.io.trajectory import PickleTrajectory atoms = bulk('Ni', a=3.52) calc = FLEUR(xc='PBE', kmax=3.6, kpts=(10, 10, 10), workdir='lat_const') atoms.set_calculator(calc) traj = PickleTrajectory('Ni.traj','w', atoms) cell0 = atoms.get_cell() for s in linspace(0.95, 1.05, 7): cell = cell0 * s atoms.set_cell((cell)) ene = atoms.get_potential_energy() traj.write()
def write(self, filename): from ase.io.trajectory import PickleTrajectory traj = PickleTrajectory(filename, 'w', self) traj.write() traj.close()
while not os.path.isfile(name + '_gs.gpw'): print('Node %d waiting for file...' % world.rank) time.sleep(10) world.barrier() tdcalc = TDDFT(name + '_gs.gpw', txt=name + '_td.txt', propagator='EFSICN') ehrenfest = EhrenfestVelocityVerlet(tdcalc) traj = PickleTrajectory(name + '_td.traj', 'w', tdcalc.get_atoms()) t0 = time.time() f = paropen(name + '_td.log', 'w') for i in range(1, niter+1): ehrenfest.propagate(timestep) if i % ndiv == 0: rate = 60 * ndiv / (time.time()-t0) ekin = tdcalc.atoms.get_kinetic_energy() epot = tdcalc.get_td_energy() * Hartree F_av = ehrenfest.F * Hartree / Bohr print('i=%06d (%6.2f min^-1), ekin=%13.9f, epot=%13.9f, etot=%13.9f' % (i, rate, ekin, epot, ekin+epot), file=f) t0 = time.time() # Hack to prevent calls to GPAW::get_potential_energy when saving spa = tdcalc.get_atoms() spc = SinglePointCalculator(epot, F_av, None, None, spa) spa.set_calculator(spc) traj.write(spa) f.close() traj.close()
def write_modes(self, q_c, branches=0, kT=units.kB*300, repeat=(1, 1, 1), nimages=30, acoustic=True): """Write mode to trajectory file. The classical equipartioning theorem states that each normal mode has an average energy:: <E> = 1/2 * k_B * T = 1/2 * omega^2 * Q^2 => Q = sqrt(k_B*T) / omega at temperature T. Here, Q denotes the normal coordinate of the mode. Parameters ---------- q_c: ndarray q-vector of the modes. branches: int or list Branch index of calculated modes. kT: float Temperature in units of eV. Determines the amplitude of the atomic displacements in the modes. repeat: tuple Repeat atoms (l, m, n) times in the directions of the lattice vectors. Displacements of atoms in repeated cells carry a Bloch phase factor given by the q-vector and the cell lattice vector R_m. nimages: int Number of images in an oscillation. """ if isinstance(branches, int): branch_n = [branches] else: branch_n = list(branches) # Calculate modes omega_n, u_n = self.band_structure([q_c], modes=True, acoustic=acoustic) # Repeat atoms atoms = self.atoms * repeat pos_mav = atoms.positions.copy() # Total number of unit cells M = np.prod(repeat) # Corresponding lattice vectors R_m R_cm = np.indices(repeat[::-1]).reshape(3, -1)[::-1] # Bloch phase phase_m = np.exp(2.j * pi * np.dot(q_c, R_cm)) phase_ma = phase_m.repeat(len(self.atoms)) for n in branch_n: omega = omega_n[0, n] u_av = u_n[0, n] # .reshape((-1, 3)) # Mean displacement at high T ? u_av *= sqrt(kT / abs(omega)) mode_av = np.zeros((len(self.atoms), 3), dtype=self.dtype) indices = self.dyn.get_indices() mode_av[indices] = u_av mode_mav = (np.vstack([mode_av]*M) * phase_ma[:, np.newaxis]).real traj = PickleTrajectory('%s.mode.%d.traj' % (self.name, n), 'w') for x in np.linspace(0, 2*pi, nimages, endpoint=False): # XXX Is it correct to take out the sine component here ? atoms.set_positions(pos_mav + sin(x) * mode_mav) traj.write(atoms) traj.close()
tdcalc = TDDFT(name + '_esx.gpw', txt=name + '_td.txt', propagator='EFSICN') ehrenfest = EhrenfestVelocityVerlet(tdcalc) traj = PickleTrajectory(name + '_td.traj', 'w', tdcalc.get_atoms()) t0 = time.time() f = paropen(name + '_td.log', 'w') for i in range(1, niter + 1): ehrenfest.propagate(timestep) if i % ndiv == 0: rate = 60 * ndiv / (time.time() - t0) ekin = tdcalc.atoms.get_kinetic_energy() epot = tdcalc.get_td_energy() * Hartree F_av = ehrenfest.F * Hartree / Bohr print( 'i=%06d (%6.2f min^-1), ekin=%13.9f, epot=%13.9f, etot=%13.9f' % (i, rate, ekin, epot, ekin + epot), file=f) t0 = time.time() # Hack to prevent calls to GPAW::get_potential_energy when saving spa = tdcalc.get_atoms() spc = SinglePointCalculator(epot, F_av, None, None, spa) spa.set_calculator(spc) traj.write(spa) f.close() traj.close()
ParticleList = [] CostList = [] CohesiveList = [] f.write("Generation 0 " + "\n") for j in range(NPsPerGen): type1 = numpy.random.randint(1, 9) type2 = numpy.random.randint(1, 9) numbertype1 = numpy.random.randint(86) ParticleList.append( createparticle(ElementsDictionary[type1], ElementsDictionary[type2], numbertype1)) ParticleList[j].gene = (ElementsDictionary[type1], ElementsDictionary[type2], numbertype1) filename = 'generation0_' + str(j) + ".traj" traj = PickleTrajectory(filename, 'w') traj.write(ParticleList[j]) traj.close() CostList.append(totalCost(ParticleList[j])) CohesiveList.append(coreshellCohesive(ParticleList[j])) traj.close() for i in range(generations): ObjectFunction = [] CostList = [] CohesiveList = [] for j in range(NPsPerGen): CostList.append(totalCost(ParticleList[j])) CohesiveList.append(coreshellCohesive(ParticleList[j])) costpart = (CostList[j] - Mincost) * 0.1 cohesivepart = numpy.abs(CohesiveList[j] - Ptcohesive) ObjectFunction.append(FractionCost * costpart +
def write_modes(self, q_c, branches=0, kT=units.kB*300, born=False, repeat=(1, 1, 1), nimages=30, center=False): """Write modes to trajectory file. Parameters ---------- q_c: ndarray q-vector of modes. branches: int or list Branch index of modes. kT: float Temperature in units of eV. Determines the amplitude of the atomic displacements in the modes. born: bool Include non-analytic contribution to the force constants at q -> 0. repeat: tuple Repeat atoms (l, m, n) times in the directions of the lattice vectors. Displacements of atoms in repeated cells carry a Bloch phase factor given by the q-vector and the cell lattice vector R_m. nimages: int Number of images in an oscillation. center: bool Center atoms in unit cell if True (default: False). """ if isinstance(branches, int): branch_n = [branches] else: branch_n = list(branches) # Calculate modes omega_n, u_n = self.band_structure([q_c], modes=True, born=born) print omega_n # Repeat atoms atoms = self.atoms * repeat # Center if center: atoms.center() # Here ma refers to a composite unit cell/atom dimension pos_mav = atoms.get_positions() # Total number of unit cells M = np.prod(repeat) # Corresponding lattice vectors R_m R_cm = np.indices(repeat).reshape(3, -1) # Bloch phase phase_m = np.exp(2.j * pi * np.dot(q_c, R_cm)) phase_ma = phase_m.repeat(len(self.atoms)) for n in branch_n: omega = omega_n[0, n] u_av = u_n[0, n] # Mean displacement of a classical oscillator at temperature T u_av *= sqrt(kT) / abs(omega) mode_av = np.zeros((len(self.atoms), 3), dtype=complex) # Insert slice with atomic displacements for the included atoms mode_av[self.indices] = u_av # Repeat and multiply by Bloch phase factor mode_mav = (np.vstack([mode_av]*M) * phase_ma[:, np.newaxis]).real traj = PickleTrajectory('%s.mode.%d.traj' % (self.name, n), 'w') for x in np.linspace(0, 2*pi, nimages, endpoint=False): atoms.set_positions(pos_mav + sin(x) * mode_mav) traj.write(atoms) traj.close()
def smallKicks(moleculeList, inTreeLevel, creationString): inTreeLevel += 1 global finalList if inTreeLevel == treeDepth: return None else: list1, list2, list3, list4, list5 = [],[],[],[],[] p1, p2, p3, p4, p5 = [],[],[],[],[] nAtoms = moleculeList[0].get_number_of_atoms() #they should all have the same number for x in range(len(moleculeList)): list1.append(moleculeList[x].copy()) list2.append(moleculeList[x].copy()) list3.append(moleculeList[x].copy()) list4.append(moleculeList[x].copy()) list5.append(moleculeList[x].copy()) for x in range(len(list1)): #but they should all be the same length list1[x] = shell_move(list1[x],random.randint(0,nAtoms)) list2[x] = HighEnergyMove(list2[x]) list3[x] = ball_move(list3[x],random.randint(0,nAtoms)) list4[x] = smallSwitchAtoms(list4[x]) list5[x] = moveAtoms(2,list5[x]) for x in range(len(list1)): #again, should all be the same length list1[x] = optimizeMolecule(list1[x],FIREMoves,creationString) list2[x] = optimizeMolecule(list2[x],FIREMoves,creationString) list3[x] = optimizeMolecule(list3[x],FIREMoves,creationString) list4[x] = optimizeMolecule(list4[x],FIREMoves,creationString) list5[x] = optimizeMolecule(list5[x],FIREMoves,creationString) del moleculeList[:] del moleculeList #This is also decidedly unpythonic for x in range(len(list1)): p1.append(list1[x].get_potential_energy()) p2.append(list2[x].get_potential_energy()) p3.append(list3[x].get_potential_energy()) p4.append(list4[x].get_potential_energy()) p5.append(list5[x].get_potential_energy()) #p1min = (MIN)imum PE. p1mi = (M)inimum (I)ndex. p1b = (B)est. p1min, p2min, p3min, p4min, p5min = min(p1),min(p2),min(p3),min(p4),min(p5) p1mi, p2mi, p3mi, p4mi, p5mi = p1.index(p1min), p2.index(p2min), p3.index(p3min), p4.index(p4min), p5.index(p5min) p1b, p2b, p3b, p4b, p5b = list1[p1mi],list2[p2mi],list3[p3mi],list4[p4mi],list5[p5mi] minimaList = PickleTrajectory(str(creationString),mode='a') minimaList.write(p1b) minimaList.write(p2b) minimaList.write(p3b) minimaList.write(p4b) minimaList.write(p5b) minimaList.close() if p1min < finalList[len(finalList)-1]: finalList.append(p1b.copy()) if p2min < finalList[len(finalList)-1]: finalList.append(p2b.copy()) if p3min < finalList[len(finalList)-1]: finalList.append(p3b.copy()) if p4min < finalList[len(finalList)-1]: finalList.append(p4b.copy()) if p5min < finalList[len(finalList)-1]: finalList.append(p5b.copy()) smallKicks(list1,inTreeLevel,creationString) smallKicks(list2,inTreeLevel,creationString) smallKicks(list3,inTreeLevel,creationString) smallKicks(list4,inTreeLevel,creationString) smallKicks(list5,inTreeLevel,creationString)
Mincost=totalCost(atoms) # set up generation 1 ParticleList = [] CostList = [] CohesiveList = [] f.write("Generation 0 " + "\n") for j in range(NPsPerGen): type1 = numpy.random.randint(1,9) type2 = numpy.random.randint(1,9) numbertype1 = numpy.random.randint(86) ParticleList.append(createparticle(ElementsDictionary[type1],ElementsDictionary[type2],numbertype1)) ParticleList[j].gene = (ElementsDictionary[type1],ElementsDictionary[type2],numbertype1) filename = 'generation0_' + str(j) + ".traj" traj = PickleTrajectory(filename,'w') traj.write(ParticleList[j]) traj.close() CostList.append(totalCost(ParticleList[j])) CohesiveList.append(coreshellCohesive(ParticleList[j])) traj.close() for i in range(generations): ObjectFunction = [] CostList = [] CohesiveList = [] for j in range(NPsPerGen): CostList.append(totalCost(ParticleList[j])) CohesiveList.append(coreshellCohesive(ParticleList[j])) costpart = (CostList[j] - Mincost) * 0.1 cohesivepart = numpy.abs(CohesiveList[j] - Ptcohesive) ObjectFunction.append(FractionCost * costpart + (1 - FractionCost) * cohesivepart)
class BasinHopping(Dynamics): """Basin hopping algorythm. After Wales and Doye, J. Phys. Chem. A, vol 101 (1997) 5111-5116 and David J. Wales and Harold A. Scheraga, Science, Vol. 285, 1368 (1999) """ def __init__(self, atoms, temperature=100 * kB, optimizer=FIRE, fmax=0.1, dr=0.1, logfile='-', trajectory='lowest.traj', optimizer_logfile='-', local_minima_trajectory='local_minima.traj', adjust_cm=True): """Parameters: atoms: Atoms object The Atoms object to operate on. trajectory: string Pickle file used to store trajectory of atomic movement. logfile: file object or str If *logfile* is a string, a file with that name will be opened. Use '-' for stdout. """ Dynamics.__init__(self, atoms, logfile, trajectory) self.kT = temperature self.optimizer = optimizer self.fmax = fmax self.dr = dr if adjust_cm: self.cm = atoms.get_center_of_mass() else: self.cm = None self.optimizer_logfile = optimizer_logfile self.lm_trajectory = local_minima_trajectory if isinstance(local_minima_trajectory, str): self.lm_trajectory = PickleTrajectory(local_minima_trajectory, 'w', atoms) self.initialize() def initialize(self): self.positions = 0.0 * self.atoms.get_positions() self.Emin = self.get_energy(self.atoms.get_positions()) or 1.e32 self.rmin = self.atoms.get_positions() self.positions = self.atoms.get_positions() self.call_observers() self.log(-1, self.Emin, self.Emin) def run(self, steps): """Hop the basins for defined number of steps.""" ro = self.positions Eo = self.get_energy(ro) for step in range(steps): En = None while En is None: rn = self.move(ro) En = self.get_energy(rn) if En < self.Emin: # new minimum found self.Emin = En self.rmin = self.atoms.get_positions() self.call_observers() self.log(step, En, self.Emin) accept = np.exp((Eo - En) / self.kT) > np.random.uniform() if accept: ro = rn.copy() Eo = En def log(self, step, En, Emin): if self.logfile is None: return name = self.__class__.__name__ self.logfile.write('%s: step %d, energy %15.6f, emin %15.6f\n' % (name, step, En, Emin)) self.logfile.flush() def move(self, ro): """Move atoms by a random step.""" atoms = self.atoms # displace coordinates disp = np.random.uniform(-1., 1., (len(atoms), 3)) rn = ro + self.dr * disp atoms.set_positions(rn) if self.cm is not None: cm = atoms.get_center_of_mass() atoms.translate(self.cm - cm) rn = atoms.get_positions() world.broadcast(rn, 0) atoms.set_positions(rn) return atoms.get_positions() def get_minimum(self): """Return minimal energy and configuration.""" atoms = self.atoms.copy() atoms.set_positions(self.rmin) return self.Emin, atoms def get_energy(self, positions): """Return the energy of the nearest local minimum.""" if np.sometrue(self.positions != positions): self.positions = positions self.atoms.set_positions(positions) try: opt = self.optimizer(self.atoms, logfile=self.optimizer_logfile) opt.run(fmax=self.fmax) if self.lm_trajectory is not None: self.lm_trajectory.write(self.atoms) self.energy = self.atoms.get_potential_energy() except: # Something went wrong. # In GPAW the atoms are probably to near to each other. return None return self.energy
label=name + "_" + code + "_" + str(n), species_dir=os.path.join(os.environ["AIMS_SPECIES_DIR"], basis), xc="PBE", kpts=kpts, KS_method="elpa", sc_accuracy_rho=1.0e-4, sc_accuracy_eev=5.0e-3, occupation_type=["gaussian", width], override_relativity=True, override_illconditioning=True, basis_threshold=basis_threshold, charge_mix_param=0.01, ) atoms.calc.set(**kwargs) # remaining calc keywords t = time.time() atoms.get_potential_energy() c.write( atoms, name=name, basis=basis, linspacestr=linspacestr, kptdensity=kptdensity, width=width, basis_threshold=basis_threshold, relativistic=relativistic, x=x, time=time.time() - t, ) traj.write(atoms) del c[id]
dyn = tsase.md.nvtandersen(atoms, 5 * units.fs, units.kB * currentTemp) dyn.run(1) # 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 = PickleTrajectory(filename, mode='a') minimaList.write(atoms) minimaList.close() totalMinimaFound += 1 timesincelast = 0 else: timesincelast += 1 if (timesincelast > 25): minimalist = PickleTrajectory(filename, mode='r') atomslist = [atom for atom in minimalist] minimalist.close() atoms.set_positions(atomslist[len(atomslist) - 1].get_positions()) atoms.get_potential_energy() timessincelast = 0 minimaList = PickleTrajectory(filename, mode='r') atomslist = [atom for atom in minimaList]
from numpy import linspace from ase.calculators.fleur import FLEUR from ase.structure import bulk from ase.io.trajectory import PickleTrajectory atoms = bulk('Ni', 'fcc', a=3.52) calc = FLEUR(xc='PBE', kmax=3.6, kpts=(10, 10, 10), workdir='lat_const') atoms.set_calculator(calc) traj = PickleTrajectory('Ni.traj','w', atoms) cell0 = atoms.get_cell() for s in linspace(0.95, 1.05, 7): cell = cell0 * s atoms.set_cell((cell)) ene = atoms.get_potential_energy() traj.write()
def write(self, atoms=None): if atoms is not None and getattr(atoms, "parallel", False): atoms = asap3.Collector(atoms, self.master) self.sanitycheck = False _PickleTrajectory.write(self, atoms)
# set calculator atoms.calc = Aims( label=name + '_' + code + '_' + str(n), species_dir=os.path.join(os.environ['AIMS_SPECIES_DIR'], basis), xc='PBE', kpts=kpts, KS_method='elpa', sc_accuracy_rho=1.e-4, sc_accuracy_eev=5.e-3, occupation_type=['gaussian', width], override_relativity=True, override_illconditioning=True, basis_threshold=basis_threshold, charge_mix_param=0.01, ) atoms.calc.set(**kwargs) # remaining calc keywords t = time.time() atoms.get_potential_energy() c.write(atoms, name=name, basis=basis, linspacestr=linspacestr, kptdensity=kptdensity, width=width, basis_threshold=basis_threshold, relativistic=relativistic, x=x, time=time.time() - t) traj.write(atoms) del c[id]
through the other. Such atoms have coordinates outside the box. This facilitates analysis of e.g. diffusion, but can be problematic when plotting. This script reads through a trajectory file, and write a new one where all atoms are mapped into the computational box. If there are axes with free boundary conditions, the corresponding coordinate is left unchanged. SIDE EFFECT: All energies, forces and stresses are removed (yes, this can be considered as a bug!) """ from __future__ import print_function import sys from ase.io.trajectory import PickleTrajectory if len(sys.argv) != 3: print(__doc__) sys.exit(1) infile = PickleTrajectory(sys.argv[1]) outfile = None for atoms in infile: atoms.set_scaled_positions(atoms.get_scaled_positions()) atoms.set_calculator(None) # or the singlepointcalculator fails! if outfile is None: outfile = PickleTrajectory(sys.argv[2], 'w') outfile.write(atoms) outfile.close()
def write_modes(self, q_c, branches=0, kT=units.kB*300, born=False, repeat=(1, 1, 1), nimages=30, center=False): """Write modes to trajectory file. Parameters ---------- q_c: ndarray q-vector of the modes. branches: int or list Branch index of modes. kT: float Temperature in units of eV. Determines the amplitude of the atomic displacements in the modes. born: bool Include non-analytic contribution to the force constants at q -> 0. repeat: tuple Repeat atoms (l, m, n) times in the directions of the lattice vectors. Displacements of atoms in repeated cells carry a Bloch phase factor given by the q-vector and the cell lattice vector R_m. nimages: int Number of images in an oscillation. center: bool Center atoms in unit cell if True (default: False). """ if isinstance(branches, int): branch_l = [branches] else: branch_l = list(branches) # Calculate modes omega_l, u_l = self.band_structure([q_c], modes=True, born=born) # Repeat atoms atoms = self.atoms * repeat # Center if center: atoms.center() # Here ``Na`` refers to a composite unit cell/atom dimension pos_Nav = atoms.get_positions() # Total number of unit cells N = np.prod(repeat) # Corresponding lattice vectors R_m R_cN = np.indices(repeat).reshape(3, -1) # Bloch phase phase_N = np.exp(2.j * pi * np.dot(q_c, R_cN)) phase_Na = phase_N.repeat(len(self.atoms)) for l in branch_l: omega = omega_l[0, l] u_av = u_l[0, l] # Mean displacement of a classical oscillator at temperature T u_av *= sqrt(kT) / abs(omega) mode_av = np.zeros((len(self.atoms), 3), dtype=complex) # Insert slice with atomic displacements for the included atoms mode_av[self.indices] = u_av # Repeat and multiply by Bloch phase factor mode_Nav = np.vstack(N * [mode_av]) * phase_Na[:, np.newaxis] traj = PickleTrajectory('%s.mode.%d.traj' % (self.name, l), 'w') for x in np.linspace(0, 2*pi, nimages, endpoint=False): atoms.set_positions((pos_Nav + np.exp(1.j * x) * mode_Nav).real) traj.write(atoms) traj.close()
def write_modes(self, q_c, branches=0, kT=units.kB * 300, repeat=(1, 1, 1), nimages=30, acoustic=True): """Write mode to trajectory file. The classical equipartioning theorem states that each normal mode has an average energy:: <E> = 1/2 * k_B * T = 1/2 * omega^2 * Q^2 => Q = sqrt(k_B*T) / omega at temperature T. Here, Q denotes the normal coordinate of the mode. Parameters ---------- q_c: ndarray q-vector of the modes. branches: int or list Branch index of calculated modes. kT: float Temperature in units of eV. Determines the amplitude of the atomic displacements in the modes. repeat: tuple Repeat atoms (l, m, n) times in the directions of the lattice vectors. Displacements of atoms in repeated cells carry a Bloch phase factor given by the q-vector and the cell lattice vector R_m. nimages: int Number of images in an oscillation. """ if isinstance(branches, int): branch_n = [branches] else: branch_n = list(branches) # Calculate modes omega_n, u_n = self.band_structure([q_c], modes=True, acoustic=acoustic) # Repeat atoms atoms = self.atoms * repeat pos_mav = atoms.positions.copy() # Total number of unit cells M = np.prod(repeat) # Corresponding lattice vectors R_m R_cm = np.indices(repeat[::-1]).reshape(3, -1)[::-1] # Bloch phase phase_m = np.exp(2.j * pi * np.dot(q_c, R_cm)) phase_ma = phase_m.repeat(len(self.atoms)) for n in branch_n: omega = omega_n[0, n] u_av = u_n[0, n] # .reshape((-1, 3)) # Mean displacement at high T ? u_av *= sqrt(kT / abs(omega)) mode_av = np.zeros((len(self.atoms), 3), dtype=self.dtype) indices = self.dyn.get_indices() mode_av[indices] = u_av mode_mav = (np.vstack([mode_av] * M) * phase_ma[:, np.newaxis]).real traj = PickleTrajectory('%s.mode.%d.traj' % (self.name, n), 'w') for x in np.linspace(0, 2 * pi, nimages, endpoint=False): # XXX Is it correct to take out the sine component here ? atoms.set_positions(pos_mav + sin(x) * mode_mav) traj.write(atoms) traj.close()
class BasinHopping(Dynamics): """Basin hopping algorythm. After Wales and Doye, J. Phys. Chem. A, vol 101 (1997) 5111-5116""" def __init__(self, atoms, temperature=100 * kB, optimizer=FIRE, fmax=0.1, dr=0.1, logfile='-', trajectory='lowest.traj', optimizer_logfile='-', local_minima_trajectory='local_minima.traj', adjust_cm=True): Dynamics.__init__(self, atoms, logfile, trajectory) self.kT = temperature self.optimizer = optimizer self.fmax = fmax self.dr = dr if adjust_cm: self.cm = atoms.get_center_of_mass() else: self.cm = None self.optimizer_logfile = optimizer_logfile self.lm_trajectory = local_minima_trajectory if isinstance(local_minima_trajectory, str): self.lm_trajectory = PickleTrajectory(local_minima_trajectory, 'w', atoms) self.initialize() def initialize(self): self.positions = 0.0 * self.atoms.get_positions() self.Emin = self.get_energy(self.atoms.get_positions()) or 1.e32 self.rmin = self.atoms.get_positions() self.positions = self.atoms.get_positions() self.call_observers() self.log(-1, self.Emin, self.Emin) def run(self, steps): """Hop the basins for defined number of steps.""" ro = self.positions Eo = self.get_energy(ro) En = None for step in range(steps): while En is None: rn = self.move(ro) En = self.get_energy(rn) if En < self.Emin: # new minimum found self.Emin = En self.rmin = self.atoms.get_positions() self.call_observers() rn = self.rmin self.log(step, En, self.Emin) accept = np.exp((Eo - En) / self.kT) > np.random.uniform() if accept: ro = rn Eo = En def log(self, step, En, Emin): if self.logfile is None: return name = self.__class__.__name__ self.logfile.write('%s: step %d, energy %15.6f, emin %15.6f\n' % (name, step, En, Emin)) self.logfile.flush() def move(self, ro): """Move atoms by a random step.""" atoms = self.atoms # displace coordinates disp = np.random.uniform(-1., 1., (len(atoms), 3)) rn = ro + self.dr * disp atoms.set_positions(rn) if self.cm is not None: cm = atoms.get_center_of_mass() atoms.translate(self.cm - cm) rn = atoms.get_positions() world.broadcast(rn, 0) atoms.set_positions(rn) return atoms.get_positions() def get_minimum(self): """Return minimal energy and configuration.""" atoms = self.atoms.copy() atoms.set_positions(self.rmin) return self.Emin, atoms def get_energy(self, positions): """Return the energy of the nearest local minimum.""" if np.sometrue(self.positions != positions): self.positions = positions self.atoms.set_positions(positions) try: opt = self.optimizer(self.atoms, logfile=self.optimizer_logfile) opt.run(fmax=self.fmax) if self.lm_trajectory is not None: self.lm_trajectory.write(self.atoms) self.energy = self.atoms.get_potential_energy() except: # Something went wrong. # In GPAW the atoms are probably to near to each other. return None return self.energy
results = {} # prepare energies and volumes b = bulk('Al', 'fcc', a=4.0, orthorhombic=True) b.set_calculator(EMT()) cell = b.get_cell() volumes = [] energies = [] traj = PickleTrajectory('eos.traj', 'w') for x in np.linspace(0.97, 1.03, 5): b.set_cell(cell * x, scale_atoms=True) volumes.append(b.get_volume()) energies.append(b.get_potential_energy()) traj.write(b) for n, (v, e) in enumerate(zip(volumes, energies)): vref = ref['volumes'][n] eref = ref['energies'][n] vabserr = abs((v - vref) / vref) vstrerr = str(n) + ' volume: ' + str(v) + ': ' + str(vref) + ': ' + str(vabserr) assert vabserr < 1.e-6, vstrerr eabserr = abs((e - eref) / eref) estrerr = str(n) + ' energy: ' + str(e) + ': ' + str(eref) + ': ' + str(eabserr) assert eabserr < 1.e-4, estrerr # ASE2 try: from ASE.Utilities.EquationOfState import EquationOfState as eos2
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) atoms = makeBimetallic(atoms,79,78,0.25) sinceLastFind = 0 def HighEnergyMove(atoms): for cntr in range (len(atoms)): if (atoms[cntr].getNeighboringAtoms(.5) > 3): decideSingleMove() elif (atoms[cntr].getNeighboringAtoms(.5) <= 3): shake(atoms)