def cjson_reader(cjsonfile, trajfile=None): """Read CJSON files Parameters ---------- cjsonfile : str Path to the CJSON file. trajfile : str, optional Name of trajectory file to be saved, by default None. Returns ------- atoms A list of Atoms objects. """ collection = json.loads(open(cjsonfile, "r").read()) atoms = [] if trajfile is not None: traj = Trajectory(trajfile, mode="w") for document in collection: cjson = json.loads(document) molecule, energy = cjson_to_ase(cjson) molecule.set_calculator(FakeCalculator()) molecule.calc.results["energy"] = energy atoms.append(molecule) if trajfile is not None: traj.write(molecule, energy=energy) return atoms
def train_test(): """Gaussian/KRR train test.""" label = 'train_test/calc' train_images = generate_data(2) traj = Trajectory('trainingset.traj', mode='w') for image in train_images: traj.write(image) calc = Amp(descriptor=Gaussian(), model=KernelRidge(forcetraining=True, trainingimages='trainingset.traj'), label=label, cores=1) calc.train(images=train_images,) for image in train_images: print("energy = %s" % str(calc.get_potential_energy(image))) print("forces = %s" % str(calc.get_forces(image))) # Test that we can re-load this calculator and call it again. del calc calc2 = Amp.load(label + '.amp') for image in train_images: print("energy = %s" % str(calc2.get_potential_energy(image))) print("forces = %s" % str(calc2.get_forces(image)))
def integrate_atoms( self, atoms, traj_file, n_steps, save_interval, steps=0, timestep=5.0, traj_dir="trajs", convert=False, ): if not os.path.exists(traj_dir): os.mkdir(traj_dir) traj_file = os.path.join(traj_dir, traj_file) if not os.path.exists(traj_file): traj = Trajectory(traj_file, "w") print("Creating trajectory {}...".format(traj_file)) dyn = VelocityVerlet(atoms, timestep=timestep * units.fs) count = n_steps // save_interval for i in range(count): dyn.run(save_interval) energy = atoms.get_total_energy() forces = atoms.get_forces() traj.write(atoms) steps += save_interval print("Steps: {}, total energy: {}".format(steps, energy)) else: print("Trajectory {} already exists!".format(traj_file)) if convert: self.convert_trajectory(traj_file) return steps, traj_file
def __call__(self): """ Writes trajectory file for current atoms list. """ from ase import Trajectory traj = Trajectory('%s_it%i.trj' % (self.name, self.i), 'w') for image in self.images: traj.write(image) self.i += 1
def nudged_elastic_band(images, fmax=0.01, algo='BFGS', trajectory='path-neb.traj', final='neb.traj'): calc = cline.gen_active_calc() load1 = calc.size[0] master = calc.rank == 0 for image in images: image.calc = calc # calculate for the first and last images # (for more efficient ML) images[0].get_potential_energy() images[-1].get_potential_energy() # define and run NEB neb = NEB(images, allow_shared_calculator=True) Min = getattr(optimize, algo) dyn = Min(neb, trajectory=trajectory, master=master) dyn.run(fmax) load2 = calc.size[0] if master: print(f'\tTotal number of Ab initio calculations: {load2-load1}\n') # output if master: out = Trajectory(final, 'w') for image in images: image.get_potential_energy() if master: out.write(image)
def test_info(): from ase import Atoms from ase.io import Trajectory # Create a molecule with an info attribute info = dict( creation_date='2011-06-27', chemical_name='Hydrogen', # custom classes also works provided that it is # imported and pickleable... foo={'seven': 7}) molecule = Atoms('H2', positions=[(0., 0., 0.), (0., 0., 1.1)], info=info) assert molecule.info == info # Copy molecule atoms = molecule.copy() assert atoms.info == info # Save molecule to trajectory traj = Trajectory('info.traj', 'w', atoms=molecule) traj.write() del traj # Load molecule from trajectory t = Trajectory('info.traj') atoms = t[-1] print(atoms.info) assert atoms.info == info
def main(): args = sys.argv imgs = read(args[1], index=":") random.shuffle(imgs) imgs_selected_Pd = imgs[:200] random.shuffle(imgs) imgs_selected_H = imgs[:100] expansions = [0.1 * (i + 1) for i in range(8)] traj = Trajectory('expanded.traj', 'w') for img in imgs_selected_Pd: Pds = [atom.index for atom in img if atom.symbol == 'Pd'] com = img.get_center_of_mass() d_atoms = [] for Pd in Pds: d_atoms.append([np.linalg.norm(img[Pd].position - com), Pd]) ordered_atoms = sorted(d_atoms, key=itemgetter(0), reverse=False) imags_expanded = expand_particle(img, expansions, random.choice(ordered_atoms[-5:])[1]) for im in imags_expanded: traj.write(im) for img in imgs_selected_H: Hs = [atom.index for atom in img if atom.symbol == 'H'] com = img.get_center_of_mass() d_Hs = [] for H in Hs: d_Hs.append([np.linalg.norm(img[H].position - com), H]) ordered_atoms = sorted(d_Hs, key=itemgetter(0), reverse=False) imags_expanded = expand_particle(img, expansions, ordered_atoms[-1][1]) for im in imags_expanded: traj.write(im)
def eos(self, atoms, name): args = self.args traj = Trajectory(self.get_filename(name, 'traj'), 'w', atoms) N, eps = args.equation_of_state.split(',') N = int(N) eps = float(eps) / 100 strains = np.linspace(1 - eps, 1 + eps, N) 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, args.eos_type) v0, e0, B = eos.fit() atoms.set_cell(cell1 * (v0 / v1)**(1 / 3), scale_atoms=True) from ase.parallel import parprint as p p('volumes:', volumes) p('energies:', energies) p('fitted energy:', e0) p('fitted volume:', v0) p('bulk modulus:', B) p('eos type:', args.eos_type)
def main(): imgs = read('train.traj', index='0::10', format='traj') natoms = len(imgs[0]) cutoff = 3.3 mindist = 2.7 traj = Trajectory('traj.traj', 'w') for atoms in imgs: nl = NeighborList([cutoff / 2] * len(atoms), self_interaction=False, bothways=False) nl.update(atoms) neighbor_info = {} n_pairs = 0 for i in range(natoms): i_indices, i_offsets = nl.get_neighbors(i) neighbor_info[i] = i_indices n_pairs += len(i_indices) print len(i_indices) #randomvalues=np.random.random((n_pairs,)) + mindist randomvalues = np.random.normal(mindist, 0.5, (n_pairs, )) pullcloser = {} pointer = 0 for key in neighbor_info.keys(): pullcloser[key] = randomvalues[pointer:len(neighbor_info[key]) + pointer:1] pointer += len(neighbor_info[key]) atoms.set_positions( pull_closer(atoms.get_positions(), neighbor_info, pullcloser)) #write('CONTCAR',atoms,format='vasp') traj.write(atoms)
def main(): args = sys.argv imgs = read(args[1], index="::40") #layers = find_layers(atoms.copy()) traj = Trajectory('traj.traj','w') H_indices = random.sample([a.index for a in imgs[0] if a.symbol == 'H'],8) n_img = 0 for atoms in imgs: nl=NeighborList([2.5/2]*len(atoms), self_interaction=False, bothways=True) nl.update(atoms) pair_selected = [] for H_index in H_indices: nl_indices, nl_offsets = nl.get_neighbors(H_index) pair_selected.append([H_index, random.sample(nl_indices, 1)[0]]) for HPd_dist in [1.0, 1.1, 1.2, 1.3, 1.4]: img = atoms.copy() for pair in pair_selected: H_index = pair[0] Pd_selected = pair[1] v = atoms[H_index].position - atoms[Pd_selected].position vn = v/np.linalg.norm(v) del img[H_index] img.append(Atom('H',atoms[Pd_selected].position + vn * HPd_dist)) traj.write(img) print n_img n_img+=1
def main(): parser = argparse.ArgumentParser() parser.add_argument('--traj', type=str, nargs='+', metavar='trajFile', default=None, help='filename of the trajectory') parser.add_argument('--runtype', type=str, nargs='+', metavar='type', default=None, help='run type: split or match') args = parser.parse_args() print(args) if args.traj[0].split('.')[1] == 'xyz': configs, es, fnorms, fmins, fmaxs = read_images(args.traj[0]) if args.traj[0].split('.')[1] == 'traj': configs, es, fnorms, fmins, fmaxs = read_traj(args.traj[0]) if args.runtype[0] == 'split': configs.sort(key=lambda x: x[1]) dn = int(len(configs) / 14) for i in range(14): print(i) test_traj = Trajectory(str(i) + '.traj', 'w') start = dn * i if i == 13: end = len(configs) else: end = dn * (i + 1) for config in configs[start:end]: test_traj.write(config[0]) if args.runtype[0] == 'match': outtraj = Trajectory('filter.traj', 'w') for i in range(len(configs) - 1): #calc = force_setter(energy=config.get_potential_energy(), forces=config.get_forces()) #config.set_cell([[40.,0,0],[0,40.,0],[0,0,40.]],scale_atoms=False) #config.set_pbc((True, True, True)) #config.center() #config.set_calculator(calc) e0 = configs[i][0].get_potential_energy() fs0 = configs[i][0].get_forces() matched = False for j in range(i + 1, len(configs)): e1 = configs[j][0].get_potential_energy() if abs(e1 - e0) <= 0.05: matched = match(configs[i][0], configs[j][0], 0.02, 3.3, indistinguishable=True) if matched: break print(i, matched) if matched: continue outtraj.write(configs[i][0])
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 = Trajectory('%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(spa, energy=epot, forces=F_av) 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 calculate_eos(atoms, npoints=5, eps=0.04, trajectory=None, callback=None): """Calculate equation-of-state. atoms: Atoms object System to calculate EOS for. Must have a calculator attached. npoints: int Number of points. eps: float Variation in volume from v0*(1-eps) to v0*(1+eps). trajectory: Trjectory object or str Write configurations to a trajectory file. callback: function Called after every energy calculation. >>> from ase.build import bulk >>> from ase.calculators.emt import EMT >>> a = bulk('Cu', 'fcc', a=3.6) >>> a.calc = EMT() >>> eos = calculate_eos(a, trajectory='Cu.traj') >>> v, e, B = eos.fit() >>> a = (4 * v)**(1 / 3.0) >>> print('{0:.6f}'.format(a)) 3.589825 """ # Save original positions and cell: p0 = atoms.get_positions() c0 = atoms.get_cell() if isinstance(trajectory, basestring): from ase.io import Trajectory trajectory = Trajectory(trajectory, 'w', atoms) if trajectory is not None: trajectory.set_description({ 'type': 'eos', 'npoints': npoints, 'eps': eps }) try: energies = [] volumes = [] for x in np.linspace(1 - eps, 1 + eps, npoints)**(1 / 3): atoms.set_cell(x * c0, scale_atoms=True) volumes.append(atoms.get_volume()) energies.append(atoms.get_potential_energy()) if callback: callback() if trajectory is not None: trajectory.write() return EquationOfState(volumes, energies) finally: atoms.cell = c0 atoms.positions = p0 if trajectory is not None: trajectory.close()
def split(images, trainingname='trainingimages.traj', testname='testimages.traj', shuffle=True, test_set=20, logfile='log.txt'): """Split data set in training and test sets. images : str Path to images to be split. trainingname : str Name of the training set trajectory file. By default is trainingimages.traj testname : str Name of the test set trajectory file. By default is testimages.traj test_set : integer Porcentage of training data that will be used as test set. shuffle : bool Whether or not the data will be randomized. logfile : str Name of logfile. By default is log.txt. """ images = Trajectory(images) total_length = len(images) test_length = int((test_set * total_length / 100)) training_leght = int(total_length - test_length) _images = list(range(len(images))) if shuffle is True: random.shuffle(_images) trainingimages = [] ti = Trajectory(trainingname, mode='w') log = open(logfile, 'w') for i in _images[0:training_leght]: trainingimages.append(i) ti.write(images[i]) log.write(str(trainingimages)) log.write('\n') if test_set > 0: testimages = [] test = Trajectory(testname, mode='w') for i in _images[-test_length:-1]: testimages.append(i) test.write(images[i]) log.write(str(testimages)) log.close() return
def calculate_eos(atoms, npoints=5, eps=0.04, trajectory=None, callback=None): """Calculate equation-of-state. atoms: Atoms object System to calculate EOS for. Must have a calculator attached. npoints: int Number of points. eps: float Variation in volume from v0*(1-eps) to v0*(1+eps). trajectory: Trjectory object or str Write configurations to a trajectory file. callback: function Called after every energy calculation. >>> from ase.build import bulk >>> from ase.calculators.emt import EMT >>> a = bulk('Cu', 'fcc', a=3.6) >>> a.calc = EMT() >>> eos = calculate_eos(a, trajectory='Cu.traj') >>> v, e, B = eos.fit() >>> a = (4 * v)**(1 / 3.0) >>> print('{0:.6f}'.format(a)) 3.589825 """ # Save original positions and cell: p0 = atoms.get_positions() c0 = atoms.get_cell() if isinstance(trajectory, basestring): from ase.io import Trajectory trajectory = Trajectory(trajectory, 'w', atoms) if trajectory is not None: trajectory.set_description({'type': 'eos', 'npoints': npoints, 'eps': eps}) try: energies = [] volumes = [] for x in np.linspace(1 - eps, 1 + eps, npoints)**(1 / 3): atoms.set_cell(x * c0, scale_atoms=True) volumes.append(atoms.get_volume()) energies.append(atoms.get_potential_energy()) if callback: callback() if trajectory is not None: trajectory.write() return EquationOfState(volumes, energies) finally: atoms.cell = c0 atoms.positions = p0 if trajectory is not None: trajectory.close()
def test_pull(): import numpy as np from ase import Atoms from ase.calculators.emt import EMT from ase.io import Trajectory Cu = Atoms('Cu', pbc=(1, 0, 0), calculator=EMT()) traj = Trajectory('Cu.traj', 'w') for a in np.linspace(2.0, 4.0, 20): Cu.set_cell([a, 1, 1], scale_atoms=True) traj.write(Cu)
def ani_to_ase(hdf5file, data_keys, trajfile=None): """ANI to ASE Parameters ---------- hdf5file : hdf5, list hdf5 file loaded using pyanitools (or list of them). data_keys : list List of keys to extract data. trajfile : str, optional Name of trajectory file to be saved, by default None. Returns ------- atoms A list of Atoms objects. """ if isinstance(hdf5file, list) is False: hdf5file = [hdf5file] atoms = [] prop = {"energies": "energy", "energy": "energy"} if trajfile is not None: traj = Trajectory(trajfile, mode="w") for hdf5 in hdf5file: for data in hdf5: symbols = data["species"] conformers = data["coordinates"] for index, conformer in enumerate(conformers): molecule = Atoms(positions=conformer, symbols=symbols) molecule.set_calculator(SinglePointCalculator()) _prop = {} for key in data_keys: value = data[key][index] # Mutate key because ANI naming is not standard. key = prop[key] _prop[key] = value molecule.calc.results[key] = value atoms.append(molecule) if trajfile is not None: traj.write(molecule, **_prop) return atoms
def main(): args = sys.argv imgs = read(args[1], index=":") random.shuffle(imgs) imgs_selected = imgs[:200] expansions = [0.05*(i+1) for i in range(8)] traj=Trajectory('expanded.traj','w') for img in imgs_selected: imags_expanded=expand_particle(img, expansions) for im in imags_expanded: traj.write(im)
def test(*args, r='::', o='test.traj'): if 'calculator' in cline.ARGS and cline.ARGS['calculator'] is not None: raise RuntimeError('set calculator = None in ARGS!') traj = Trajectory(o, 'w') calc = cline.gen_active_calc() for arg in args: data = [read(arg)] if (r is None or ':' not in r) else read(arg, r) for atoms in data: atoms.set_calculator(calc) atoms.get_forces() if calc.rank == 0: traj.write(atoms)
def traj_from_qe_xml(fileobj, index=-1, results_required=True): """Reads Quantum ESPRESSO output files. The atomistic configurations as well as results (energy, force, stress, magnetic moments) of the calculation are read for all configurations within the output file. Will probably raise errors for broken or incomplete files. Parameters ---------- fileobj : file|str A file like object or filename index : slice The index of configurations to extract. results_required : bool If True, atomistic configurations that do not have any associated results will not be included. This prevents double printed configurations and incomplete calculations from being returned as the final configuration with no results data. Yields ------ structure : Atoms The next structure from the index slice. The Atoms has a SinglePointCalculator attached with any results parsed from the file. """ root = ET.parse(fileobj).getroot() output = root.find('output') steps = root.findall('step') atoms, input_parameters = xml2atoms(output) trajectory = None trajectory = Trajectory('t1.traj', 'a') atoms_list = [] for step in steps: aaa, _ = xml2atoms(step) trajectory.write(aaa) atoms_list.append(aaa) trajectory.close() return atoms, input_parameters, atoms_list
def backup_outcar(): # it needs some improvement. Use with caution. import os import numpy as np from ase.io import read, write, Trajectory calc_id = int(np.loadtxt('db_id')) if os.path.isfile( 'OUTCAR') and not os.path.isfile(f'opt_id_{calc_id}.traj'): write(f'opt_id_{calc_id}.traj', read('OUTCAR', index=':')) elif os.path.isfile('OUTCAR') and os.path.isfile(f'opt_id_{calc_id}.traj'): t1 = Trajectory(f'opt_id_{calc_id}.traj', 'a') t2 = read('OUTCAR', index=':') for atoms in t2: t1.write(atoms) t1.close() return print('OUTCAR backup complete')
def main(): arg = sys.argv paras = readinputs(arg[1]) distances = paras['distance'].split() md_traj = read('3w-pos-1.xyz', index=slice(-3000, None), format='xyz') for p in md_traj: dist = p.get_distance(7, 13) + p.get_distance(9, 11) for distance in distances: if dist > float(distance) - 0.05 and dist < float(distance) + 0.05: make_dir(distance) write(distance + '/geometry.xyz', p, format='xyz') break traj = Trajectory('selected.traj', 'w') for distance in distances: traj.write( read(distance + '/geometry.xyz', index=':', format='xyz')[0])
def run(T, sysID): ceBulk = init_BC() prec = 1E-4 db = dataset.connect("sqlite:///" + mc_db_name) entry = db["systems"].find_one(id=sysID) chem_pot = {"c1_0": entry["c1_0"], "c1_1": entry["c1_1"]} if entry["status"] == "finished": return equil_params = {"window_length": 30 * len(ceBulk.atoms), "mode": "fixed"} max_steps = 1000 * len(ceBulk.atoms) trajfile = "data/almgsi_sgc/traj_{}.traj".format(sysID) traj = None if rank == 0: traj = Trajectory(trajfile, mode='w') for temp in T: print("Current temperature {}K".format(temp)) mc_obj = SGCMonteCarlo(ceBulk.atoms, temp, mpicomm=comm, symbols=["Al", "Mg", "Si"]) mc_obj.runMC(mode="prec", prec=prec, chem_potential=chem_pot, equil_params=equil_params, steps=max_steps) thermo = mc_obj.get_thermodynamic() thermo["temperature"] = temp thermo["prec"] = prec thermo["internal_energy"] = thermo.pop("energy") thermo["converged"] = True thermo["muc1_0"] = chem_pot["c1_0"] thermo["muc1_1"] = chem_pot["c1_1"] if (rank == 0): thermo["sysID"] = sysID newID = db["thermodynamic"].insert(thermo) cf = ceBulk.atoms._calc.get_cf() cf["resultID"] = newID db["correlation"].insert(cf) atoms_cpy = ceBulk.atoms.copy() atoms_cpy.set_calculator(None) traj.write(atoms_cpy) if (rank == 0): db["systems"].update({"status": "finished", "id": sysID}, ["id"])
def main(): arg = sys.argv try: configs = read(arg[1], index=":") except: configs = read_atoms(arg[1]) traj = Trajectory('selected_' + arg[1], 'w') chem_symbols = ['H', 'Pd'] H_indices = [atom.index for atom in configs[0] if atom.symbol == 'H'] Pd_indices = [atom.index for atom in configs[0] if atom.symbol == 'Pd'] #temp = copy.deepcopy(configs) for itrj in range(len(configs)): print itrj config = configs[itrj] delete = False for i in range(len(H_indices) - 1): for j in range(i + 1, len(H_indices)): if config.get_distance(H_indices[i], H_indices[j]) < 0.5: delete = True break if delete: break for pd in Pd_indices: if config.get_distance(H_indices[i], pd) < 1.00: delete = True break if delete: break if delete: continue for i in range(len(Pd_indices) - 1): for j in range(i + 1, len(Pd_indices)): if config.get_distance(Pd_indices[i], Pd_indices[j]) < 2.00: delete = True break if delete: break if delete: continue traj.write(config)
def init_model(atoms, samples=5, rattle=0.05, trajectory='init.traj'): """ atoms: ASE atoms samples: number of samples rattle: stdev for random displacements trajectory: traj file name """ calc = cline.gen_active_calc() master = calc.rank == 0 if master: traj = Trajectory(trajectory, 'w') for _ in range(samples): tmp = atoms.copy() tmp.rattle(rattle, rng=np.random) tmp.set_calculator(calc) tmp.get_potential_energy() if master: traj.write(tmp)
def main(): #config = ConfigParser.SafeConfigParser() config = ConfigParser.ConfigParser() config.read('config.ini') #print config main_paras = dict(config.items('main')) #print main_paras atoms = read(main_paras['structurefile'], index=main_paras['structure_slice'], format=main_paras['fileformat']) h_distances = np.array([0.6 + float(i) / 10.0 for i in range(10)]) bondlength = 1.6 traj = Trajectory('traj.traj', 'w') h_index = [] for index in range(len(atoms[0])): if atoms[0][index].symbol == 'H': h_index.append(index) h_index.sort(reverse=True) for p in atoms: for index in h_index: p.pop(i=index) center = np.mean(p.get_positions(), axis=0) print center for atom in p: distance = np.linalg.norm(center - atom.position) if distance > 2.0: dot = atom.position + bondlength * (atom.position - center) / distance perp_vector = perpendicular_vector(atom.position - center) unit_perp_vector = perp_vector / np.linalg.norm(perp_vector) for h_distance in h_distances: image = p.copy() image.append( Atom('H', dot + h_distance * unit_perp_vector / 2.0)) image.append( Atom('H', dot - h_distance * unit_perp_vector / 2.0)) #image=image.wrap(center=(0.5, 0.5, 0.5)) traj.write(image) break
def test_hcp(): a0 = 3.52 / np.sqrt(2) c0 = np.sqrt(8 / 3.0) * a0 print('%.4f %.3f' % (a0, c0 / a0)) for i in range(3): traj = Trajectory('Ni.traj', 'w') eps = 0.01 for a in a0 * np.linspace(1 - eps, 1 + eps, 4): for c in c0 * np.linspace(1 - eps, 1 + eps, 4): ni = bulk('Ni', 'hcp', a=a, covera=c / a) ni.calc = EMT() ni.get_potential_energy() traj.write(ni) traj.close() configs = read('Ni.traj', index=':') energies = [config.get_potential_energy() for config in configs] ac = [(config.cell[0, 0], config.cell[2, 2]) for config in configs] p = polyfit(ac, energies, 2) a0, c0 = fmin_bfgs(p, (a0, c0)) print('%.4f %.3f' % (a0, c0 / a0)) assert abs(a0 - 2.466) < 0.001 assert abs(c0 / a0 - 1.632) < 0.005
def main(): arg = sys.argv paras = readinputs(arg[1]) distances = paras['distance'].split() #output = open('freeEnergy.dat','w') dx = float(paras['dx']) avg_force = [] free_energy = [] md_steps = [] atom_distance = {} tag = None atoms = None traj = Trajectory('reaction.traj', 'w', atoms) #traj=[] cellsize = 20.0 for distance in distances: cp2k_inp = open(distance + '/' + paras['cp2k_inp'], 'r') lines = cp2k_inp.readlines() for line in lines: if 'PROJECT_NAME' in line: tag = line.split()[1] break try: p = read(distance + '/' + tag + '-pos-1.xyz', index=slice(-1, None), format='xyz')[0] p.set_cell([[cellsize, 0, 0], [0, cellsize, 0], [0, 0, cellsize]], scale_atoms=False) p.set_pbc((True, True, True)) except: print(distance) continue p.center() print(p) #traj.append(p) traj.write(p)
# Make a mask of zeros and ones that select fixed atoms - the two # bottom layers: mask = initial.positions[:, 2] - min(initial.positions[:, 2]) < 1.5 * h constraint = FixAtoms(mask=mask) initial.set_constraint(constraint) # Calculate using EMT: initial.calc = EMT() # Relax the initial state: QuasiNewton(initial).run(fmax=0.05) e0 = initial.get_potential_energy() traj = Trajectory('dimer_along.traj', 'w', initial) traj.write() # Making dimer mask list: d_mask = [False] * (N - 1) + [True] # Set up the dimer: d_control = DimerControl(initial_eigenmode_method='displacement', displacement_method='vector', logfile=None, mask=d_mask) d_atoms = MinModeAtoms(initial, d_control) # Displacement settings: displacement_vector = np.zeros((N, 3)) # Strength of displacement along y axis = along row: displacement_vector[-1, 1] = 0.001
# Set calculator # loop a number of times to capture if minimization stops with high force # due to the VariansBreak calls niter = 0 # If the structure is already fully relaxed just return it traj = Trajectory(label + '_lcao.traj', 'w', structure) while (structure.get_forces()** 2).sum(axis=1).max()**0.5 > forcemax and niter < niter_max: dyn = BFGS(structure, logfile=label + '.log') vb = VariansBreak(structure, dyn, min_stdev=0.01, N=15) dyn.attach(traj) dyn.attach(vb) dyn.run(fmax=forcemax, steps=steps) niter += 1 #print('relaxgpaw over',flush=True) return structure calc = GPAW(mode=PW(500), xc='PBE', basis='dzp', kpts=(3, 3, 1)) traj = Trajectory('V2O5_H2OTiO2_101_DFTrelaxed.traj', 'w') name = 'V2O5_H2OTiO2_101surface_gm' data = read('BE_V2O5_H2O_TiO2_101_I8.traj@:') for i in range(0, len(data)): name = 'V2O5H2OTiO2_101surface_isomer_{}'.format(i) a = data[i] a.set_calculator(calc) a_relaxed = relaxGPAW(a, name, forcemax=0.01, niter_max=2, steps=100) traj.write(a_relaxed)
class globalOptim(): """ --Input-- MLmodel: Model that given training data can predict energy and gradient of a structure. Hint: must include a fit, predict_energy and predict_force methods. Natoms: Number of atoms in structure. Niter: Number of monte-carlo steps. rattle_maxDist: Max translation of each coordinate when perturbing the current structure to form a new candidate. min_saveDifference: Defines the energy which a new trajectory point has to be lover than the previous, to be saved for training. minSampleStep: if minSampleStep=10, every tenth point in the relaxation trajectory is used for training, and so on.. Unless min_saveDifference have not been ecxeeded. """ def __init__(self, traj_namebase, MLmodel, startGenerator, mutationSelector, calc=None, startStructures=None, population_size=5, kappa=2, Niter=50, Ninit=2, sigma=20, min_saveDifference=0.3, minSampleStep=10, dualPoint=False, relaxFinalPop=False, stat=True): self.traj_namebase = traj_namebase self.MLmodel = MLmodel self.startGenerator = startGenerator self.mutationSelector = mutationSelector self.calc = calc self.startStructures = startStructures self.population = population(population_size=population_size, comparator=self.MLmodel.comparator) self.kappa = kappa self.Natoms = len(self.startGenerator.slab) + len(self.startGenerator.atom_numbers) self.Niter = Niter self.Ninit = Ninit try: len(sigma) self.sigma = list(sigma) except: self.sigma = [sigma] self.min_saveDifference = min_saveDifference self.minSampleStep = minSampleStep self.dualPoint = dualPoint self.relaxFinalPop = relaxFinalPop self.stat = stat self.opNameList = [op.descriptor for op in self.mutationSelector.oplist] # List of structures to be added in next training self.a_add = [] self.traj_counter = 0 self.ksaved = 0 # Define parallel communication self.comm = world.new_communicator(np.array(range(world.size))) self.master = self.comm.rank == 0 # Make new folders self.ML_dir = 'all_MLcandidates/' self.pop_dir = 'relaxedPop/' if self.master: os.makedirs(self.ML_dir) os.makedirs(self.pop_dir) # Trajectory names self.writer_initTrain = Trajectory(filename=traj_namebase+'initTrain.traj', mode='a', master=self.master) self.writer_spTrain = Trajectory(filename=traj_namebase+'spTrain.traj', mode='a', master=self.master) self.writer_spPredict = Trajectory(filename=traj_namebase+'spPredict.traj', mode='a', master=self.master) self.writer_current = Trajectory(filename=traj_namebase+'current.traj', mode='a', master=self.master) # make txt file open(traj_namebase + 'sigma.txt', 'a').close() open(traj_namebase + 'MLerror_Ntries.txt', 'a').close() open(traj_namebase + 'E_MLerror.txt', 'a').close() open(traj_namebase + 'time.txt', 'a').close() def runOptimizer(self): # Initial structures if self.startStructures is None: for i in range(self.Ninit): a_init, _ = self.startGenerator.get_new_individual() a, E, F = self.relaxTrue(a_init) self.population.add_structure(a, E, F) else: for a in self.startStructures: Ei = a.get_potential_energy() Fi = a.get_forces() self.a_add.append(a) self.writer_initTrain.write(a, energy=Ei) self.population.add_structure(a, Ei, Fi) # Reset traj_counter for ML-relaxations self.traj_counter = 0 # Run global search for i in range(self.Niter): # Train ML model if new data is available t0_all = time() t0_train = time() if len(self.a_add) > 0: self.trainModel() t1_train = time() # Clean similar structures from population self.update_MLrelaxed_pop() # Generate new rattled + MLrelaxed candidate t_newCand_start = time() a_new = self.newCandidate_beyes() t_newCand_end = time() # Singlepoint with objective potential t_sp_start = time() Enew, Fnew = self.singlePoint(a_new) t_sp_end = time() # Get dual-point if relevant Fnew_max = (Fnew**2).sum(axis=1).max()**0.5 if self.dualPoint and i > 50 and Fnew_max > 0.5: a_dp = self.get_dualPoint(a_new, Fnew) E, error, _ = self.MLmodel.predict_energy(a_dp, return_error=True) # If dual-point looks promising - perform sp-calculation if E - self.kappa*error < self.population.largest_energy: E_dp, F_dp = self.singlePoint(a_dp) if E_dp < Enew: a_new = a_dp.copy() Enew = E_dp Fnew = F_dp # Try to add the new structure to the population t1_all = time() #self.update_MLrelaxed_pop() self.population.add_structure(a_new, Enew, Fnew) if self.master: for i, a in enumerate(self.population.pop): E = a.get_potential_energy() print('pop{0:d}={1:.2f} '.format(i, E), end='') # write population to file self.writer_current.write(a, energy=E, forces=a.get_forces()) print('') print('Enew={}'.format(Enew)) t2_all = time() if self.master: with open(self.traj_namebase + 'time.txt', 'a') as f: f.write('{}\t{}\t{}\t{}\t{}\n'.format(t_newCand_end-t_newCand_start, t_sp_end-t_sp_start, t1_train - t0_train, t1_all - t0_all, t2_all - t0_all)) self.traj_counter += 1 # Save final population self.update_MLrelaxed_pop() pop = self.population.pop write(self.traj_namebase + 'finalPop.traj', pop) # relax final pop with true potential if self.relaxFinalPop: relaxed_pop = [] for i, a in enumerate(pop): # Only promicing structures if (a.get_forces()**2).sum(axis = 1).max()**0.5 < 2: name = savefiles_namebase + 'pop{}'.format(i) a_relaxed = relaxGPAW(a, name, forcemax=0.05, steps=30, niter_max=2) relaxed_pop.append(a_relaxed) write(self.traj_namebase + 'finalPop_relaxed.traj', relaxed_pop) def update_MLrelaxed_pop(self): # Initialize MLrelaxed population self.population.pop_MLrelaxed = [] for a in self.population.pop: self.population.pop_MLrelaxed.append(a.copy()) E_relaxed_pop = np.zeros(len(self.population.pop)) error_relaxed_pop = np.zeros(len(self.population.pop)) if self.comm.rank < len(self.population.pop): index = self.comm.rank a_MLrelaxed = self.relaxML(self.population.pop[index], Fmax=0.01) self.population.pop_MLrelaxed[index] = a_MLrelaxed E_temp, error_temp, _ = self.MLmodel.predict_energy(a_MLrelaxed, return_error=True) E_relaxed_pop[index] = E_temp error_relaxed_pop[index] = error_temp for i in range(len(self.population.pop)): pos = self.population.pop_MLrelaxed[i].positions self.comm.broadcast(pos, i) self.population.pop_MLrelaxed[i].set_positions(pos) E = np.array([E_relaxed_pop[i]]) error = np.array([error_relaxed_pop[i]]) self.comm.broadcast(E, i) self.comm.broadcast(error, i) self.population.pop_MLrelaxed[i].info['key_value_pairs']['predictedEnergy'] = E[0] self.population.pop_MLrelaxed[i].info['key_value_pairs']['predictedError'] = error[0] self.population.pop_MLrelaxed[i].info['key_value_pairs']['fitness'] = E[0] - self.kappa*error[0] label = self.pop_dir + 'ML_relaxed_pop{}'.format(self.traj_counter) write(label+'.traj', self.population.pop_MLrelaxed) """ # Initialize MLrelaxed population self.population.pop_MLrelaxed = [] for a in self.population.pop: self.population.pop_MLrelaxed.append(a.copy()) if self.comm.rank < len(self.population.pop): index = self.comm.rank self.population.pop_MLrelaxed[index] = self.relaxML(self.population.pop[index], Fmax=0.01) for i in range(len(self.population.pop)): pos = self.population.pop_MLrelaxed[i].positions self.comm.broadcast(pos, i) self.population.pop_MLrelaxed[i].set_positions(pos) """ def get_dualPoint(self, a, F, lmax=0.10, Fmax_flat=5): """ lmax: The atom with the largest force will be displaced by this distance Fmax_flat: max displaced distance is increased linearely with force until Fmax = Fmax_flat, over which it will be constant as lmax. """ a_dp = a.copy() # Calculate and set new positions Fmax = np.sqrt((F**2).sum(axis=1).max()) pos_displace = lmax * F*min(1/Fmax_flat, 1/Fmax) pos_dp = a.positions + pos_displace a_dp.set_positions(pos_dp) return a_dp def get_force_mutated_population(self, lmax=[0.02, 0.07]): Npop = len(self.population.pop) Nl = len(lmax) E_list = np.zeros(Npop*Nl) error_list = np.zeros(Npop*Nl) pos_list = np.zeros((Npop*Nl, 3*self.Natoms)) for i, a in enumerate(self.population.pop): F = a.get_forces() for n, l in enumerate(lmax): anew = self.get_dualPoint(a, F, lmax=l) pos_new = anew.get_positions() E, error, theta0 = self.MLmodel.predict_energy(anew, return_error=True) E_list[i*Nl+n] = E error_list[i*Nl+n] = error pos_list[i*Nl+n] = pos_new.reshape(-1) return pos_list, E_list, error_list def mutate(self, Ntasks_each): a_mutated_list = [] for k in range(Ntasks_each): # draw random structure to mutate from population a = self.population.get_structure() a_copy = a.copy() a_mutated, _ = self.mutationSelector.get_new_individual([a_copy]) a_mutated_list.append(a_mutated) self.comm.barrier() return a_mutated_list def newCandidate_beyes(self): N_newCandidates = 30 # the maximum number of candidates a core need to make N_newCandidates on a single node. N_tasks = int(np.ceil(N_newCandidates / self.comm.size)) # Use all cores on nodes. N_newCandidates = N_tasks * N_newCandidates # perform mutations if self.master: t0 = time() anew_mutated_list = self.mutate(N_tasks) if self.master: print('mutation time:', time() - t0, flush=True) # Relax with MLmodel anew_list = [] E_list = [] error_list = [] for anew_mutated in anew_mutated_list: anew = self.relaxML(anew_mutated, with_error=True) anew_list.append(anew) E, error, theta0 = self.MLmodel.predict_energy(anew, return_error=True) E_list.append(E) error_list.append(error) E_list = np.array(E_list) error_list = np.array(error_list) if self.master: print('theta0:', theta0, flush=True) oplist_index = np.array([self.opNameList.index(a.info['key_value_pairs']['origin']) for a in anew_list]).astype(int) # Gather data from slaves to master pos_new_list = np.array([anew.positions for anew in anew_list]) pos_new_mutated_list = np.array([anew_mutated.positions for anew_mutated in anew_mutated_list]) if self.comm.rank == 0: E_all = np.empty(N_tasks * self.comm.size, dtype=float) error_all = np.empty(N_tasks * self.comm.size, dtype=float) pos_all = np.empty(N_tasks * 3*self.Natoms*self.comm.size, dtype=float) pos_all_mutated = np.empty(N_tasks * 3*self.Natoms*self.comm.size, dtype=float) oplist_index_all = np.empty(N_tasks * self.comm.size, dtype=int) else: E_all = None error_all = None pos_all = None pos_all_mutated = None oplist_index_all = None self.comm.gather(E_list, 0, E_all) self.comm.gather(error_list, 0, error_all) self.comm.gather(pos_new_list.reshape(-1), 0, pos_all) self.comm.gather(pos_new_mutated_list.reshape(-1), 0, pos_all_mutated) self.comm.gather(oplist_index, 0, oplist_index_all) # Pick best candidate on master + broadcast pos_new = np.zeros((self.Natoms, 3)) pos_new_mutated = np.zeros((self.Natoms, 3)) if self.master: fitness_all = E_all - self.kappa * error_all index_best = fitness_all.argmin() print('{}:\n'.format(self.traj_counter), np.c_[E_all, error_all]) print('{} best:\n'.format(self.traj_counter), E_all[index_best], error_all[index_best]) with open(self.traj_namebase + 'E_MLerror.txt', 'a') as f: f.write('{0:.4f}\t{1:.4f}\n'.format(E_all[index_best], error_all[index_best])) pos_all = pos_all.reshape((-1, self.Natoms, 3)) pos_new = pos_all[index_best] # old pos_all_mutated = pos_all_mutated.reshape((N_tasks * self.comm.size, self.Natoms, 3)) pos_new_mutated = pos_all_mutated[index_best] # old if self.stat: a_all = [] a_all_mutated = [] for i, (pos, pos_mutated) in enumerate(zip(pos_all, pos_all_mutated)): a = anew.copy() a_mutated = anew.copy() a.positions = pos a_mutated.positions = pos_mutated a.info['key_value_pairs']['predictedEnergy'] = E_all[i] a.info['key_value_pairs']['predictedError'] = error_all[i] a.info['key_value_pairs']['fitness'] = E_all[i] - self.kappa*error_all[i] a.info['key_value_pairs']['origin'] = self.opNameList[oplist_index_all[index_best]] a_all.append(a) a_all_mutated.append(a_mutated) label_relaxed = self.ML_dir + 'ML_relaxed{}'.format(self.traj_counter) write(label_relaxed+'.traj', a_all, parallel=False) label_unrelaxed = self.ML_dir + 'ML_unrelaxed{}'.format(self.traj_counter) write(label_unrelaxed+'.traj', a_all_mutated, parallel=False) # Write unrelaxed + relaxed versions of best candidate to file label = self.ML_dir + 'ML_best{}'.format(self.traj_counter) write(label+'.traj', [a_all_mutated[index_best], a_all[index_best]], parallel=False) #try: # pos_new = pos_all[index_best] # pos_new_mutated = pos_all_mutated[index_best] #except IndexError: # pos_new = self.population.pop_MLrelaxed[index_best % N_newCandidates].get_positions() # pos_new_mutated = self.population.pop[index_best % N_newCandidates].get_positions() self.comm.broadcast(pos_new, 0) anew.positions = pos_new self.comm.broadcast(pos_new_mutated, 0) anew_mutated = anew.copy() anew_mutated.positions = pos_new_mutated self.comm.barrier() # Write unrelaxed + relaxed versions of best candidate to file #label = self.ML_dir + 'ML_best{}'.format(self.traj_counter) #write(label+'.traj', [anew_mutated, anew]) return anew def trainModel(self): """ # Reduce training data - If there is too much if self.ksaved > self.maxNtrain: Nremove = self.ksaved - self.maxNtrain self.ksaved = self.maxNtrain self.MLmodel.remove_data(Nremove) """ #GSkwargs = {'reg': [1e-5], 'sigma': np.logspace(1, 3, 5)} # GSkwargs = {'reg': [1e-5], 'sigma': [30]} # C24 GSkwargs = {'reg': [1e-5], 'sigma': self.sigma} # SnO FVU, params = self.MLmodel.train(atoms_list=self.a_add, add_new_data=True, k=3, **GSkwargs) self.a_add = [] if self.master: with open(self.traj_namebase + 'sigma.txt', 'a') as f: f.write('{0:.2f}\n'.format(params['sigma'])) def add_trajectory_to_training(self, trajectory_file): atoms = read(filename=trajectory_file, index=':', parallel=False) E = [a.get_potential_energy() for a in atoms] Nstep = len(atoms) # Always add+save start structure self.a_add.append(atoms[0]) self.writer_initTrain.write(atoms[0], energy=E[0]) n_last = 0 Ecurrent = E[0] for i in range(1,Nstep-int(self.minSampleStep/2)): n_last += 1 if Ecurrent - E[i] > self.min_saveDifference and n_last > self.minSampleStep: self.a_add.append(atoms[i]) Ecurrent = E[i] self.ksaved += 1 n_last = 0 # Save to initTrain-trajectory self.writer_initTrain.write(atoms[i], energy=E[i]) # Always save+add last structure self.a_add.append(atoms[-1]) self.writer_initTrain.write(atoms[-1], energy=E[-1]) def relaxML(self, anew, Fmax=0.1, with_error=True): a = anew.copy() # Relax label = self.traj_namebase + 'ML{}'.format(self.traj_counter) if with_error: krr_calc = krr_calculator(self.MLmodel, kappa=self.kappa) else: krr_calc = krr_calculator(self.MLmodel) a_relaxed = relax_VarianceBreak(a, krr_calc, label, niter_max=1, forcemax=Fmax) return a_relaxed def relaxTrue(self, a): pos = a.positions if self.master: pos = a.positions self.comm.broadcast(pos, 0) a.positions = pos self.comm.barrier() label = self.traj_namebase + '{}'.format(self.traj_counter) pos_relaxed = a.positions Erelaxed = np.zeros(1) Frelaxed = np.zeros((3,self.Natoms)) if self.master: # Relax a_relaxed = relaxGPAW(a, label, calc=self.calc) pos_relaxed = a_relaxed.positions Erelaxed = np.array([a_relaxed.get_potential_energy()]) Frelaxed = a_relaxed.get_forces() self.comm.broadcast(pos_relaxed, 0) self.comm.broadcast(Erelaxed, 0) Erelaxed = Erelaxed[0] self.comm.broadcast(Frelaxed, 0) a_relaxed = a.copy() a_relaxed.positions = pos_relaxed self.comm.barrier() # Add sampled trajectory to training data. self.add_trajectory_to_training(label+'_lcao.traj') self.traj_counter += 1 return a_relaxed, Erelaxed, Frelaxed def singlePoint(self, anew): a = anew.copy() # Save structure with ML-energy if self.master: self.writer_spPredict.write(a) # broadcast structure, so all cores have the same pos = a.positions if self.master: pos = a.positions self.comm.broadcast(pos, 0) a.positions = pos self.comm.barrier() # Perform single-point E = np.zeros(1) F = np.zeros((self.Natoms,3)) if self.master: label = self.traj_namebase + '{}'.format(self.traj_counter) E, F = singleGPAW(a, label, calc=self.calc) E = np.array([E]) self.comm.broadcast(E, 0) E = E[0] self.comm.broadcast(F, 0) # save structure for training a.energy = E results = {'energy': E} calc = SinglePointCalculator(a, **results) a.set_calculator(calc) self.a_add.append(a) # Save to spTrain-trajectory self.writer_spTrain.write(a, energy=E, forces=F) self.ksaved += 1 return E, F
if sys.platform in ['win32']: raise NotAvailable('Fails on Windows ' 'https://trac.fysik.dtu.dk/projects/ase/ticket/62') import os from ase import Atom, Atoms from ase.io import Trajectory, read from ase.constraints import FixBondLength co = Atoms([Atom('C', (0, 0, 0)), Atom('O', (0, 0, 1.2))]) traj = Trajectory('1.traj', 'w', co) for i in range(5): co.positions[:, 2] += 0.1 traj.write() traj = Trajectory('1.traj', 'a') co = read('1.traj') print(co.positions) co.positions[:] += 1 traj.write(co) for a in Trajectory('1.traj'): print(1, a.positions[-1, 2]) co.positions[:] += 1 t = Trajectory('1.traj', 'a') t.write(co) assert len(t) == 7 co[0].number = 1
from ase.test import NotAvailable, must_raise if sys.platform in ['win32']: raise NotAvailable('Fails on Windows ' 'https://trac.fysik.dtu.dk/projects/ase/ticket/62') import os from ase import Atom, Atoms from ase.io import Trajectory, read co = Atoms([Atom('C', (0, 0, 0)), Atom('O', (0, 0, 1.2))]) traj = Trajectory('1.traj', 'w', co) for i in range(5): co.positions[:, 2] += 0.1 traj.write() traj = Trajectory('1.traj', 'a') co = read('1.traj') print(co.positions) co.positions[:] += 1 traj.write(co) for a in Trajectory('1.traj'): print(1, a.positions[-1, 2]) co.positions[:] += 1 t = Trajectory('1.traj', 'a') t.write(co) assert len(t) == 7 co[0].number = 1
relativistic=relativistic, constant_basis=constant_basis, x=x) if id is None: continue # perform EOS step atoms.set_cell(cell * x, scale_atoms=True) # set calculator atoms.calc = GPAW( txt=name + '_' + code + '_' + str(n) + '.txt', xc='PBE', kpts=kpts, width=width, parallel={'band': 1}, idiotproof=False) atoms.calc.set(**kwargs) # remaining calc keywords t = time.time() atoms.get_potential_energy() c.write(atoms, category=category, name=name, e=e, linspacestr=linspacestr, kptdensity=kptdensity, width=width, relativistic=relativistic, constant_basis=constant_basis, x=x, magnetic_moment=atoms.calc.get_magnetic_moment(), niter=atoms.calc.get_number_of_iterations(), time=time.time()-t) traj.write(atoms) del c[id]
import numpy as np from ase import Atoms from ase.calculators.emt import EMT from ase.io import Trajectory Cu = Atoms('Cu', pbc=(1, 0, 0), calculator=EMT()) traj = Trajectory('Cu.traj', 'w') for a in np.linspace(2.0, 4.0, 20): Cu.set_cell([a, 1, 1], scale_atoms=True) traj.write(Cu)
# Make a mask of zeros and ones that select fixed atoms - the two # bottom layers: mask = initial.positions[:, 2] - min(initial.positions[:, 2]) < 1.5 * h constraint = FixAtoms(mask=mask) initial.set_constraint(constraint) # Calculate using EMT: initial.set_calculator(EMT()) # Relax the initial state: QuasiNewton(initial).run(fmax=0.05) e0 = initial.get_potential_energy() traj = Trajectory('dimer_along.traj', 'w', initial) traj.write() # Making dimer mask list: d_mask = [False] * (N - 1) + [True] # Set up the dimer: d_control = DimerControl(initial_eigenmode_method='displacement', displacement_method='vector', logfile=None, mask=d_mask) d_atoms = MinModeAtoms(initial, d_control) # Displacement settings: displacement_vector = np.zeros((N, 3)) # Strength of displacement along y axis = along row: displacement_vector[-1, 1] = 0.001
import numpy as np a0 = 3.52 / np.sqrt(2) c0 = np.sqrt(8 / 3.0) * a0 from ase.io import Trajectory traj = Trajectory('Ni.traj', 'w') from ase.lattice import bulk from ase.calculators.emt import EMT eps = 0.01 for a in a0 * np.linspace(1 - eps, 1 + eps, 3): for c in c0 * np.linspace(1 - eps, 1 + eps, 3): ni = bulk('Ni', 'hcp', a=a, c=c) ni.set_calculator(EMT()) ni.get_potential_energy() traj.write(ni) from ase.io import read configs = read('Ni.traj@:') energies = [config.get_potential_energy() for config in configs] a = np.array([config.cell[0, 0] for config in configs]) c = np.array([config.cell[2, 2] for config in configs]) functions = np.array([a**0, a, c, a**2, a * c, c**2]) p = np.linalg.lstsq(functions.T, energies)[0] p0 = p[0] p1 = p[1:3] p2 = np.array([(2 * p[3], p[4]), (p[4], 2 * p[5])]) a0, c0 = np.linalg.solve(p2.T, -p1)