def __init__(self, atoms, temperature=100 * kB, optimizer=FIRE, fmax=0.1, dr=.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 replay_trajectory(self, traj): """Initialize hessian from old trajectory.""" self.replay = True if isinstance(traj, str): from ase_ext.io.trajectory import PickleTrajectory traj = PickleTrajectory(traj, 'r') atoms = traj[0] r0 = None g0 = None for i in range(0, len(traj) - 1): r = traj[i].get_positions().ravel() g = -traj[i].get_forces().ravel() / self.alpha self.update(r, g, r0, g0, self.p) self.p = -np.dot(self.H, g) r0 = r.copy() g0 = g.copy() self.r0 = r0 self.g0 = g0
def replay_trajectory(self, traj): """Initialize history from old trajectory.""" if isinstance(traj, str): from ase_ext.io.trajectory import PickleTrajectory traj = PickleTrajectory(traj, 'r') r0 = None f0 = None # The last element is not added, as we get that for free when taking # the first qn-step after the replay for i in range(0, len(traj) - 1): r = traj[i].get_positions() f = traj[i].get_forces() self.update(r, f, r0, f0) r0 = r.copy() f0 = f.copy() self.iteration += 1 self.r0 = r0 self.f0 = f0
def replay_trajectory(self, traj): """Initialize hessian from old trajectory.""" if isinstance(traj, str): from ase_ext.io.trajectory import PickleTrajectory traj = PickleTrajectory(traj, 'r') self.H = None atoms = traj[0] r0 = atoms.get_positions().ravel() f0 = atoms.get_forces().ravel() for atoms in traj: r = atoms.get_positions().ravel() f = atoms.get_forces().ravel() self.update(r, f, r0, f0) r0 = r f0 = f self.r0 = r0 self.f0 = f0
def __init__(self, atoms, logfile, trajectory): self.atoms = atoms if rank != 0: logfile = None elif isinstance(logfile, str): if logfile == '-': logfile = sys.stdout else: logfile = open(logfile, 'a') self.logfile = logfile self.observers = [] self.nsteps = 0 if trajectory is not None: if isinstance(trajectory, str): trajectory = PickleTrajectory(trajectory, 'w', atoms) self.attach(trajectory)
def write_mode(self, n, kT=units.kB * 300, nimages=30): """Write mode to trajectory file.""" 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 write(self, filename): from ase_ext.io.trajectory import PickleTrajectory traj = PickleTrajectory(filename, 'w', self) traj.write() 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=.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. * self.atoms.get_positions() self.Emin = self.get_energy(self.atoms.get_positions()) 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): 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, self.Emin)) self.logfile.flush() def move(self, ro): 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() if world is not None: world.broadcast(rn, 0) atoms.set_positions(rn) return atoms.get_positions() def get_minimum(self): 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: # the atoms are probably to near to each other self.energy = 1.e32 return self.energy