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 _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 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 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 __init__(self, X=None, traj=None): if X is not None: self.X = [] for loc in X: assert loc.__class__ == Local self.X += [loc] elif traj is not None: from ase.io import Trajectory t = Trajectory(traj, 'r') self.X = [] for atoms in t: tatoms = TorchAtoms(ase_atoms=atoms) if not np.allclose(tatoms.positions[0], np.zeros((3, ))): raise RuntimeError self.X += [tatoms.as_local()] t.close() else: raise RuntimeError('LocalsData invoked without any input') self.trainable = False
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 test_hcp(): import numpy as np from ase.io import read, Trajectory from ase.build import bulk from ase.calculators.emt import EMT class NDPoly: def __init__(self, ndims=1, order=3): """Multivariate polynomium. ndims: int Number of dimensions. order: int Order of polynomium.""" if ndims == 0: exponents = [()] else: exponents = [] for i in range(order + 1): E = NDPoly(ndims - 1, order - i).exponents exponents += [(i, ) + tuple(e) for e in E] self.exponents = np.array(exponents) self.c = None def __call__(self, *x): """Evaluate polynomial at x.""" return np.dot(self.c, (x**self.exponents).prod(1)) def fit(self, x, y): """Fit polynomium at points in x to values in y.""" A = (x**self.exponents[:, np.newaxis]).prod(2) self.c = np.linalg.solve(np.inner(A, A), np.dot(A, y)) def polyfit(x, y, order=3): """Fit polynomium at points in x to values in y. With D dimensions and N points, x must have shape (N, D) and y must have length N.""" p = NDPoly(len(x[0]), order) p.fit(x, y) return p 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.set_calculator(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) from scipy.optimize import fmin_bfgs 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
evv = EhrenfestVelocityVerlet(tdcalc) traj = Trajectory(traj_file, 'w', tdcalc.get_atoms()) trajdiv = 1 # number of timesteps between trajectory images densdiv = 10 # number of timesteps between saved electron densities niters = 100 # total number of timesteps to propagate for i in range(niters): # Stopping condition when projectile z coordinate passes threshold if evv.x[proj_idx, 2] < delta_stop: tdcalc.write(strbody + '_end.gpw', mode='all') break # Saving trajectory file every trajdiv timesteps if i % trajdiv == 0: F_av = evv.F * Hartree / Bohr # forces converted from atomic units v_av = evv.v * Bohr / AUT # velocities converted from atomic units epot = tdcalc.get_td_energy() * Hartree # energy atoms = tdcalc.get_atoms().copy() atoms.set_velocities(v_av) traj.write(atoms, energy=epot, forces=F_av) # Saving electron density every densdiv timesteps if (i != 0 and i % densdiv == 0): tdcalc.write(strbody + '_step' + str(i) + '.gpw') evv.propagate(timestep) traj.close()
class Dynamics: def __init__( self, atomsbatch, mdparam=DEFAULTNVEPARAMS, ): # initialize the atoms batch system self.atomsbatch = atomsbatch self.mdparam = mdparam # todo: structure optimization before starting # intialize system momentum MaxwellBoltzmannDistribution(self.atomsbatch, self.mdparam['T_init'] * units.kB) Stationary(self.atomsbatch) # zero linear momentum ZeroRotation(self.atomsbatch) # set thermostats integrator = self.mdparam['thermostat'] self.integrator = integrator(self.atomsbatch, **self.mdparam['thermostat_params']) # attach trajectory dump self.traj = Trajectory(self.mdparam['traj_filename'], 'w', self.atomsbatch) self.integrator.attach(self.traj.write, interval=self.mdparam['save_frequency']) # attach log file self.integrator.attach(NeuralMDLogger(self.integrator, self.atomsbatch, self.mdparam['thermo_filename'], mode='a'), interval=self.mdparam['save_frequency']) def setup_restart(self, restart_param): """If you want to restart a simulations with predfined mdparams but longer youneed to prodive a dcionary like the following: note that the thermo_filename and traj_name should be different restart_param = {'atoms_path': md_log_dir + '/atom.traj', 'thermo_filename': md_log_dir + '/thermo_restart.log', 'traj_filename': md_log_dir + '/atom_restart.traj', 'steps': 100 } Args: restart_param (dict): dictionary to contains restart paramsters and file paths """ if restart_param['thermo_filename'] == self.mdparam['thermo_filename']: raise ValueError("{} is also used, \ please change a differnt thermo file name".format( restart_param['thermo_filename'])) if restart_param['traj_filename'] == self.mdparam['traj_filename']: raise ValueError("{} is also used, \ please change a differnt traj file name".format( restart_param['traj_filename'])) self.restart_param = restart_param new_atoms = Trajectory(restart_param['atoms_path'])[-1] self.atomsbatch.set_positions(new_atoms.get_positions()) self.atomsbatch.set_velocities(new_atoms.get_velocities()) # set thermostats integrator = self.mdparam['thermostat'] self.integrator = integrator(self.atomsbatch, **self.mdparam['thermostat_params']) # attach trajectory dump self.traj = Trajectory(self.restart_param['traj_filename'], 'w', self.atomsbatch) self.integrator.attach(self.traj.write, interval=self.mdparam['save_frequency']) # attach log file self.integrator.attach(NeuralMDLogger( self.integrator, self.atomsbatch, self.restart_param['thermo_filename'], mode='a'), interval=self.mdparam['save_frequency']) self.mdparam['steps'] = restart_param['steps'] def run(self): epochs = int(self.mdparam['steps'] // self.mdparam['nbr_list_update_freq']) for step in range(epochs): self.integrator.run(self.mdparam['nbr_list_update_freq']) # # unwrap coordinates if mol_idx is defined # if self.atomsbatch.props.get("mol_idx", None) : # self.atomsbatch.set_positions(self.atoms.get_positions(wrap=True)) # self.atomsbatch.set_positions(reconstruct_atoms(atoms, self.atomsbatch.props['mol_idx'])) self.atomsbatch.update_nbr_list() self.traj.close() def save_as_xyz(self, filename='./traj.xyz'): traj = Trajectory(self.mdparam['traj_filename'], mode='r') xyz = [] skip = self.mdparam['skip'] traj = list(traj)[skip:] if len(traj) > skip else traj for snapshot in traj: frames = np.concatenate([ snapshot.get_atomic_numbers().reshape(-1, 1), snapshot.get_positions().reshape(-1, 3) ], axis=1) xyz.append(frames) write_traj(filename, np.array(xyz))
bottom_mask = np.loadtxt("bottom_mask.txt").astype(bool) top_mask = np.loadtxt("top_mask.txt").astype(bool) damp = pc.AutoDamping(C11, p_c) slider = pc.SlideWithNormalPressureCuboidCell(top_mask, bottom_mask, Pdir, P, vdir, v, damp) atoms.set_constraint(slider) calc = ASE_CALCULATOR_OBJECT # put a specific calculator here atoms.set_calculator(calc) temps = np.zeros((len(atoms), 3)) temps[slider.middle_mask, slider.Tdir] = kB * T gammas = np.zeros((len(atoms), 3)) gammas[slider.middle_mask, slider.Tdir] = gamma_langevin integrator = Langevin(atoms, dt, temps, gammas, fixcm=False) trajectory = Trajectory('slide.traj', 'a', atoms) # append with open('log_slide.txt', 'r', encoding='utf-8') as log_handle: step_offset = pc.SlideLog(log_handle).step[-1] log_handle = open('log_slide.txt', 'a', 1, encoding='utf-8') # line buffered append logger = pc.SlideLogger(log_handle, atoms, slider, integrator, step_offset) integrator.attach(logger) integrator.attach(trajectory) integrator.run(steps_integrate) log_handle.close() trajectory.close()
def test_trajectory(): import pytest import os from ase import Atom, Atoms from ase.io import Trajectory, read from ase.constraints import FixBondLength from ase.calculators.calculator import PropertyNotImplementedError co = Atoms([Atom('C', (0, 0, 0)), Atom('O', (0, 0, 1.2))]) traj = Trajectory('1.traj', 'w', co) written = [] for i in range(5): co.positions[:, 2] += 0.1 traj.write() written.append(co.copy()) traj = Trajectory('1.traj', 'a') co = read('1.traj') print(co.positions) co.positions[:] += 1 traj.write(co) written.append(co.copy()) for a in Trajectory('1.traj'): print(1, a.positions[-1, 2]) co.positions[:] += 1 t = Trajectory('1.traj', 'a') t.write(co) written.append(co.copy()) assert len(t) == 7 co[0].number = 1 t.write(co) written.append(co.copy()) co[0].number = 6 co.pbc = True t.write(co) written.append(co.copy()) co.pbc = False o = co.pop(1) t.write(co) written.append(co.copy()) co.append(o) t.write(co) written.append(co.copy()) imgs = read('1.traj', index=':') assert len(imgs) == len(written) for img1, img2 in zip(imgs, written): assert img1 == img2 # Verify slicing works. read_traj = Trajectory('1.traj', 'r') sliced_traj = read_traj[3:8] assert len(sliced_traj) == 5 sliced_again = sliced_traj[1:-1] assert len(sliced_again) == 3 assert sliced_traj[1] == sliced_again[0] # append to a nonexisting file: fname = '2.traj' if os.path.isfile(fname): os.remove(fname) t = Trajectory(fname, 'a', co) t.close() os.remove(fname) t = Trajectory('empty.traj', 'w') t.close() t = Trajectory('empty.traj', 'r') assert len(t) == 0 t = Trajectory('fake.traj', 'w') t.write(Atoms('H'), energy=-42.0, forces=[[1, 2, 3]]) t = Trajectory('only-energy.traj', 'w', properties=['energy']) a = read('fake.traj') t.write(a) b = read('only-energy.traj') e = b.get_potential_energy() assert e + 42 == 0 with pytest.raises(PropertyNotImplementedError): b.get_forces() # Make sure constraints play well with momenta: a = Atoms('H2', positions=[(0, 0, 0), (0, 0, 1)], momenta=[(1, 0, 0), (0, 0, 0)]) a.constraints = [FixBondLength(0, 1)] t = Trajectory('constraint.traj', 'w', a) t.write() b = read('constraint.traj') assert not (b.get_momenta() - a.get_momenta()).any()
assert img1 == img2 # Verify slicing works. read_traj = Trajectory('1.traj', 'r') sliced_traj = read_traj[3:8] assert len(sliced_traj) == 5 sliced_again = sliced_traj[1:-1] assert len(sliced_again) == 3 assert sliced_traj[1] == sliced_again[0] # append to a nonexisting file: fname = '2.traj' if os.path.isfile(fname): os.remove(fname) t = Trajectory(fname, 'a', co) t.close() os.remove(fname) t = Trajectory('empty.traj', 'w') t.close() t = Trajectory('empty.traj', 'r') assert len(t) == 0 t = Trajectory('fake.traj', 'w') t.write(Atoms('H'), energy=-42.0, forces=[[1, 2, 3]]) t = Trajectory('only-energy.traj', 'w', properties=['energy']) a = read('fake.traj') t.write(a) b = read('only-energy.traj') e = b.get_potential_energy()
def calculate_ET(self, unit_cell_a, unit_cell_b): """ Set up ET calculator and calculate transmission of interface_config_structure """ # either write or read the restart file depending on if we performed # the initial energy or interface search if (self.restart is not False): traj = Trajectory(self.input.dict['restart_path'] + '/' + self.input.dict['restart_file'] + '.traj') self.interface.atom = traj[0] self.interface.file_name = self.input.dict['restart_file'] traj.close() else: temp = Trajectory(filename='ET_restart_coord.traj', mode='w', atoms=self.interface.atom) temp.write() temp.close() # read the output file to get the basis set sizes scatter_basis, scatter_number = self.get_basis_sizes( self.input.dict['restart_path'] + self.interface.file_name + '.out') # determine the important dimensions llead_dimens, llead_apl, llead_number = self.determine_dimensions( unit_cell_a, 1) rlead_dimens, rlead_apl, rlead_number = self.determine_dimensions( unit_cell_b, 2) # gather what we need from the last output of the whole system energy # calculation and the initial unit cells basis_a = 0 basis_b = 0 for i in scatter_basis: basis_a += scatter_basis[i] * llead_number[i] basis_b += scatter_basis[i] * rlead_number[i] Total_basis = 0 for i in scatter_basis: Total_basis += scatter_basis[i] * scatter_number[i] N1 = abs( int((basis_a / llead_dimens[2, 2]) * int(self.input.dict['number_of_layers_a']))) N2 = abs( int((basis_b / rlead_dimens[2, 2]) * int(self.input.dict['number_of_layers_b']))) N = int(Total_basis - N1 - N2) # take a moment to print out the filename being used printx('\n' + self.interface.file_name + '\n', self.file) collected = gc.collect() printx("Garbage collector: collected %d objects." % (collected)) if (self.input.dict['et_method'] is not 'ASE'): Hamil, Overlap = self.get_whole_matrix( Total_basis, self.input.dict['restart_path'] + self.interface.file_name + '-hamiltonian-1_0.Log') else: scatter_hamil = self.get_matrices( N, N1, N2, self.input.dict['restart_path'] + self.interface.file_name + '-hamiltonian-1_0.Log') if (self.input.dict['et_method'] is not 'ASE'): points = self.input.dict['energy_levels_ET'] starting = points[0] step_size = points[2] steps = int((points[1] - points[0]) / points[2]) Transmission = ptw.call_slymer(Hamil, Overlap, N1, N2, steps, starting, step_size) printx("Transmission values \n", self.file) et_energy = starting for output in Transmission: printx(str(et_energy) + ' ' + str(output), self.file) et_energy += step_size else: ase_et(scatter_hamil) return
p = NDPoly(len(x[0]), order) p.fit(x, y) return p 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.set_calculator(EMT()) ni.get_potential_energy() traj.write(ni) traj.close() configs = read('Ni.traj@:') 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) from scipy.optimize import fmin_bfgs 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 loop_over_angles(self, temp_storage, lowest_energy): backup_initial = lowest_energy.copy() temp_angles = [[] for y in range(2)] # setup energy output file header if (self.input.dict['angle_write_energy_file'] == 'True'): angle_energy = open( self.input.dict['project_name'] + '.a_e.log', 'a') angle_energy.write("===================\nSurface : " + str(self.surf_a) + '/' + str(self.surf_b) + '\n') angle_energy.write( "===================\nAngle Energy Atoms\n\n") angle_energy.close() # loop over angles for j in self.input.dict['angles_list']: printx('===========\n', self.file) printx('beginning rotation of ' + str(j) + ' degrees:\n', self.file) Backup_atom = self.initial.unit_cell_a.copy() radians = pi * j / 180.0 self.interface.cut_cell_a = self.interface.rotate_cell( self.initial.unit_cell_a, radians).copy() try: self.interface.generate_interface() except Exception as err: [printx(x, self.file) for x in err.args] if self.input.dict['print_debug'] != 'False': print_exc() self.initial.unit_cell_a = Backup_atom.copy() continue printx('printing output: angle = ' + str(j) + ' atoms = ' + str(len(self.interface.interface)) + '\n', self.file) temp_angles[0].append(j) temp_angles[1].append(len(self.interface.interface)) # calculate energy and return lowest energy configuration if (self.input.dict['angle_calculate_energy'] != 'False'): temp_storage.atom = self.interface.interface.copy() surf_index_a = ''.join(str(x) for x in self.surf_a) surf_index_b = ''.join(str(y) for y in self.surf_b) temp_storage.file_name = (self.input.dict['project_name'] + '.' + str( j) + '.' + surf_index_a + surf_index_b) temp_storage.step = j temp_storage.unit_cell_a = self.interface.cut_cell_a.copy() temp_storage.unit_cell_b = self.interface.cut_cell_b.copy() # Check to see if this combination of surfaces and angle has # already been calculated to save on work done Exist = os.path.isfile(temp_storage.file_name + '.out') if Exist: printx("Duplicate angle for energy calculation detected." "Skipping energy calculation") temp_storage.energy = 1.0e10 else: # print out a traj file that can be used for ET calcs # without calculating energy again if (self.input.dict['angle_write_restart'] != 'False'): temp_name = temp_storage.file_name + '.traj' traj = Trajectory(filename=(temp_name), mode='w', atoms=temp_storage.atom) traj.write() traj.close() try: EnergyCalc( self.input, self.input.dict['energy_method'], temp_storage, 'run') except Exception as err: [printx(x) for x in err.args] printx( 'An error occured when calculating the energy ' 'for rotation ' + str(j) + ' degrees') continue if self.input.dict['angle_optimize_separation'] != 'False': temp_storage = self.optimize_separation(temp_storage) try: if (self.input.dict['calculate_binding_energy'] != 'False'): temp_storage.energy = calculate_binding_energy( temp_storage, self.input) except Exception as err: [printx(x) for x in err.args] printx( 'An error occured when calculating the energy for ' 'rotation ' + str(j) + ' degrees') continue # determine if this is lowest energy structure if (temp_storage.energy < lowest_energy.energy): lowest_energy = temp_storage.copy() if (self.input.dict['angle_write_energy_file'] == 'True' and not Exist): angle_energy = open( self.input.dict['project_name'] + '.a_e.log', 'a', 0) angle_energy.write(str(j) + ' ' + str(temp_storage.energy) + ' ' + str(len(self.interface.interface)) + '\n') angle_energy.close() # set up information in case we didn't run the energy calculation else: temp_storage.atom = self.interface.interface.copy() surf_index_a = ''.join(str(x) for x in self.surf_a) surf_index_b = ''.join(str(y) for y in self.surf_b) temp_storage.file_name = (self.input.dict['project_name'] + '.' + str( j) + '.' + surf_index_a + surf_index_b) temp_storage.step = j temp_storage.unit_cell_a = self.interface.cut_cell_a.copy() temp_storage.unit_cell_b = self.interface.cut_cell_b.copy() lowest_energy = temp_storage.copy() # write the xyz file if (self.input.dict['angle_write_coord_file'] == 'True'): write_storage = ICS() if self.input.dict['angle_calculate_energy'] != 'False': write_storage.atom = temp_storage.atom.copy() else: write_storage.atom = self.interface.interface.copy() write_storage.file_name = (self.input.dict['project_name'] + '.' + str(j)) write_xyz(write_storage) self.initial.unit_cell_a = Backup_atom.copy() printx("\nLowest Energy configuration correspond to angle " + str(lowest_energy.step) + '\n', self.file) if (self.input.dict['angle_return_initial'] != 'True'): return lowest_energy, temp_angles else: return backup_initial, temp_angles
class TI: def __init__( self, atomsbatch, final_aggr, init_aggr, mdparam=DEFAULTNVEPARAMS, ): ''' from nff.io import NeuralFF modelparams = dict() modelparams['n_atom_basis'] = 128 modelparams['n_filters'] = 128 modelparams['n_gaussians'] = 32 modelparams['n_convolutions'] = 3 modelparams['n_convolutions'] = 3 modelparams['cutoff'] = 3 thermo_int = GraphConvIntegration(modelparams) calc = NeuralFF(model=thermo_int, device=1) final_aggr = torch.Tensor([1.] * 127 + [0.]) init_aggr = torch.Tensor([1.] * 128) bulk.set_calculator(calc) nve = TI(bulk, final_aggr, init_aggr, DEFAULTNVEPARAMS) ''' # initialize the atoms batch system self.atomsbatch = atomsbatch self.mdparam = mdparam self.init_aggr = init_aggr self.final_aggr = final_aggr # todo: structure optimization before starting # intialize system momentum MaxwellBoltzmannDistribution(self.atomsbatch, self.mdparam['T_init'] * units.kB) # set thermostats integrator = self.mdparam['thermostat'] self.integrator = integrator(self.atomsbatch, **self.mdparam['thermostat_params']) # attach trajectory dump self.traj = Trajectory(self.mdparam['traj_filename'], 'w', self.atomsbatch) self.integrator.attach(self.traj.write, interval=mdparam['save_frequency']) # attach log file self.integrator.attach(NeuralMDLogger(self.integrator, self.atomsbatch, self.mdparam['thermo_filename'], mode='a'), interval=mdparam['save_frequency']) def run(self): # epochs = int(self.mdparam['steps'] // self.mdparam['nbr_list_update_freq']) dlambda = (self.final_aggr - self.init_aggr) / epochs self.atomsbatch.props['aggr_wgt'] = self.init_aggr for step in range(epochs): self.integrator.run(self.mdparam['nbr_list_update_freq']) self.atomsbatch.update_nbr_list() self.atomsbatch.props['aggr_wgt'] += dlambda # update self.traj.close()
o = co.pop(1) with must_raise(ValueError): t.write(co) co.append(o) t.write(co) # append to a nonexisting file: fname = '2.traj' if os.path.isfile(fname): os.remove(fname) t = Trajectory(fname, 'a', co) os.remove(fname) t = Trajectory('empty.traj', 'w') t.close() assert os.path.getsize('empty.traj') == 0 t = Trajectory('fake.traj', 'w') t.write(Atoms('H'), energy=-42.0, forces=[[1, 2, 3]]) t = Trajectory('only-energy.traj', 'w', properties=['energy']) a = read('fake.traj') t.write(a) b = read('only-energy.traj') e = b.get_potential_energy() assert e + 42 == 0 with must_raise(NotImplementedError): f = b.get_forces() # Make sure constraints play well with momenta:
def to_traj(self, trajname, mode='w', start=0): from ase.io import Trajectory t = Trajectory(trajname, mode) for loc in self.X[start:]: t.write(loc.as_atoms()) t.close()
# coding=utf-8 #Append one trajectory to the end of another from ase.io import Trajectory t1 = Trajectory('t1.traj', 'a') t2 = Trajectory('t2.traj') for atoms in t2: t1.write(atoms) t1.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 = Trajectory('%s.mode.%d.traj' % (self.name, n), 'w') for x in np.linspace(0, 2 * pi, nimages, endpoint=False): # XXX Is it correct to take out the sine component here ? atoms.set_positions(pos_mav + sin(x) * mode_mav) traj.write(atoms) traj.close()
class Dynamics: def __init__( self, atomsbatch, mdparam=DEFAULTNVEPARAMS, ): # initialize the atoms batch system self.atomsbatch = atomsbatch self.mdparam = mdparam # todo: structure optimization before starting # intialize system momentum MaxwellBoltzmannDistribution(self.atomsbatch, self.mdparam['T_init'] * units.kB) # set thermostats integrator = self.mdparam['thermostat'] self.integrator = integrator(self.atomsbatch, **self.mdparam['thermostat_params']) # attach trajectory dump self.traj = Trajectory(self.mdparam['traj_filename'], 'w', self.atomsbatch) self.integrator.attach(self.traj.write, interval=mdparam['save_frequency']) # attach log file self.integrator.attach(NeuralMDLogger(self.integrator, self.atomsbatch, self.mdparam['thermo_filename'], mode='a'), interval=mdparam['save_frequency']) def run(self): # epochs = int(self.mdparam['steps'] // self.mdparam['nbr_list_update_freq']) for step in range(epochs): self.integrator.run(self.mdparam['nbr_list_update_freq']) self.atomsbatch.update_nbr_list() self.traj.close() def save_as_xyz(self, filename='./traj.xyz'): ''' TODO: save time information TODO: subclass TrajectoryReader/TrajectoryReader to digest AtomsBatch instead of Atoms? TODO: other system variables in .xyz formats ''' traj = Trajectory(self.mdparam['traj_filename'], mode='r') xyz = [] skip = self.mdparam['skip'] traj = list(traj)[skip:] if len(traj) > skip else traj for snapshot in traj: frames = np.concatenate([ snapshot.get_atomic_numbers().reshape(-1, 1), snapshot.get_positions().reshape(-1, 3) ], axis=1) xyz.append(frames) write_traj(filename, np.array(xyz))