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 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 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 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 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 _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 _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 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 MD(self): """Molecular Dynamic""" from ase.md.velocitydistribution import MaxwellBoltzmannDistribution from ase import units from ase.md import MDLogger from ase.io.trajectory import PickleTrajectory from ase.md.langevin import Langevin from ase.md.verlet import VelocityVerlet dyndrivers = { 'Langevin': Langevin, 'None': VelocityVerlet, } useAsap = False mol = self.mol temperature = self.definedParams['temperature'] init_temperature = self.definedParams['init_temperature'] time_step = self.definedParams['time_step'] nstep = self.definedParams['nstep'] nprint = self.definedParams['nprint'] thermostat = self.definedParams['thermostat'] prop_file = os.path.join(self.definedParams['workdir'], self.definedParams['output_prefix'] + '.out') traj_file = os.path.join(self.definedParams['workdir'], self.definedParams['output_prefix'] + '.traj') MaxwellBoltzmannDistribution(mol, init_temperature * units.kB) if thermostat == 'None': dyn = VelocityVerlet(mol, time_step * units.fs) elif thermostat == 'Langevin': dyn = Langevin(mol, time_step * units.fs, temperature * units.kB, 0.01) else: raise ImplementationError( method, 'Thermostat is not implemented in the MD function') #Function to print the potential, kinetic and total energy traj = PickleTrajectory(traj_file, "a", mol) dyn.attach(MDLogger(dyn, mol, prop_file), interval=nprint) dyn.attach(traj.write, interval=nprint) dyn.run(nstep) 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 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 MD(self): """Molecular Dynamic""" from ase.md.velocitydistribution import MaxwellBoltzmannDistribution from ase import units from ase.md import MDLogger from ase.io.trajectory import PickleTrajectory from ase.md.langevin import Langevin from ase.md.verlet import VelocityVerlet dyndrivers = { 'Langevin': Langevin, 'None': VelocityVerlet, } useAsap = False mol = self.mol temperature = self.definedParams['temperature'] init_temperature = self.definedParams['init_temperature'] time_step = self.definedParams['time_step'] nstep = self.definedParams['nstep'] nprint = self.definedParams['nprint'] thermostat = self.definedParams['thermostat'] prop_file = os.path.join(self.definedParams['workdir'], self.definedParams['output_prefix']+'.out') traj_file = os.path.join(self.definedParams['workdir'], self.definedParams['output_prefix']+'.traj') MaxwellBoltzmannDistribution(mol,init_temperature*units.kB) if thermostat == 'None': dyn = VelocityVerlet(mol, time_step*units.fs) elif thermostat == 'Langevin': dyn = Langevin(mol, time_step*units.fs, temperature*units.kB, 0.01 ) else: raise ImplementationError(method,'Thermostat is not implemented in the MD function') #Function to print the potential, kinetic and total energy traj = PickleTrajectory(traj_file,"a",mol) dyn.attach(MDLogger(dyn,mol,prop_file),interval=nprint) dyn.attach(traj.write, interval = nprint) dyn.run(nstep) traj.close()
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 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 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
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
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()
train1_pos = np.column_stack((t1_x, t1_y, t1_z)) train2_pos = np.column_stack((t2_x, t2_y, t2_z)) train1_vel = np.column_stack((v1_x, v1_y, v1_z)) train2_vel = np.column_stack((v2_x, v2_y, v2_z)) train_pos = np.copy(train1_pos) train_vel = np.copy(train1_vel) # second train commented out to avoid collisions that screw GPAW # calculation #train_pos = np.append(train_pos, train2_pos, axis=0) #train_vel = np.append(train_vel, train2_vel, axis=0) methane_trains = Atoms() for i in range(len(train_pos)): m = molecule("CH4") m.set_positions(m.get_positions() + train_pos[i]) m.set_velocities(np.zeros((5, 3)) + train_vel[i]) methane_trains.extend(m) # trains are now ready, append to atoms #print(methane_trains.get_positions()) atoms.extend(methane_trains) # now write to .traj file pt = PickleTrajectory(filename="ch4_train.traj", mode="w", backup=False) pt.write(atoms) pt.close()
def run(self, steps=1000, temp=1000, txt=None, amc=None, trajectory=None): #Open the output textfile if txt is not None: if not isinstance(txt, str): raise Warning('You must specify a valid filename.') f = open(txt, 'w') else: f = None #Initialize the dataobject if amc is not None: amcdata = AtomMonteCarloData(amc, self.cluster.atomic_number, self.cluster.symmetry, self.cluster.lattice_constant, self.size, temp) amcdata.set_dimensions(self.type_count + 1, self.neighbor_count + 1) else: amcdata = None #Open the trajectoryfile if trajectory is not None: traj = PickleTrajectory(trajectory, 'w', self.cluster, None, False) #traj.write_energy = False traj.write_forces = False traj.write_stress = False traj.write_momenta = False traj.write() #Print header to outputfile if isinstance(f, file): print >> f, ( 'Monte Carlo Sumulation on Cluster Surface Atoms \n' + 'Date: %s\n' % datetime.now().strftime("%A, %d %b %Y %H:%M:%S") + 'Material: %s\n' % data.chemical_symbols[self.cluster.atomic_number] + 'Lattice constant: %s\n' % self.cluster.lattice_constant + 'Cluster size: %i\n' % self.size + 'Multiplicity: %i\n' % self.cluster.multiplicity + 'Temperature: %i K\n' % temp + 'Thermal energy: %.5f eV\n' % (data.kB * temp) + 'Iteration Atom Position ' + 'Desination Energy Accept Probability') #Set initial values for the simulation old_energy = self.cluster.get_potential_energy() acceptances = 0 if amcdata is not None: amcdata.append(( old_energy, 0.0, #Releaxed energy not found yet self.cluster.get_diameter(), self.cluster.multiplicity, 1, np.bincount(self.get_types()), np.bincount(self.get_coordinations()), np.bincount(self.get_vacant_types()), np.bincount(self.get_vacant_coordinations()), )) #Print initial energy to outputfile if isinstance(f, file): print >> f, '%6i %70.4f' % (0, old_energy) # Check for ASAP calculator, and enable optimization #use_asap = 'asap' in str(self.cluster.get_calculator()) if self.use_asap: auxcluster = self.cluster.copy() auxcluster.set_calculator(self.asap_calc) auxcluster.get_potential_energy() #Monte Carlo simulering for i in range(1, steps + 1): #Chose a move surface_i, vacant_i = self.chose_move_old() if self.use_asap: new_atom = auxcluster[surface_i] new_atom.set_position(self.get_vacant_positions()[vacant_i]) new_energy = auxcluster.get_potential_energy() # Move atom back. It is moved forward again if accepted. #new_atom.set_position(self.cluster[surface_i].position) else: #Make new cluster with change and calculate energy new_cluster = self.cluster.copy() new_cluster.calc = self.cluster.calc new_atom = ClusterAtom(new_cluster.atomic_number) new_atom.position = self.get_vacant_positions()[vacant_i] new_atom.neighbors = self.get_vacant_neighbors()[vacant_i] new_atom.type = self.get_vacant_types()[vacant_i] new_atom.coordination = self.get_vacant_coordinations( )[vacant_i] new_cluster.move_atom(surface_i, new_atom) new_energy = new_cluster.get_potential_energy() #Calculate the energy change and accept or reject the change energy_change = new_energy - old_energy accept = False if energy_change < 0: p = 1.0 accept = True else: p = math.exp(-energy_change / (data.kB * temp)) pc = random.random() if pc < p: accept = True #Print info on MC move til outputfile if isinstance(f, file): old_position = self.cluster[surface_i].position new_position = new_atom.position print >> f, ( '%6i %8i (%6.2f%7.2f%7.2f) (%6.2f%7.2f%7.2f) %11.4f' % (i, surface_i, old_position[0], old_position[1], old_position[2], new_position[0], new_position[1], new_position[2], new_energy)), if accept: old_energy = new_energy acceptances += 1 self.move_atom(surface_i, vacant_i) if isinstance(f, file): print >> f, '%7s %10.2f' % ('Yes', p) if amcdata is not None: amcdata.append(( old_energy, 0.0, #Releaxed energy not found yet self.cluster.get_diameter(), self.cluster.multiplicity, 1, np.bincount(self.get_types()), np.bincount(self.get_coordinations()), np.bincount(self.get_vacant_types()), np.bincount(self.get_vacant_coordinations()), )) if trajectory is not None: traj.write(self.cluster) else: if self.use_asap: # Move atom back new_atom.set_position(self.cluster[surface_i].position) if isinstance(f, file): print >> f, '%7s %10.2f' % ('No', p) if amcdata is not None: amcdata.add_count(-1, 1) #Print footer to the outputfile if isinstance(f, file): print >> f, '\nDate: %s' % datetime.now().strftime( "%A, %d %b %Y %H:%M:%S") print >> f, 'Acceptances ratio: %.2f' % (acceptances * 1.0 / steps) #Save the data object if amcdata is not None: amcdata.write() #Close the trajectory if trajectory is not None: 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()
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()
randomNewRadius = random.gauss( (ninetyNinthRadius+ninetyFifthRadius)/2 , (ninetyNinthRadius - ninetyFifthRadius)/2 ) xFromCenter = random.uniform(0,randomNewRadius) randomNewRadius = ((randomNewRadius**2) - (xFromCenter**2))**0.5 yFromCenter = random.uniform(0,randomNewRadius) zFromCenter = ((randomNewRadius**2) - (yFromCenter**2))**0.5 newXPosition = inCOM[0] + random.choice([-1,1])*xFromCenter newYPosition = inCOM[1] + random.choice([-1,1])*yFromCenter newZPosition = inCOM[2] + random.choice([-1,1])*zFromCenter positionArray = inAtom.get_positions() positionArray[atomIndex] = (newXPosition,newYPosition,newZPosition) inAtom.set_positions(positionArray) return inAtom except IndexError: print "The index of the atom you wanted to move is too high or too low." print "Please check your function call of shell_move(a,b)" print "-Jeff" minimaList.close() minimaList = PickleTrajectory('Pt75Au25.traj',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()
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()
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)
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] ase.io.write('movie.xyz', atomslist,
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 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, 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()