def _log(self, cat='msg', message=None): """Records the message as a line in the log file.""" if cat == 'init': if rank == 0: if os.path.exists(self._logfile): raise RuntimeError('File exists: %s' % self._logfile) f = paropen(self._logfile, 'w') f.write('par: %12s %12s %12s\n' % ('T (K)', 'Ediff (eV)', 'mdmin')) f.write('ene: %12s %12s %12s\n' % ('E_current', 'E_previous', 'Difference')) f.close() return f = paropen(self._logfile, 'a') if cat == 'msg': line = 'msg: %s' % message elif cat == 'par': line = ('par: %12.4f %12.4f %12i' % (self._temperature, self._Ediff, self._mdmin)) elif cat == 'ene': current = self._atoms.get_potential_energy() if self._previous_optimum: previous = self._previous_energy line = ('ene: %12.5f %12.5f %12.5f' % (current, previous, current - previous)) else: line = ('ene: %12.5f' % current) f.write(line + '\n') f.close()
def _write_metadata(self, metadata): """Write the metadata file of the bundle. Modifies the medadata dictionary! """ # Add standard fields that must always be present. assert self.state == 'write' or self.state == 'prewrite' metadata['format'] = 'BundleTrajectory' metadata['version'] = self.version metadata['subtype'] = self.subtype metadata['backend'] = self.backend_name if self.backend_name == 'ulm': metadata['ulm.singleprecision'] = self.singleprecision metadata['python_ver'] = tuple(sys.version_info) f = paropen(os.path.join(self.filename, 'metadata.json'), 'w') fido = jsonio.encode(metadata) f.write(fido) f.close() # Write a compatibility .pickle file - will be picked up by # older versions of ASE and result in a meaningful error. metadata['comment'] = ('For compatibility only - ' 'see metadata.json instead.') f = paropen(os.path.join(self.filename, 'metadata'), 'wb') pickle.dump(metadata, f, protocol=0) del metadata['comment'] f.close()
def read_lammps_log(self, lammps_log=None, PotEng_first=False): """Method which reads a LAMMPS output log file.""" if (lammps_log == None): lammps_log = self.label + '.log' if isinstance(lammps_log, str): f = paropen(lammps_log, 'w') close_log_file = True else: # Expect lammps_in to be a file-like object f = lammps_log close_log_file = False thermo_content = [] line = f.readline() while line and line.strip() != CALCULATION_END_MARK: # get thermo output if line.startswith(self._custom_thermo_mark): m = True while m: line = f.readline() m = self._custom_thermo_re.match(line) if m: # create a dictionary between each of the thermo_style args # and it's corresponding value thermo_content.append(dict(zip(self._custom_thermo_args, map(float, m.groups())))) else: line = f.readline() if close_log_file: f.close() self.thermo_content = thermo_content
def write_mies_weights(self, wfs, file=None): if file is None: file = 'eed_mies.dat' if isinstance(file, str): out = paropen(file, 'aw') else: out = file fmf = FMF(['exterior electron density weights after', 'Y. Harada et al., Chem. Rev. 97 (1997) 1897']) print >> out, fmf.header(), print >> out, fmf.data(['band index: n', 'k-point index: k', 'spin index: s', 'k-point weight: weight', 'energy: energy [eV]', 'occupation number: occ', 'relative EED weight: eed_weight']), print >> out, '#; n k s weight energy occ eed_weight' for kpt in wfs.kpt_u: for n in range(wfs.nbands): print >> out, '%4d %3d %1d %8.5f %10.5f %10.5f %10.5f' % \ (n, kpt.k, kpt.s, kpt.weight, kpt.eps_n[n] * Hartree, kpt.f_n[n], self.get_weight(kpt.psit_nG[n]) ) if hasattr(out, 'flush'): out.flush()
def summary(self, omega, gamma=0.1, method='standard', direction='central', intensity_unit='(D/A)2/amu', log=sys.stdout): """Print summary for given omega [eV]""" hnu = self.get_energies(method, direction) s = 0.01 * units._e / units._c / units._hplanck intensities = self.get_intensities(omega, gamma) if isinstance(log, str): log = paropen(log, 'a') parprint('-------------------------------------', file=log) parprint(' excitation at ' + str(omega) + ' eV', file=log) parprint(' gamma ' + str(gamma) + ' eV\n', file=log) parprint(' Mode Frequency Intensity', file=log) parprint(' # meV cm^-1 [a.u.]', file=log) parprint('-------------------------------------', file=log) for n, e in enumerate(hnu): if e.imag != 0: c = 'i' e = e.imag else: c = ' ' e = e.real parprint('%3d %6.1f%s %7.1f%s %9.3g' % (n, 1000 * e, c, s * e, c, intensities[n]), file=log) parprint('-------------------------------------', file=log) parprint('Zero-point energy: %.3f eV' % self.get_zero_point_energy(), file=log)
def _resume(self): """Attempt to resume a run, based on information in the log file. Note it will almost always be interrupted in the middle of either a qn or md run or when exceeding totalsteps, so it only has been tested in those cases currently.""" f = paropen(self._logfile, 'r') lines = f.read().splitlines() f.close() self._log('msg', 'Attempting to resume stopped run.') self._log('msg', 'Using existing minima file with %i prior ' 'minima: %s' % (len(self._minima), self._minima_traj)) mdcount, qncount = 0, 0 for line in lines: if (line[:4] == 'par:') and ('Ediff' not in line): self._temperature = eval(line.split()[1]) self._Ediff = eval(line.split()[2]) elif line[:18] == 'msg: Optimization:': qncount = int(line[19:].split('qn')[1]) elif line[:24] == 'msg: Molecular dynamics:': mdcount = int(line[25:].split('md')[1]) self._counter = max((mdcount, qncount)) if qncount == mdcount: # Either stopped during local optimization or terminated due to # max steps. self._log('msg', 'Attempting to resume at qn%05i' % qncount) if qncount > 0: atoms = io.read('qn%05i.traj' % (qncount - 1), index=-1) self._previous_optimum = atoms.copy() self._previous_energy = atoms.get_potential_energy() if os.path.getsize('qn%05i.traj' % qncount) > 0: atoms = io.read('qn%05i.traj' % qncount, index=-1) else: atoms = io.read('md%05i.traj' % qncount, index=-3) self._atoms.positions = atoms.get_positions() fmax = np.sqrt((atoms.get_forces() ** 2).sum(axis=1).max()) if fmax < self._fmax: # Stopped after a qn finished. self._log('msg', 'qn%05i fmax already less than fmax=%.3f' % (qncount, self._fmax)) self._counter += 1 return self._optimize() self._counter += 1 if qncount > 0: self._check_results() else: self._record_minimum() self._log('msg', 'Found a new minimum.') self._log('msg', 'Accepted new minimum.') self._log('par') elif qncount < mdcount: # Probably stopped during molecular dynamics. self._log('msg', 'Attempting to resume at md%05i.' % mdcount) atoms = io.read('qn%05i.traj' % qncount, index=-1) self._previous_optimum = atoms.copy() self._previous_energy = atoms.get_potential_energy() self._molecular_dynamics(resume=mdcount) self._optimize() self._counter += 1 self._check_results()
def write_clr(f, atoms): """Write extra color and radius code to a CLR-file (for use with AtomEye). Hit F12 in AtomEye to use. See: http://mt.seas.upenn.edu/Archive/Graphics/A/ """ color = None radius = None if atoms.has('color'): color = atoms.get_array('color') if atoms.has('radius'): radius = atoms.get_array('radius') if color is None: color = np.zeros([len(atoms), 3], dtype=float) for a in atoms: color[a.index, :] = default_color[a.symbol] if radius is None: radius = np.zeros(len(atoms), dtype=float) for a in atoms: radius[a.index] = default_radius[a.symbol] radius.shape = (-1, 1) if isinstance(f, basestring): f = paropen(f, 'w') for c1, c2, c3, r in np.append(color, radius, axis=1): f.write('%f %f %f %f\n' % (c1, c2, c3, r))
def read_results(self): FileIOCalculator.read_results(self) onetep_file = self.label + '.out' warnings = [] try: out = paropen(onetep_file, 'r') except IOError: raise ReadError('Could not open output file "%s"' % onetep_file) line = out.readline() while line: if '| Total' in line: self.results['energy'] = Hartree * float(line.split()[-2]) elif ('Element Atom Cartesian components (Eh/a)' in line): self._read_forces(out) elif 'warn' in line.lower(): warnings.append(line) line = out.readline() if warnings: warn('WARNING: %s contains warnings' % onetep_file) for warning in warnings: warn(warning)
def __init__( self, vibrations_object, settings={}, log=sys.stdout, pre_names='an_mode_', ): """Initialization Args: vibrations_object (obj): The vibration object of ASE. settings (optional[dict]): Change default behavior. E.g. "tempurature": 400 # (400K instead of 300K). log (optional[str]): name of log file. """ self.vib = vibrations_object self.pre_names = pre_names self.settings = settings if isinstance(log, str): log = paropen(log, 'a') self.log = log self.atoms = self.vib.atoms self.an_modes = [] self.h_modes = None # harmonic modes self.h_freq = None # harmonic modes self.reduced_h_modes = self.vib.modes # For harmonic subspace self.kT = units.kB * self.settings.get('temperature', 300) # kelvin self.ev__inv_cm = 0.01 * units._e / units._c / units._hplanck
def to_file(self, calculator, filename='multipole.dat', mode='a'): """Expand the charge distribution in multipoles and write the result to a file""" if self.gd is None: self.initialize(calculator.density.finegd) q_L = self.expand(-calculator.density.rhot_g) f = paropen(filename, mode) prnt('# Multipole expansion of the charge density', file=f) prnt('# center =', self.center * Bohr, 'Angstrom', file=f) prnt('# lmax =', self.lmax, file=f) prnt(('# see https://trac.fysik.dtu.dk/projects/gpaw/browser/' + 'trunk/c/bmgs/sharmonic.py'), file=f) prnt('# for the definition of spherical harmonics', file=f) prnt('# l m q_lm[|e| Angstrom**l]', file=f) L = 0 for l in range(self.lmax + 1): for m in range(-l, l + 1): prnt('{0:2d} {1:3d} {2:g}'.format(l, m, q_L[L]), file=f) L += 1 f.close()
def write(self, filename=None, fh=None): """Write current state to a file. 'filename' is the filename. If the filename ends in .gz, the file is automatically saved in compressed gzip format. 'fh' is a filehandle. This can be used to write into already opened files. """ if self.world.rank != 0: return if fh is None: if filename.endswith('.gz') and mpi.rank == mpi.MASTER: import gzip f = gzip.open(filename, 'wb') else: f = paropen(filename, 'w') else: f = fh f.write('# KSSingles\n') f.write('{0} {1}\n'.format(len(self), np.dtype(self.dtype))) f.write('{0}\n'.format(self.eps)) for kss in self: f.write(kss.outstring()) if fh is None: f.close()
def write_gjf(fileobj, images): if isinstance(fileobj, str): fileobj = paropen(fileobj, 'w') if not isinstance(images, (list, tuple)): images = [images] symbols = images[0].get_chemical_symbols() natoms = len(symbols) for atoms in images: this_info = atoms.info fileobj.write('%5s%-20s \n' % ('%mem=',this_info["mem"])) fileobj.write('%7s \n' % ('%NoSave')) fileobj.write('%5s%8s%4s\n' % ('%chk=',this_info["filebase"],'.chk')) fileobj.write('%6s%-20s\n' % ('%nproc=',this_info["ncpus"])) fileobj.write('%13s \n\n' % ('#Method/basis')) fileobj.write('%8s \n\n' % (this_info["filebase"])) fileobj.write('%d %d\n' % (this_info["charge"], this_info["multiplicity"])) for s, (x, y, z) in zip(symbols, atoms.get_positions()): fileobj.write('%-2s %22.15f %22.15f %22.15f\n' % (s, x, y, z)) if images[0].pbc.any(): fileobj.write('%-5s %8.3f %8.3f %8.3f \n' % ('Tv', images[0].get_cell()[0][0], images[0].get_cell()[0][1], images[0].get_cell()[0][2])) fileobj.write('%-5s %8.3f %8.3f %8.3f \n' % ('Tv', images[0].get_cell()[1][0], images[0].get_cell()[1][1], images[0].get_cell()[1][2])) fileobj.write('%-5s %8.3f %8.3f %8.3f \n' % ('Tv', images[0].get_cell()[2][0], images[0].get_cell()[2][1], images[0].get_cell()[2][2]))
def write_cyc(fn, this, conv=1.0): """ Write the lattice information to a cyc.dat file (i.e., tblmd input file) """ lattice = this.get_cell() f = paropen(fn, "w") f.write("<------- Simulation box definition\n") f.write("<------- Barostat (on = 1, off = 0)\n") f.write(" 0\n") f.write("<------- Box vectors (start)\n") f.write(" %20.10f %20.10f %20.10f\n" % (lattice[0][0]*conv, lattice[1][0]*conv, lattice[2][0]*conv)) f.write(" %20.10f %20.10f %20.10f\n" % (lattice[0][1]*conv, lattice[1][1]*conv, lattice[2][1]*conv)) f.write(" %20.10f %20.10f %20.10f\n" % (lattice[0][2]*conv, lattice[1][2]*conv, lattice[2][2]*conv)) f.write("<------- Box vectors (end)\n") f.write(" %20.10f %20.10f %20.10f\n" % (lattice[0][0]*conv, lattice[1][0]*conv, lattice[2][0]*conv)) f.write(" %20.10f %20.10f %20.10f\n" % (lattice[0][1]*conv, lattice[1][1]*conv, lattice[2][1]*conv)) f.write(" %20.10f %20.10f %20.10f\n" % (lattice[0][2]*conv, lattice[1][2]*conv, lattice[2][2]*conv)) f.write("<------- Mass and gamma of the box (used in connection with the barostat)\n") f.write(" 240 0.005\n") f.write("<------- Stress tensor (start)\n") f.write(" 0 0 0\n") f.write(" 0 0 0\n") f.write(" 0 0 0\n") f.write("<------- Stress tensor (end)\n") f.write(" 0 0 0\n") f.write(" 0 0 0\n") f.write(" 0 0 0\n") f.close()
def read_cyc(this, fn, conv=1.0): """ Read the lattice information from a cyc.dat file (i.e., tblmd input file) """ f = paropen(fn, "r") f.readline() f.readline() f.readline() f.readline() cell = np.array( [ [ 0.0, 0.0, 0.0 ], [ 0.0, 0.0, 0.0 ], [ 0.0, 0.0, 0.0 ] ] ) l = f.readline() s = map(float, l.split()) cell[0, 0] = s[0]*conv cell[1, 0] = s[1]*conv cell[2, 0] = s[2]*conv l = f.readline() s = map(float, l.split()) cell[0, 1] = s[0]*conv cell[1, 1] = s[1]*conv cell[2, 1] = s[2]*conv l = f.readline() s = map(float, l.split()) cell[0, 2] = s[0]*conv cell[1, 2] = s[1]*conv cell[2, 2] = s[2]*conv this.set_cell(cell) this.set_pbc(True) f.close()
def write_lammps_data(fileobj, atoms, specorder=None, force_skew=False, prismobj=None, velocities=False): """Method which writes atomic structure data to a LAMMPS data file.""" if isinstance(fileobj, str): f = paropen(fileobj, 'w') close_file = True else: # Presume fileobj acts like a fileobj f = fileobj close_file = False if isinstance(atoms, list): if len(atoms) > 1: raise ValueError('Can only write one configuration to a lammps data file!') atoms = atoms[0] f.write(f.name + ' (written by ASE) \n\n') symbols = atoms.get_chemical_symbols() n_atoms = len(symbols) f.write('%d \t atoms \n' % n_atoms) if specorder is None: # This way it is assured that LAMMPS atom types are always # assigned predictively according to the alphabetic order species = sorted(set(symbols)) else: # To index elements in the LAMMPS data file # (indices must correspond to order in the potential file) species = specorder n_atom_types = len(species) f.write('%d atom types\n' % n_atom_types) if prismobj is None: p = prism(atoms.get_cell()) else: p = prismobj xhi, yhi, zhi, xy, xz, yz = p.get_lammps_prism_str() f.write('0.0 %s xlo xhi\n' % xhi) f.write('0.0 %s ylo yhi\n' % yhi) f.write('0.0 %s zlo zhi\n' % zhi) if force_skew or p.is_skewed(): f.write('%s %s %s xy xz yz\n' % (xy, xz, yz)) f.write('\n\n') f.write('Atoms \n\n') for i, r in enumerate(map(p.pos_to_lammps_str, atoms.get_positions())): s = species.index(symbols[i]) + 1 f.write('%6d %3d %s %s %s\n' % ((i+1, s)+tuple(r))) if velocities and atoms.get_velocities() is not None: f.write('\n\nVelocities \n\n') for i, v in enumerate(atoms.get_velocities()): f.write('%6d %s %s %s\n' % ((i+1,)+tuple(v))) if close_file: f.close()
def write_pdb(fileobj, images): """Write images to PDB-file. The format is assumed to follow the description given in http://www.wwpdb.org/documentation/format32/sect9.html.""" if isinstance(fileobj, str): fileobj = paropen(fileobj, 'w') if not isinstance(images, (list, tuple)): images = [images] if images[0].get_pbc().any(): from ase.lattice.spacegroup.cell import cell_to_cellpar cellpar = cell_to_cellpar( images[0].get_cell()) # ignoring Z-value, using P1 since we have all atoms defined explicitly format = 'CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f P 1\n' fileobj.write(format % (cellpar[0], cellpar[1], cellpar[2], cellpar[3], cellpar[4], cellpar[5])) # 1234567 123 6789012345678901 89 67 456789012345678901234567 890 format = 'ATOM %5d %4s MOL 1 %8.3f%8.3f%8.3f 1.00 0.00 %2s \n' # RasMol complains if the atom index exceeds 100000. There might # be a limit of 5 digit numbers in this field. MAXNUM = 100000 symbols = images[0].get_chemical_symbols() natoms = len(symbols) for n,atoms in enumerate(images): fileobj.write('MODEL '+str(n+1)+'\n') p = atoms.get_positions() for a in range(natoms): x, y, z = p[a] fileobj.write(format % (a % MAXNUM, symbols[a], x, y, z, symbols[a].rjust(2))) fileobj.write('ENDMDL\n')
def summary(self, method='standard', direction='central', intensity_unit='(D/A)2/amu', log=stdout): hnu = self.get_energies(method, direction) s = 0.01 * units._e / units._c / units._hplanck iu, iu_string = self.intensity_prefactor(intensity_unit) if intensity_unit == '(D/A)2/amu': iu_format = '%9.4f' elif intensity_unit == 'km/mol': iu_string = ' ' + iu_string iu_format = ' %7.1f' if isinstance(log, str): log = paropen(log, 'a') parprint('-------------------------------------', file=log) parprint(' Mode Frequency Intensity', file=log) parprint(' # meV cm^-1 ' + iu_string, file=log) parprint('-------------------------------------', file=log) for n, e in enumerate(hnu): if e.imag != 0: c = 'i' e = e.imag else: c = ' ' parprint(('%3d %6.1f%s %7.1f%s ' + iu_format) % (n, 1000 * e, c, s * e, c, iu * self.intensities[n]), file=log) parprint('-------------------------------------', file=log) parprint('Zero-point energy: %.3f eV' % self.get_zero_point_energy(), file=log) parprint('Static dipole moment: %.3f D' % self.dipole_zero, file=log) parprint('Maximum force on atom in `equilibrium`: %.4f eV/Å' % self.force_zero, file=log) parprint(file=log)
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 get_rpa_correlation_energy(self, kcommsize=1, ecut=10, nbands=None, w=np.linspace(0, 200., 32), extrapolate=True, restart=None): self.initialize_calculation(w, ecut, nbands, kcommsize, extrapolate) E_q = [] if restart is not None: assert type(restart) is str try: f = paropen(restart, 'r') lines = f.readlines() for line in lines: E_q.append(eval(line)) f.close() print >> self.txt, 'Correlation energy from %s Q-points obtained from restart file: ' % len(E_q), restart print >> self.txt except: IOError for index, q in enumerate(self.ibz_q_points[len(E_q):]): E_q.append(self.get_E_q(kcommsize=kcommsize, index=index, q=q, ecut=ecut, nbands=self.nbands, w=w, extrapolate=extrapolate)) if restart is not None: f = paropen(restart, 'a') print >> f, E_q[-1] f.close() E = np.dot(np.array(self.q_weights), np.array(E_q).real) print >> self.txt, 'RPA correlation energy:' print >> self.txt, 'E_c = %s eV' % E print >> self.txt print >> self.txt, 'Calculation completed at: ', ctime() print >> self.txt print >> self.txt, '------------------------------------------------------' print >> self.txt return E
def write_gromacs(fileobj, images): """Write gromacs geometry files (\*.gro). Writes: atom positions, velocities (if present, otherwise 0) and simulation cell (if present) """ from ase import units if isinstance(fileobj, str): fileobj = paropen(fileobj, "w") if not isinstance(images, (list, tuple)): images = [images] natoms = images[-1].get_number_of_atoms() try: gromacs_residuenames = images[-1].get_array("residuenames") except: gromacs_residuenames = [] for idum in range(natoms): gromacs_residuenames.append("1DUM") try: gromacs_atomtypes = images[-1].get_array("atomtypes") except: gromacs_atomtypes = images[-1].get_chemical_symbols() pos = images[-1].get_positions() pos = pos / 10.0 try: vel = images[-1].get_velocities() vel = vel * 1000.0 * units.fs / units.nm except: vel = pos vel = pos * 0.0 fileobj.write("#A Gromacs structure file written by ASE \n") fileobj.write("%5d \n" % images[-1].get_number_of_atoms()) count = 1 for resname, atomtype, xyz, vxyz in zip(gromacs_residuenames, gromacs_atomtypes, pos, vel): fileobj.write( " %5s %5s%5d%8.3f%8.3f%8.3f%8.4f%8.4f%8.4f\n" % (resname, atomtype, count, xyz[0], xyz[1], xyz[2], vxyz[0], vxyz[1], vxyz[2]) ) count = count + 1 if images[-1].get_pbc().any(): mycell = images[-1].get_cell() # gromacs manual (manual.gromacs.org/online/gro.html) says: # v1(x) v2(y) v3(z) v1(y) v1(z) v2(x) v2(z) v3(x) v3(y) # # cell[0,0] cell[1,0] cell[2,0] v1(x) v2(y) v3(z) fv0[0 1 2] # cell[0,1] cell[1,1] cell[2,1] v1(y) v1(z) v2(x) fv1[0 1 2] # cell[0,2] cell[1,2] cell[2,2] v2(z) v3(x) v3(y) fv2[0 1 2] fileobj.write("%10.5f%10.5f%10.5f" % (mycell[0, 0] * 0.1, mycell[1, 1] * 0.1, mycell[2, 2] * 0.1)) fileobj.write("%10.5f%10.5f%10.5f" % (mycell[1, 0] * 0.1, mycell[2, 0] * 0.1, mycell[0, 1] * 0.1)) fileobj.write("%10.5f%10.5f%10.5f\n" % (mycell[2, 1] * 0.1, mycell[0, 2] * 0.1, mycell[1, 2] * 0.1)) return
def write_to_restartfile(self): import pickle f = paropen(self.restartfile,'wb') pickle.dump((self.oldpos, self.oldG, self.oldenergy, self.radius, self.hessian, self.energy_estimate),f) f.close()
def read(self, label): """Read a onetep .out file into the current instance.""" FileIOCalculator.read(self, label) onetep_file = self.label + '.out' warnings = [] try: out = paropen(onetep_file, 'r') except IOError: raise ReadError('Could not open output file "%s"' % onetep_file) # keep track of what we've read in read_lattice = False read_species = False read_positions = False line = out.readline() if self.atoms is None: self.atoms = Atoms() self.atoms.calc = self while line: clean_line = line.strip().lower() if '%block lattice_cart' in clean_line: self._read_lattice(out) read_lattice = True elif '%block species_pot' in clean_line: self._read_species_pot(out) elif '%block species' in clean_line: self._read_species(out) read_species = True elif '%block positions_abs' in clean_line: self._read_positions(out) read_positions = True elif '%block species_cond' in clean_line: self._read_species_cond(out) elif 'warn' in line.lower(): warnings.append(line) line = out.readline() out.close() if warnings: warn('WARNING: %s contains warnings' % onetep_file) for warning in warnings: warn(warning) if not (read_lattice and read_species and read_positions): raise ReadError('Failed to read in essential calculation' ' data from output file "%s"' % onetep_file) self.read_results(label)
def __init__(self, name, hybrid=None, xc=None, finegrid=False, alpha=None, skip_gamma=False, gygi=False, acdf=True, qsym=True, txt=None, ecut=None): """Mix standard functionals with exact exchange. name: str Name of hybrid functional. hybrid: float Fraction of exact exchange. xc: str or XCFunctional object Standard DFT functional with scaled down exchange. finegrid: boolean Use fine grid for energy functional evaluations? """ if name == 'EXX': assert hybrid is None and xc is None hybrid = 1.0 xc = XC(XCNull()) elif name == 'PBE0': assert hybrid is None and xc is None hybrid = 0.25 xc = XC('HYB_GGA_XC_PBEH') elif name == 'B3LYP': assert hybrid is None and xc is None hybrid = 0.2 xc = XC('HYB_GGA_XC_B3LYP') if isinstance(xc, str): xc = XC(xc) self.hybrid = hybrid self.xc = xc self.type = xc.type self.alpha = alpha self.qsym = qsym self.skip_gamma = skip_gamma self.gygi = gygi self.acdf = acdf self.exx = None self.ecut = ecut if txt is None: if rank == 0: #self.txt = devnull self.txt = sys.stdout else: sys.stdout = devnull self.txt = devnull else: assert type(txt) is str from ase.parallel import paropen self.txt = paropen(txt, 'w') XCFunctional.__init__(self, name)
def calculate(self): """Generate necessary files in working directory and run QuantumEspresso The method first writes a [name].in file. Then it """ # if self.status == 'running': # raise LammpsRunning('Running', os.getcwd()) # if (self.status == 'done' # and self.converged == False): # raise LammpsNotConverged('Not Converged', os.getcwd()) # if self.calculation_required(force=force): # self.write_input() script = '''#!/bin/bash #$ -S /bin/bash #$ -cwd #$ -V #$ -N test #$ -P cr_liion_materials #$ -l excl=true #$ -l h_rt=10:00:00 #$ -q regular #$ -pe openmpi 10 MPI_CMD="mpirun" LAMMPS=$LAMMPS_COMMAND $MPI_CMD $LAMMPS < input.lmp''' f = paropen('qscript', 'w') f.write(script) f.close() p = Popen(['qsub qscript'],shell=True,stdout=PIPE,stderr=PIPE) out, err = p.communicate() if out=='' or err !='': raise Exception('something went wrong in qsub:\n\n{0}'.format(err)) f = paropen('jobid','w') f.write(out) f.close() self.status = 'running' return
def calculate(self): """Generate necessary files in working directory and run QuantumEspresso The method first writes a [name].in file. Then it """ # if self.status == 'running': # raise LammpsRunning('Running', os.getcwd()) # if (self.status == 'done' # and self.converged == False): # raise LammpsNotConverged('Not Converged', os.getcwd()) # if self.calculation_required(force=force): # self.write_input() script = """#!/bin/bash #$ -S /bin/bash #$ -cwd #$ -V #$ -N pylammps #$ -P cr_liion_materials #$ -l excl=true #$ -l h_rt=72:00:00 #$ -q all.q #$ -pe intel_mpi 24 MPI_CMD="mpirun" LAMMPS=$LAMMPS_COMMAND $MPI_CMD $LAMMPS < input.lmp""" f = paropen("qscript", "w") f.write(script) f.close() p = Popen(["qsub qscript"], shell=True, stdout=PIPE, stderr=PIPE) out, err = p.communicate() if out == "" or err != "": raise Exception("something went wrong in qsub:\n\n{0}".format(err)) f = paropen("jobid", "w") f.write(out) f.close() self.status = "running" return
def output_init(self): if self.txtname is None: if rank == 0: self.txt = sys.stdout else: sys.stdout = devnull self.txt = devnull else: assert type(self.txtname) is str from ase.parallel import paropen self.txt = paropen(self.txtname,'w')
def write_xyz(fileobj, images): if isinstance(fileobj, str): fileobj = paropen(fileobj, 'w') if not isinstance(images, (list, tuple)): images = [images] symbols = images[0].get_chemical_symbols() natoms = len(symbols) for atoms in images: fileobj.write('%d\n\n' % natoms) for s, (x, y, z) in zip(symbols, atoms.get_positions()): fileobj.write('%-2s %22.15f %22.15f %22.15f\n' % (s, x, y, z))
def _write_metadata(self, metadata): """Write the metadata file of the bundle. Modifies the medadata dictionary! """ # Add standard fields that must always be present. assert self.state == 'write' or self.state == 'prewrite' metadata['format'] = 'BundleTrajectory' metadata['version'] = self.version metadata['subtype'] = self.subtype metadata['backend'] = self.backend_name f = paropen(os.path.join(self.filename, "metadata"), "w") pickle.dump(metadata, f, -1) f.close()
def _write_metadata(self, metadata): """Write the metadata file of the bundle. Modifies the medadata dictionary! """ # Add standard fields that must always be present. assert self.state == "write" or self.state == "prewrite" metadata["format"] = "BundleTrajectory" metadata["version"] = self.version metadata["subtype"] = self.subtype metadata["backend"] = self.backend_name f = paropen(os.path.join(self.filename, "metadata"), "w") pickle.dump(metadata, f, -1) f.close()
def write_viewmol(self, filename, mode='w'): """Write yourself in viewmol style.""" f = paropen(filename, mode) if mode == 'w': print >> f, ' $coord', 1. / Angstrom self.write_viewmol_positions(f, self[0]) print >> f, ' $grad' else: raise NotImplementedError('append') for i, atoms in enumerate(self): self.write_viewmol_atoms(f, atoms, i) f.close()
from __future__ import print_function from ase.parallel import paropen from ase.units import Hartree from gpaw.xc.rpa import RPACorrelation f = paropen('con_freq.dat', 'w') for N in [4, 6, 8, 12, 16, 24, 32]: rpa = RPACorrelation('N2.gpw', txt='rpa_N2_frequencies.txt', nfrequencies=N) E = rpa.calculate(ecut=[50]) print(N, E[0], file=f) if N == 16: f16 = paropen('frequency_gauss16.dat', 'w') for w, e in zip(rpa.omega_w, rpa.E_w): print(w * Hartree, e, file=f16) f16.close() f.close()
def read_lammps_data( fileobj, Z_of_type=None, style="atomic", ## YJ sort_by_id=False, units="metal"): """Method which reads a LAMMPS data file. sort_by_id: Order the particles according to their id. Might be faster to switch it off. Units are set by default to the style=metal setting in LAMMPS. """ if isinstance(fileobj, str): fd = paropen(fileobj) else: fd = fileobj # load everything into memory lines = fd.readlines() # begin read_lammps_data comment = None N = None # N_types = None xlo = None xhi = None ylo = None yhi = None zlo = None zhi = None xy = None xz = None yz = None pos_in = {} travel_in = {} mol_id_in = {} charge_in = {} mass_in = {} vel_in = {} bonds_in = [] angles_in = [] dihedrals_in = [] sections = [ "Atoms", "Velocities", "Masses", "Charges", "Ellipsoids", "Lines", "Triangles", "Bodies", "Bonds", "Angles", "Dihedrals", "Impropers", "Impropers Pair Coeffs", "PairIJ Coeffs", "Pair Coeffs", "Bond Coeffs", "Angle Coeffs", "Dihedral Coeffs", "Improper Coeffs", "BondBond Coeffs", "BondAngle Coeffs", "MiddleBondTorsion Coeffs", "EndBondTorsion Coeffs", "AngleTorsion Coeffs", "AngleAngleTorsion Coeffs", "BondBond13 Coeffs", "AngleAngle Coeffs", ] header_fields = [ "atoms", "bonds", "angles", "dihedrals", "impropers", "atom types", "bond types", "angle types", "dihedral types", "improper types", "extra bond per atom", "extra angle per atom", "extra dihedral per atom", "extra improper per atom", "extra special per atom", "ellipsoids", "lines", "triangles", "bodies", "xlo xhi", "ylo yhi", "zlo zhi", "xy xz yz", ] sections_re = "(" + "|".join(sections).replace(" ", "\\s+") + ")" header_fields_re = "(" + "|".join(header_fields).replace(" ", "\\s+") + ")" section = None header = True for line in lines: if comment is None: comment = line.rstrip() else: line = re.sub("#.*", "", line).rstrip().lstrip() if re.match("^\\s*$", line): # skip blank lines continue # check for known section names m = re.match(sections_re, line) if m is not None: section = m.group(0).rstrip().lstrip() header = False continue if header: field = None val = None # m = re.match(header_fields_re+"\s+=\s*(.*)", line) # if m is not None: # got a header line # field=m.group(1).lstrip().rstrip() # val=m.group(2).lstrip().rstrip() # else: # try other format # m = re.match("(.*)\s+"+header_fields_re, line) # if m is not None: # field = m.group(2).lstrip().rstrip() # val = m.group(1).lstrip().rstrip() m = re.match("(.*)\\s+" + header_fields_re, line) if m is not None: field = m.group(2).lstrip().rstrip() val = m.group(1).lstrip().rstrip() if field is not None and val is not None: if field == "atoms": N = int(val) # elif field == "atom types": # N_types = int(val) elif field == "xlo xhi": (xlo, xhi) = [float(x) for x in val.split()] elif field == "ylo yhi": (ylo, yhi) = [float(x) for x in val.split()] elif field == "zlo zhi": (zlo, zhi) = [float(x) for x in val.split()] elif field == "xy xz yz": (xy, xz, yz) = [float(x) for x in val.split()] if section is not None: fields = line.split() if section == "Atoms": # id * id = int(fields[0]) if style == "full" and (len(fields) == 7 or len(fields) == 10): # id mol-id type q x y z [tx ty tz] pos_in[id] = ( int(fields[2]), float(fields[4]), float(fields[5]), float(fields[6]), ) mol_id_in[id] = int(fields[1]) charge_in[id] = float(fields[3]) if len(fields) == 10: travel_in[id] = ( int(fields[7]), int(fields[8]), int(fields[9]), ) elif style == "atomic" and (len(fields) == 5 or len(fields) == 8): # id type x y z [tx ty tz] pos_in[id] = ( int(fields[1]), float(fields[2]), float(fields[3]), float(fields[4]), ) if len(fields) == 8: travel_in[id] = ( int(fields[5]), int(fields[6]), int(fields[7]), ) elif (style in ("angle", "bond", "molecular")) and (len(fields) == 6 or len(fields) == 9): # id mol-id type x y z [tx ty tz] pos_in[id] = ( int(fields[2]), float(fields[3]), float(fields[4]), float(fields[5]), ) mol_id_in[id] = int(fields[1]) if len(fields) == 9: travel_in[id] = ( int(fields[6]), int(fields[7]), int(fields[8]), ) elif (style == "charge" and (len(fields) == 6 or len(fields) == 9)): # id type q x y z [tx ty tz] pos_in[id] = ( int(fields[1]), float(fields[3]), float(fields[4]), float(fields[5]), ) charge_in[id] = float(fields[2]) if len(fields) == 9: travel_in[id] = ( int(fields[6]), int(fields[7]), int(fields[8]), ) else: raise RuntimeError("Style '{}' not supported or invalid " "number of fields {}" "".format(style, len(fields))) elif section == "Velocities": # id vx vy vz vel_in[int(fields[0])] = ( float(fields[1]), float(fields[2]), float(fields[3]), ) elif section == "Masses": mass_in[int(fields[0])] = float(fields[1]) elif section == "Bonds": # id type atom1 atom2 bonds_in.append( (int(fields[1]), int(fields[2]), int(fields[3]))) elif section == "Angles": # id type atom1 atom2 atom3 angles_in.append(( int(fields[1]), int(fields[2]), int(fields[3]), int(fields[4]), )) elif section == "Dihedrals": # id type atom1 atom2 atom3 atom4 dihedrals_in.append(( int(fields[1]), int(fields[2]), int(fields[3]), int(fields[4]), int(fields[5]), )) # set cell cell = np.zeros((3, 3)) cell[0, 0] = xhi - xlo cell[1, 1] = yhi - ylo cell[2, 2] = zhi - zlo if xy is not None: cell[1, 0] = xy if xz is not None: cell[2, 0] = xz if yz is not None: cell[2, 1] = yz # initialize arrays for per-atom quantities positions = np.zeros((N, 3)) numbers = np.zeros((N), int) ids = np.zeros((N), int) types = np.zeros((N), int) if len(vel_in) > 0: velocities = np.zeros((N, 3)) else: velocities = None if len(mass_in) > 0: masses = np.zeros((N)) else: masses = None if len(mol_id_in) > 0: mol_id = np.zeros((N), int) else: mol_id = None if len(charge_in) > 0: charge = np.zeros((N), float) else: charge = None if len(travel_in) > 0: travel = np.zeros((N, 3), int) else: travel = None if len(bonds_in) > 0: bonds = [""] * N else: bonds = None if len(angles_in) > 0: angles = [""] * N else: angles = None if len(dihedrals_in) > 0: dihedrals = [""] * N else: dihedrals = None ind_of_id = {} # copy per-atom quantities from read-in values for (i, id) in enumerate(pos_in.keys()): # by id ind_of_id[id] = i if sort_by_id: ind = id - 1 else: ind = i type = pos_in[id][0] positions[ind, :] = [pos_in[id][1], pos_in[id][2], pos_in[id][3]] if velocities is not None: velocities[ind, :] = [vel_in[id][0], vel_in[id][1], vel_in[id][2]] if travel is not None: travel[ind] = travel_in[id] if mol_id is not None: mol_id[ind] = mol_id_in[id] if charge is not None: charge[ind] = charge_in[id] ids[ind] = id # by type types[ind] = type if Z_of_type is None: numbers[ind] = type else: numbers[ind] = Z_of_type[type] if masses is not None: masses[ind] = mass_in[type] # convert units positions = convert(positions, "distance", units, "ASE") cell = convert(cell, "distance", units, "ASE") if masses is not None: masses = convert(masses, "mass", units, "ASE") if velocities is not None: velocities = convert(velocities, "velocity", units, "ASE") # create ase.Atoms at = Atoms( positions=positions, numbers=numbers, masses=masses, cell=cell, pbc=[True, True, True], ) # set velocities (can't do it via constructor) if velocities is not None: at.set_velocities(velocities) at.arrays["id"] = ids at.arrays["type"] = types if travel is not None: at.arrays["travel"] = travel if mol_id is not None: at.arrays["mol-id"] = mol_id if charge is not None: at.arrays["initial_charges"] = charge at.arrays["mmcharges"] = charge.copy() if bonds is not None: for (type, a1, a2) in bonds_in: i_a1 = ind_of_id[a1] i_a2 = ind_of_id[a2] if len(bonds[i_a1]) > 0: bonds[i_a1] += "," bonds[i_a1] += "%d(%d)" % (i_a2, type) for i in range(len(bonds)): if len(bonds[i]) == 0: bonds[i] = "_" at.arrays["bonds"] = np.array(bonds) if angles is not None: for (type, a1, a2, a3) in angles_in: i_a1 = ind_of_id[a1] i_a2 = ind_of_id[a2] i_a3 = ind_of_id[a3] if len(angles[i_a2]) > 0: angles[i_a2] += "," angles[i_a2] += "%d-%d(%d)" % (i_a1, i_a3, type) for i in range(len(angles)): if len(angles[i]) == 0: angles[i] = "_" at.arrays["angles"] = np.array(angles) if dihedrals is not None: for (type, a1, a2, a3, a4) in dihedrals_in: i_a1 = ind_of_id[a1] i_a2 = ind_of_id[a2] i_a3 = ind_of_id[a3] i_a4 = ind_of_id[a4] if len(dihedrals[i_a1]) > 0: dihedrals[i_a1] += "," dihedrals[i_a1] += "%d-%d-%d(%d)" % (i_a2, i_a3, i_a4, type) for i in range(len(dihedrals)): if len(dihedrals[i]) == 0: dihedrals[i] = "_" at.arrays["dihedrals"] = np.array(dihedrals) at.info["comment"] = comment return at
# Creates: C_GW.png import pickle import numpy as np from ase.parallel import paropen import matplotlib.pyplot as plt plt.figure(figsize=(6.5, 4.5)) ecuts = np.array([100, 200, 300, 400]) color = ['ro-', 'bo-', 'go-', 'ko-', 'co-', 'mo-', 'yo-'] direct_gap = np.zeros(4) for j, k in enumerate([6, 8, 10, 12]): for i, ecut in enumerate([100, 200, 300, 400]): try: fil = pickle.load(paropen('C-g0w0_k%s_ecut%s_results.pckl' % (k, ecut), 'rb')) direct_gap[i] = fil['qp'][0, 0, 1] - fil['qp'][0, 0, 0] except: direct_gap[i] = np.nan plt.plot(ecuts, direct_gap, color[j], label='(%sx%sx%s) k-points' % (k, k, k)) plt.xlabel('Cutoff energy (eV)') plt.ylabel('Direct band gap (eV)') plt.title('non-selfconsistent G0W0@LDA') plt.legend(loc='lower right') plt.savefig('C_GW.png') plt.show()
def write(self, filename): """Write to json file.""" with paropen(filename, 'w') as f: f.write(encode(self))
def OptimizeLatticeScript(): import cPickle, json, os, ase, shutil import scipy.optimize as opt import ase.parallel as asepar global energies, lparams ####################### print "Initializing..." #---------------------- params, initatoms = initialize( ) # Remove old .out/.err files, load from fw_spec, and write 'init.traj' shutil.copy( 'init.traj', 'out.traj' ) # Initial guess for atomic coordinates inside getBulkEnergy reads from 'out.traj' energies, lparams = [], [] # Initialize variables if rank() == 0: for d in [ 'qn.traj', 'qn.log', 'lattice_opt.log', 'energy_forces.pckl' ]: # Remove partially completed calculations that may still be held over from failed job if os.path.exists(d): os.remove(d) print 'Removed existing file ', d ################################ print "Loading initial guess..." #------------------------------- try: with asepar.paropen('lastguess.json', 'r') as f: iGuess = json.loads(f.read()) print '\tread lastguess from lastguess.json: ', iGuess except: iGuess = getInitGuess(params['structure'], initatoms.get_cell()) print '\tgenerating initial guess from getInitGuess(): ', iGuess ######################################## print "Optimizing cell and positions..." #--------------------------------------- optimizedLatticeParams = opt.fmin(getBulkEnergy, iGuess, args=(params, ), ftol=1, xtol=params['xtol']) print 'Optimized lattice params: ', optimizedLatticeParams ################################ print "Storing Results..." #------------------------------- optAtoms = ase.io.read('out.traj') #read optimized cell and positions with asepar.paropen('energy_forces.pckl') as f: eng, forces = cPickle.loads(str(f.read())) resultDict = mergeDicts([ params, trajDetails(optAtoms), { 'raw_energy': eng, 'forces_pckl': cPickle.dumps(forces), 'latticeopt_pckl': cPickle.dumps(zip(energies, lparams)) } ]) with open('result.json', 'w') as f: f.write(json.dumps(resultDict)) if rank() == 0: log(params, optAtoms) #with open('result.json', 'r') as outfile: json.load(outfile) #WHY DOES THIS CRASH return 0
calc.diagonalize_full_hamiltonian(nbands=70) # diagonalize Hamiltonian calc.write('si_large.gpw', 'all') # write wavefunctions # Getting absorption spectrum df = DielectricFunction(calc='si_large.gpw', eta=0.05, domega0=0.02, ecut=150) df.get_dielectric_function(filename='si_abs.csv') # Getting macroscopic constant df = DielectricFunction( calc='si_large.gpw', frequencies=[0.0], hilbert=False, eta=0.0001, ecut=150, ) epsNLF, epsLF = df.get_macroscopic_dielectric_constant() # Make table epsrefNLF = 14.08 # from [1] in top epsrefLF = 12.66 # from [1] in top with paropen('mac_eps.csv', 'w') as f: print(' , Without LFE, With LFE', file=f) print('%s, %.6f, %.6f' % ('GPAW-linear response', epsNLF, epsLF), file=f) print('%s, %.6f, %.6f' % ('[1]', epsrefNLF, epsrefLF), file=f) print('%s, %.6f, %.6f' % ('Exp.', 11.90, 11.90), file=f) if world.rank == 0: Path('si_large.gpw').unlink()
def write_cfg(f, a): """Write atomic configuration to a CFG-file (native AtomEye format). See: http://mt.seas.upenn.edu/Archive/Graphics/A/ """ if isinstance(f, str): f = paropen(f, 'w') if isinstance(a, list): if len(a) == 1: a = a[0] else: raise RuntimeError('Cannot write sequence to single .cfg file.') f.write('Number of particles = %i\n' % len(a)) f.write('A = 1.0 Angstrom\n') cell = a.get_cell(complete=True) for i in range(3): for j in range(3): f.write('H0(%1.1i,%1.1i) = %f A\n' % (i + 1, j + 1, cell[i, j])) entry_count = 3 for x in a.arrays.keys(): if x not in cfg_default_fields: if len(a.get_array(x).shape) == 1: entry_count += 1 else: entry_count += a.get_array(x).shape[1] vels = a.get_velocities() if isinstance(vels, np.ndarray): entry_count += 3 else: f.write('.NO_VELOCITY.\n') f.write('entry_count = %i\n' % entry_count) i = 0 for name, aux in a.arrays.items(): if name not in cfg_default_fields: if len(aux.shape) == 1: f.write('auxiliary[%i] = %s [a.u.]\n' % (i, name)) i += 1 else: if aux.shape[1] == 3: for j in range(3): f.write('auxiliary[%i] = %s_%s [a.u.]\n' % (i, name, chr(ord('x') + j))) i += 1 else: for j in range(aux.shape[1]): f.write('auxiliary[%i] = %s_%1.1i [a.u.]\n' % (i, name, j)) i += 1 # Distinct elements spos = a.get_scaled_positions() for i in a: el = i.symbol f.write('%f\n' % ase.data.atomic_masses[chemical_symbols.index(el)]) f.write('%s\n' % el) x, y, z = spos[i.index, :] s = '%e %e %e ' % (x, y, z) if isinstance(vels, np.ndarray): vx, vy, vz = vels[i.index, :] s = s + ' %e %e %e ' % (vx, vy, vz) for name, aux in a.arrays.items(): if name not in cfg_default_fields: if len(aux.shape) == 1: s += ' %e' % aux[i.index] else: s += (aux.shape[1] * ' %e') % tuple(aux[i.index].tolist()) f.write('%s\n' % s)
def read_atoms(fn, cycfn=None, pos_only=False, conv=1.0): """ Read atom information from an atoms.dat file (i.e., tblmd, MDCORE input file) """ f = paropen(fn, "r") l = f.readline().lstrip() while len(l) > 0 and ( l[0] == '#' or l[0] == '<' ): l = f.readline().lstrip() n_atoms = int(l) l = f.readline().lstrip() while len(l) > 0 and ( l[0] == '#' or l[0] == '<' ): l = f.readline().lstrip() l = f.readline().lstrip() while len(l) > 0 and ( l[0] == '#' or l[0] == '<' ): l = f.readline().lstrip() # # Read positions # forces = np.zeros( [ n_atoms, 3 ] ) groups = np.zeros( [ n_atoms ] ) gamma = np.zeros( [ n_atoms ] ) T = np.zeros( [ n_atoms ] ) ats = [ ] for i in range(n_atoms): s = l.split() # type x y z sym = None try: Z = int(s[0]) sym = ase.data.chemical_symbols[Z] except: sym = s[0] a = ase.Atom(sym, ( float(s[2])*conv, float(s[3])*conv, float(s[4])*conv ) ) groups[i] = int(s[5]) gamma[i] = float(s[6]) T[i] = float(s[7]) ats += [ a ] l = f.readline() this = ase.Atoms(ats, pbc=True) if not pos_only: while l and l == "": l = f.readline().strip() while l: key = l.strip(" <-#\r\n") if key.upper() == "VELOCITIES": for i in range(n_atoms): s = f.readline().split() m = this[i].mass if m is None: m = ase.data.atomic_masses[ase.data.chemical_symbols.index(this[i].symbol)] this[i].momentum = ( m*float(s[0]), m*float(s[1]), m*float(s[2]) ) l = None elif key.upper() == "FORCES": for i in range(n_atoms): s = f.readline().split() forces[i] = np.array( [ float(s[0]), float(s[1]), float(s[2]) ] ) l = None elif key.upper() == "CHARGES": for i in this: l = f.readline() if l and len(l.split()) == 1: i.charge = float(l) l = None elif key.upper() == "CELL" or key.upper().split()[0:2] == ("BOX", "VECTORS" ): l1 = f.readline() l2 = f.readline() l3 = f.readline() this.set_cell( [ [float(x) for x in l1.split()], [float(x) for x in l2.split()], [float(x) for x in l3.split()] ] ) l = None else: aux = [ ] l = f.readline().strip() while l and l[0] not in [ '<', '#' ]: s = l.split() aux += [ [float(x) for x in s] ] l = f.readline().strip() if len(aux) == n_atoms: this.set_array(key, np.asarray(aux)) else: print("Warning: Encountered field '%s' which does not seem to be per-atom data." % key) if l is None: l = f.readline().strip() while l and l == "": l = f.readline().strip() f.close() this.set_array("forces", forces) this.set_array("groups", groups) this.set_array("gamma", gamma) this.set_array("T", T) if cycfn: read_cyc(this, cycfn, conv=conv) return this
def write_atoms(fn, this, cycfn=None, conv=1.0, symbols=True): """ Write atom information to an atoms.dat file (i.e., tblmd, MDCORE input file) """ f = paropen(fn, "w") f.write("<--- Number of atoms\n") f.write("%i\n" % len(this)) f.write("<--- Number of occupied orbitals\n") f.write("%f\n" % 0.0) f.write("<--- Atom positions\n") groups = None if this.has("groups"): groups = this.get_array("groups") gamma = None if this.has("gamma"): gamma = this.get_array("gamma") T = None if this.has("T"): T = this.get_array("T") for idx, i in enumerate(this): group_str = "1" if groups is not None: group_str = "%i" % groups[idx] gamma_str = "0.0" if gamma is not None: gamma_str = "%20.10e" % gamma[idx] T_str = "0.0" if T is not None: T_str = "%20.10e" % T[idx] sym = i.symbol r = i.position if symbols: f.write("%s %f %20.10e %20.10e %20.10e %s %s %s\n" % (sym, ase.data.atomic_masses[ase.data.chemical_symbols.index(sym)], r[0]*conv, r[1]*conv, r[2]*conv, group_str, gamma_str, T_str)) else: f.write("%i %f %20.10e %20.10e %20.10e %s %s %s\n" % (ase.data.chemical_symbols.index(sym), ase.data.atomic_masses[ase.data.chemical_symbols.index(sym)], r[0]*conv, r[1]*conv, r[2]*conv, group_str, gamma_str, T_str)) f.write("<--- Velocities\n") for i in this: m = i.mass if m is None: m = ase.data.atomic_masses[ase.data.chemical_symbols.index(i.symbol)] if i.momentum is not None: v = i.momentum/m else: v = [ 0.0, 0.0, 0.0 ] f.write("%20.10e %20.10e %20.10e\n" % ( v[0], v[1], v[2] )) f.write("<--- Forces\n") for i in this: f.write("0 0 0\n") f.write("<--- cell\n") cell = this.get_cell() f.write("%f %f %f\n" % tuple(cell[0, :])) f.write("%f %f %f\n" % tuple(cell[1, :])) f.write("%f %f %f\n" % tuple(cell[2, :])) for name, aux in this.arrays.items(): if not name in atoms_default_fields: f.write("<--- %s\n" % name) if aux.dtype == int: if len(aux.shape) == 1: for i in this: f.write(" %i\n" % aux[i.index]) else: for i in this: f.write(( aux.shape[1]*" %i" + "\n" ) % tuple(aux[i.index].tolist())) else: if len(aux.shape) == 1: for i in this: f.write(" %e\n" % aux[i.index]) else: for i in this: f.write(( aux.shape[1]*" %e" + "\n" ) % tuple(aux[i.index].tolist())) f.close() if cycfn: write_cyc(cycfn, this, conv=conv)
#xcname = '1.0_LDA_K_TF+1.0_LDA_X+1.0_LDA_C_PW' #xcname='1.0_LDA_K_TF+1.0_LDA_K_LP+1.0_LDA_X+1.0_LDA_C_PW' #xcname='1.0_LDA_K_TF+1.0_LDA_K_LP+-1.0_LDA_K_LP+1.0_LDA_X+1.0_LDA_C_PW' xcname = '1.0_GGA_K_TFVW+-1.0_GGA_K_VW+1.0_GGA_X_PBE+1.0_GGA_C_PBE' # Fraction of Tw lambda_coeff = 1.0 name = 'lambda_{0}'.format(lambda_coeff) filename = 'atoms_' + name + '.dat' f = paropen(filename, 'w') elements = ['N'] for symbol in elements: mixer = Mixer() eigensolver = CG(tw_coeff=lambda_coeff) poissonsolver = PoissonSolver() molecule = Atoms(symbol, positions=[(c, c, c)], cell=(a, a, a)) calc = GPAW(h=h, xc=xcname, maxiter=240, eigensolver=eigensolver,
def write_xsf(fileobj, images, data=None): if isinstance(fileobj, str): fileobj = paropen(fileobj, 'w') if hasattr(images, 'get_positions'): images = [images] is_anim = len(images) > 1 if is_anim: fileobj.write('ANIMSTEPS %d\n' % len(images)) numbers = images[0].get_atomic_numbers() pbc = images[0].get_pbc() npbc = sum(pbc) if pbc[2]: fileobj.write('CRYSTAL\n') assert npbc == 3 elif pbc[1]: fileobj.write('SLAB\n') assert npbc == 2 elif pbc[0]: fileobj.write('POLYMER\n') assert npbc == 1 else: # (Header written as part of image loop) assert npbc == 0 cell_variable = False for image in images[1:]: if np.abs(images[0].cell - image.cell).max() > 1e-14: cell_variable = True break for n, atoms in enumerate(images): anim_token = ' %d' % (n + 1) if is_anim else '' if pbc.any(): write_cell = (n == 0 or cell_variable) if write_cell: if cell_variable: fileobj.write('PRIMVEC%s\n' % anim_token) else: fileobj.write('PRIMVEC\n') cell = atoms.get_cell() for i in range(3): fileobj.write(' %.14f %.14f %.14f\n' % tuple(cell[i])) fileobj.write('PRIMCOORD%s\n' % anim_token) else: fileobj.write('ATOMS%s\n' % anim_token) # Get the forces if it's not too expensive: calc = atoms.get_calculator() if (calc is not None and (hasattr(calc, 'calculation_required') and not calc.calculation_required(atoms, ['forces']))): forces = atoms.get_forces() / Hartree else: forces = None pos = atoms.get_positions() if pbc.any(): fileobj.write(' %d 1\n' % len(pos)) for a in range(len(pos)): fileobj.write(' %2d' % numbers[a]) fileobj.write(' %20.14f %20.14f %20.14f' % tuple(pos[a])) if forces is None: fileobj.write('\n') else: fileobj.write(' %20.14f %20.14f %20.14f\n' % tuple(forces[a])) if data is None: return fileobj.write('BEGIN_BLOCK_DATAGRID_3D\n') fileobj.write(' data\n') fileobj.write(' BEGIN_DATAGRID_3Dgrid#1\n') data = np.asarray(data) if data.dtype == complex: data = np.abs(data) shape = data.shape fileobj.write(' %d %d %d\n' % shape) cell = atoms.get_cell() origin = np.zeros(3) for i in range(3): if not pbc[i]: origin += cell[i] / shape[i] fileobj.write(' %f %f %f\n' % tuple(origin)) for i in range(3): # XXXX is this not just supposed to be the cell? # What's with the strange division? # This disagrees with the output of Octopus. Investigate fileobj.write(' %f %f %f\n' % tuple(cell[i] * (shape[i] + 1) / shape[i])) for k in range(shape[2]): for j in range(shape[1]): fileobj.write(' ') fileobj.write(' '.join(['%f' % d for d in data[:, j, k]])) fileobj.write('\n') fileobj.write('\n') fileobj.write(' END_DATAGRID_3D\n') fileobj.write('END_BLOCK_DATAGRID_3D\n')
pos = slab.get_positions() add_adsorbate(slab, 'C', d, position=(pos[3,0], pos[3,1])) add_adsorbate(slab, 'C', d, position=(cell[0,0]/3 + cell[1,0]/3, cell[0,1]/3 + cell[1,1]/3)) #view(slab) calc = GPAW(xc='PBE', eigensolver='cg', mode=PW(600), kpts=kpts, occupations=FermiDirac(width=0.01), mixer=MixerSum(beta=0.1, nmaxold=5, weight=50.0), convergence={'density': 1.e-6}, maxiter=300, parallel={'domain': 1, 'band': 1}, txt='gs_%s.txt' % d) slab.set_calculator(calc) E = slab.get_potential_energy() exx = EXX(calc, txt='exx_%s.txt' % d) exx.calculate() E_hf = exx.get_total_energy() calc.diagonalize_full_hamiltonian() calc.write('gs_%s.gpw' % d, mode='all') f = paropen('hf_acdf.dat', 'a') print(d, E, E_hf, file=f) f.close() del slab[-2:]
def write_gen(fileobj, images): """Write structure in GEN format (refer to DFTB+ manual). Multiple snapshots are not allowed. """ if isinstance(fileobj, str): fileobj = paropen(fileobj, 'w') if not isinstance(images, (list, tuple)): images = [images] # Images is kept in a list but a size > 0 is not allowed # as GEN format doesn't support multiple snapshots. # Images is used as a list for consistency with the other # output modules if len(images) != 1: raise ValueError('images contains more than one structure\n' + 'GEN format supports only single snapshot output') symbols = images[0].get_chemical_symbols() # Define a dictionary with symbols-id symboldict = dict() for sym in symbols: if not (sym in symboldict): symboldict[sym] = len(symboldict) + 1 # An ordered symbol list is needed as ordered dictionary # is just available in python 2.7 orderedsymbols = list(['null'] * len(symboldict.keys())) for sym in symboldict.keys(): orderedsymbols[symboldict[sym] - 1] = sym # Check whether the structure is periodic # GEN cannot describe periodicity in one or two direction, # a periodic structure is considered periodic in all the # directions. If your structure is not periodical in all # the directions, be sure you have set big periodicity # vectors in the non-periodic directions if images[0].pbc.any(): pb_flag = 'S' else: pb_flag = 'C' natoms = len(symbols) ind = 0 for atoms in images: fileobj.write('%d %-5s\n' % (natoms, pb_flag)) for s in orderedsymbols: fileobj.write('%-5s' % s) fileobj.write('\n') for sym, (x, y, z) in zip(symbols, atoms.get_positions()): ind += 1 symbolid = symboldict[sym] fileobj.write('%-6d %d %22.15f %22.15f %22.15f\n' % (ind, symbolid, x, y, z)) if images[0].pbc.any(): fileobj.write('%22.15f %22.15f %22.15f \n' % (0.0, 0.0, 0.0)) fileobj.write('%22.15f %22.15f %22.15f \n' % (images[0].get_cell()[0][0], images[0].get_cell()[0][1], images[0].get_cell()[0][2])) fileobj.write('%22.15f %22.15f %22.15f \n' % (images[0].get_cell()[1][0], images[0].get_cell()[1][1], images[0].get_cell()[1][2])) fileobj.write('%22.15f %22.15f %22.15f \n' % (images[0].get_cell()[2][0], images[0].get_cell()[2][1], images[0].get_cell()[2][2]))
def write_xyz(fileobj, images, comment='', columns=None, write_info=True, write_results=True, plain=False, vec_cell=False, append=False): """ Write output in extended XYZ format Optionally, specify which columns (arrays) to include in output, whether to write the contents of the `atoms.info` dict to the XYZ comment line (default is True), the results of any calculator attached to this Atoms. The `plain` argument can be used to write a simple XYZ file with no additional information. `vec_cell` can be used to write the cell vectors as additional pseudo-atoms. If `append` is set to True, the file is for append (mode `a`), otherwise it is overwritten (mode `w`). See documentation for :func:`read_xyz()` for further details of the extended XYZ file format. """ if isinstance(fileobj, str): mode = 'w' if append: mode = 'a' fileobj = paropen(fileobj, mode) if hasattr(images, 'get_positions'): images = [images] for atoms in images: natoms = len(atoms) if columns is None: fr_cols = None else: fr_cols = columns[:] if fr_cols is None: fr_cols = (['symbols', 'positions'] + [ key for key in atoms.arrays.keys() if key not in ['symbols', 'positions', 'numbers', 'species', 'pos'] ]) if vec_cell: plain = True if plain: fr_cols = ['symbols', 'positions'] write_info = False write_results = False per_frame_results = {} per_atom_results = {} if write_results: calculator = atoms.calc if (calculator is not None and isinstance(calculator, Calculator)): for key in all_properties: value = calculator.results.get(key, None) if value is None: # skip missing calculator results continue if (key in per_atom_properties and len(value.shape) >= 1 and value.shape[0] == len(atoms)): # per-atom quantities (forces, energies, stresses) per_atom_results[key] = value elif key in per_config_properties: # per-frame quantities (energy, stress) # special case for stress, which should be converted # to 3x3 matrices before writing if key == 'stress': xx, yy, zz, yz, xz, xy = value value = np.array([(xx, xy, xz), (xy, yy, yz), (xz, yz, zz)]) per_frame_results[key] = value # Move symbols and positions to first two properties if 'symbols' in fr_cols: i = fr_cols.index('symbols') fr_cols[0], fr_cols[i] = fr_cols[i], fr_cols[0] if 'positions' in fr_cols: i = fr_cols.index('positions') fr_cols[1], fr_cols[i] = fr_cols[i], fr_cols[1] # Check first column "looks like" atomic symbols if fr_cols[0] in atoms.arrays: symbols = atoms.arrays[fr_cols[0]] else: symbols = atoms.get_chemical_symbols() if natoms > 0 and not isinstance(symbols[0], str): raise ValueError('First column must be symbols-like') # Check second column "looks like" atomic positions pos = atoms.arrays[fr_cols[1]] if pos.shape != (natoms, 3) or pos.dtype.kind != 'f': raise ValueError('Second column must be position-like') # if vec_cell add cell information as pseudo-atoms if vec_cell: pbc = list(atoms.get_pbc()) cell = atoms.get_cell() if True in pbc: nPBC = 0 for i, b in enumerate(pbc): if b: nPBC += 1 symbols.append('VEC' + str(nPBC)) pos = np.vstack((pos, cell[i])) # add to natoms natoms += nPBC if pos.shape != (natoms, 3) or pos.dtype.kind != 'f': raise ValueError( 'Pseudo Atoms containing cell have bad coords') # Move mask if 'move_mask' in fr_cols: cnstr = images[0]._get_constraints() if len(cnstr) > 0: c0 = cnstr[0] if isinstance(c0, FixAtoms): cnstr = np.ones((natoms, ), dtype=np.bool) for idx in c0.index: cnstr[idx] = False elif isinstance(c0, FixCartesian): for i in range(len(cnstr)): idx = cnstr[i].a cnstr[idx] = cnstr[i].mask cnstr = np.asarray(cnstr) else: fr_cols.remove('move_mask') # Collect data to be written out arrays = {} for column in fr_cols: if column == 'positions': arrays[column] = pos elif column in atoms.arrays: arrays[column] = atoms.arrays[column] elif column == 'symbols': arrays[column] = np.array(symbols) elif column == 'move_mask': arrays[column] = cnstr else: raise ValueError('Missing array "%s"' % column) if write_results: for key in per_atom_results: if key not in fr_cols: fr_cols += [key] else: warnings.warn( 'write_xyz() overwriting array "{0}" present ' 'in atoms.arrays with stored results ' 'from calculator'.format(key)) arrays.update(per_atom_results) comm, ncols, dtype, fmt = output_column_format(atoms, fr_cols, arrays, write_info, per_frame_results) if plain or comment != '': # override key/value pairs with user-speficied comment string comm = comment # Pack fr_cols into record array data = np.zeros(natoms, dtype) for column, ncol in zip(fr_cols, ncols): value = arrays[column] if ncol == 1: data[column] = np.squeeze(value) else: for c in range(ncol): data[column + str(c)] = value[:, c] nat = natoms if vec_cell: nat -= nPBC # Write the output fileobj.write('%d\n' % nat) fileobj.write('%s\n' % comm) for i in range(natoms): fileobj.write(fmt % tuple(data[i]))
def write_lammps_in(self, lammps_in=None, lammps_trj=None, lammps_data=None): """Write a LAMMPS in_ file with run parameters and settings.""" if isinstance(lammps_in, basestring): f = paropen(lammps_in, 'wb') close_in_file = True else: # Expect lammps_in to be a file-like object f = lammps_in close_in_file = False if self.keep_tmp_files: f.write('# (written by ASE)\n'.encode('utf-8')) # Write variables f.write(('clear\n' 'variable dump_file string "{0}"\n' 'variable data_file string "{1}"\n').format( lammps_trj, lammps_data).encode('utf-8')) parameters = self.parameters if 'package' in parameters: f.write(('\n'.join( ['package {0}'.format(p) for p in parameters['package']]) + '\n').encode('utf-8')) pbc = self.atoms.get_pbc() f.write('units metal \n'.encode('utf-8')) if 'boundary' in parameters: f.write('boundary {0} \n'.format( parameters['boundary']).encode('utf-8')) else: f.write('boundary {0} {1} {2} \n'.format(*tuple( 'sp'[int(x)] for x in pbc)).encode('utf-8')) f.write('atom_modify sort 0 0.0 \n'.encode('utf-8')) for key in ('neighbor', 'newton'): if key in parameters: f.write('{0} {1} \n'.format(key, parameters[key]).encode('utf-8')) f.write('\n'.encode('utf-8')) # If self.no_lammps_data, # write the simulation box and the atoms if self.no_data_file: if self.keep_tmp_files: f.write('## Original ase cell\n'.encode('utf-8')) f.write(''.join([ '# {0:.16} {1:.16} {2:.16}\n'.format(*x) for x in self.atoms.get_cell() ]).encode('utf-8')) f.write('lattice sc 1.0\n'.encode('utf-8')) xhi, yhi, zhi, xy, xz, yz = self.prism.get_lammps_prism_str() if self.always_triclinic or self.prism.is_skewed(): f.write('region asecell prism 0.0 {0} 0.0 {1} 0.0 {2} ' ''.format(xhi, yhi, zhi).encode('utf-8')) f.write('{0} {1} {2} side in units box\n' ''.format(xy, xz, yz).encode('utf-8')) else: f.write(('region asecell block 0.0 {0} 0.0 {1} 0.0 {2} ' 'side in units box\n').format(xhi, yhi, zhi).encode('utf-8')) symbols = self.atoms.get_chemical_symbols() if self.specorder is None: # By default, atom types in alphabetic order species = sorted(set(symbols)) else: # By request, specific atom type ordering species = self.specorder n_atom_types = len(species) species_i = dict([(s, i + 1) for i, s in enumerate(species)]) f.write('create_box {0} asecell\n'.format(n_atom_types).encode( 'utf-8')) for s, pos in zip(symbols, self.atoms.get_positions()): if self.keep_tmp_files: f.write('# atom pos in ase cell: {0:.16} {1:.16} {2:.16}' '\n'.format(*tuple(pos)).encode('utf-8')) f.write('create_atoms {0} single {1} {2} {3} units box\n' ''.format(*((species_i[s], ) + self.prism.pos_to_lammps_fold_str(pos) )).encode('utf-8')) # if NOT self.no_lammps_data, then simply refer to the data-file else: f.write('read_data {0}\n'.format(lammps_data).encode('utf-8')) # Write interaction stuff f.write('\n### interactions \n'.encode('utf-8')) if ('pair_style' in parameters) and ('pair_coeff' in parameters): pair_style = parameters['pair_style'] f.write('pair_style {0} \n'.format(pair_style).encode('utf-8')) for pair_coeff in parameters['pair_coeff']: f.write('pair_coeff {0} \n' ''.format(pair_coeff).encode('utf-8')) if 'mass' in parameters: for mass in parameters['mass']: f.write('mass {0} \n'.format(mass).encode('utf-8')) else: # simple default parameters # that should always make the LAMMPS calculation run f.write('pair_style lj/cut 2.5 \n' 'pair_coeff * * 1 1 \n' 'mass * 1.0 \n'.encode('utf-8')) if 'group' in parameters: f.write(( '\n'.join(['group {0}'.format(p) for p in parameters['group']]) + '\n').encode('utf-8')) f.write('\n### run\n' 'fix fix_nve all nve\n'.encode('utf-8')) if 'fix' in parameters: f.write( ('\n'.join(['fix {0}'.format(p) for p in parameters['fix']]) + '\n').encode('utf-8')) f.write('dump dump_all all custom {1} {0} id type x y z vx vy vz ' 'fx fy fz\n' ''.format(lammps_trj, self.dump_period).encode('utf-8')) f.write('thermo_style custom {0}\n' 'thermo_modify flush yes\n' 'thermo 1\n'.format(' '.join( self._custom_thermo_args)).encode('utf-8')) if 'timestep' in parameters: f.write('timestep {0}\n'.format( parameters['timestep']).encode('utf-8')) if 'minimize' in parameters: f.write('minimize {0}\n'.format( parameters['minimize']).encode('utf-8')) if 'run' in parameters: f.write('run {0}\n'.format(parameters['run']).encode('utf-8')) if not (('minimize' in parameters) or ('run' in parameters)): f.write('run 0\n'.encode('utf-8')) f.write('print "{0}" \n'.format(CALCULATION_END_MARK).encode('utf-8')) # Force LAMMPS to flush log f.write('log /dev/stdout\n'.encode('utf-8')) f.flush() if close_in_file: f.close()
def write_gcube(obj, filename=None, dbn=None, etyp=None): """ write general cube file, being either trivial gaussian cube or extended gaussian cube file (where the second line is energy in unit kJ/mol) """ if isinstance(obj, str): print(' use string to gen geometry from db, then write cube') atoms, db0 = db2atoms(obj, dbn=dbn, rdb=True) filename = obj try: energy = db0[etyp] # e.g., etyp = 'De' or 'D0' except: print('#ERROR: no such keyword `%s in db0' % etyp) sys.exit(2) elif isinstance(obj, Atoms): print(' directly use input Atoms obj to write cube') atoms = obj if filename is None: filename = concatenate([aj.symbol for aj in atoms]) energy = 1.0E+20 else: print('#ERROR: invalid input obj for writing cube file') try: De = db0['De'] except: print('#ERROR: no `De keyword') sys.exit(2) # codes following are extracted from cube.py in ase/io/ directory # with minor modifications. fileobj = formula + '.cube' fileobj = paropen(fileobj, 'w') data = np.ones((2, 2, 2)) data = np.asarray(data) fileobj.write('%s\n' % formula) fileobj.write('%.5E\n' % energy) cell = atoms.get_cell() shape = np.array(data.shape) corner = np.zeros(3) for i in range(3): if shape[i] % 2 == 1: shape[i] += 1 corner += cell[i] / shape[i] / Bohr fileobj.write('%5d%12.6f%12.6f%12.6f\n' % (len(atoms), corner[0], corner[1], corner[2])) for i in range(3): n = data.shape[i] d = cell[i] / shape[i] / Bohr fileobj.write('%5d%12.6f%12.6f%12.6f\n' % (n, d[0], d[1], d[2])) positions = atoms.get_positions() / Bohr numbers = atoms.get_atomic_numbers() for Z, (x, y, z) in zip(numbers, positions): fileobj.write('%5d%12.6f%12.6f%12.6f%12.6f\n' % (Z, 0.0, x, y, z)) data.tofile(fileobj, sep='\n', format='%e')
del calc time.sleep(10) while not os.path.isfile(name + '_esx.gpw'): print('Node %d waiting for %s...' % (world.rank, name + '_esx.gpw')) time.sleep(10) world.barrier() tdcalc = TDDFT(name + '_esx.gpw', txt=name + '_td.txt', propagator='EFSICN') ehrenfest = EhrenfestVelocityVerlet(tdcalc) traj = Trajectory(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 s = 'i=%06d (%6.2f min^-1), ekin=%13.9f, epot=%13.9f, etot=%13.9f' print(s % (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(spa, energy=epot, forces=F_av)
from __future__ import print_function from ase.dft.kpoints import bandpath from ase.io import read from ase.parallel import paropen from gpaw import GPAW a = read('gs_Bi2Se3.gpw') G = [0.0, 0.0, 0.0] L = [0.5, 0.0, 0.0] F = [0.5, 0.5, 0.0] Z = [0.5, 0.5, 0.5] kpts, x, X = bandpath([G, Z, F, G, L], a.cell, npoints=200) calc = GPAW('gs_Bi2Se3.gpw', kpts=kpts, symmetry='off', fixdensity=True, txt='Bi2Se3_bands.txt') calc.get_potential_energy() calc.write('Bi2Se3_bands.gpw') with paropen('kpath.dat', 'w') as f: for k in x: print(k, file=f) with paropen('highsym.dat', 'w') as f: for k in X: print(k, file=f)
atoms.set_velocities(np.zeros_like(atoms.get_positions())) cell_c = np.sum(atoms.get_cell()**2, axis=1)**0.5 N_c = 16 * np.round(cell_c / (0.25 * 16)) calc = GPAW(gpts=N_c, nbands=1, basis='dzp', setups={'Na': '1'}, txt=name + '_gs.txt') atoms.set_calculator(calc) atoms.get_potential_energy() calc.write(name + '_gs.gpw', mode='all') del atoms, calc time.sleep(10) while not os.path.isfile(name + '_gs.gpw'): print('Node %d waiting for file...' % world.rank) time.sleep(10) world.barrier() tdcalc = GPAW(name + '_gs.gpw', txt=name + '_td.txt') atoms = tdcalc.get_atoms() traj = Trajectory(name + '_td.traj', 'w', atoms) verlet = VelocityVerlet(atoms, timestep * 1e-3 * fs, logfile=paropen(name + '_td.verlet', 'w'), trajectory=traj) verlet.attach(Timing(paropen(name + '_td.log', 'w')), ndiv, atoms) verlet.run(niter) traj.close()
def write_lammps_data(fileobj, atoms, specorder=None, force_skew=False, prismobj=None, velocities=False, charges=False): """Write atomic structure data to a LAMMPS data_file.""" if isinstance(fileobj, basestring): f = paropen(fileobj, 'wb') close_file = True else: # Presume fileobj acts like a fileobj f = fileobj close_file = False if isinstance(atoms, list): if len(atoms) > 1: raise ValueError( 'Can only write one configuration to a lammps data file!') atoms = atoms[0] f.write('{0} (written by ASE) \n\n'.format(f.name).encode('utf-8')) symbols = atoms.get_chemical_symbols() n_atoms = len(symbols) f.write('{0} atoms \n'.format(n_atoms).encode('utf-8')) if specorder is None: # This way it is assured that LAMMPS atom types are always # assigned predictably according to the alphabetic order species = sorted(set(symbols)) else: # To index elements in the LAMMPS data file # (indices must correspond to order in the potential file) species = specorder n_atom_types = len(species) f.write('{0} atom types\n'.format(n_atom_types).encode('utf-8')) if prismobj is None: p = Prism(atoms.get_cell()) else: p = prismobj xhi, yhi, zhi, xy, xz, yz = p.get_lammps_prism_str() f.write('0.0 {0} xlo xhi\n'.format(xhi).encode('utf-8')) f.write('0.0 {0} ylo yhi\n'.format(yhi).encode('utf-8')) f.write('0.0 {0} zlo zhi\n'.format(zhi).encode('utf-8')) if force_skew or p.is_skewed(): f.write('{0} {1} {2} xy xz yz\n'.format(xy, xz, yz).encode('utf-8')) f.write('\n'.encode('utf-8')) f.write('Masses \n\n'.encode('utf-8')) for s in species: i = species.index(s) + 1 f.write('{0:>2d} {1:>.4f}\n'.format( i, atomic_masses[atomic_numbers[s]]).encode('utf-8')) f.write('\n'.encode('utf-8')) f.write('Atoms \n\n'.encode('utf-8')) # Temporary support for adding a charge if charges: for i, (r, q) in enumerate( zip(p.positions_to_lammps_strs(atoms.get_positions()), atoms.get_initial_charges())): s = species.index(symbols[i]) + 1 f.write( '{0:>6} {1:>3} {5:>10.6f} {2:>14} {3:>14} {4:>14}\n'.format( *(i + 1, s) + tuple(r), q).encode('utf-8')) else: for i, r in enumerate(p.positions_to_lammps_strs( atoms.get_positions())): s = species.index(symbols[i]) + 1 f.write('{0:>6} {1:>3} {2:>14} {3:>14} {4:>14}\n'.format( *(i + 1, s) + tuple(r)).encode('utf-8')) if velocities and atoms.get_velocities() is not None: f.write('\n\nVelocities \n\n'.encode('utf-8')) for i, v in enumerate(atoms.get_velocities() / (Ang / (fs * 1000.))): f.write('{0:>6} {1:>.10f} {2:>.10f} {3:>.10f}\n'.format( *(i + 1, ) + tuple(v)).encode('utf-8')) f.flush() if close_file: f.close()
def write_lammps_data( fileobj, atoms, specorder=None, force_skew=False, prismobj=None, velocities=True, units="metal", ## YJ atom_style='atomic'): """Write atomic structure data to a LAMMPS data file.""" if isinstance(fileobj, str): fd = paropen(fileobj, "w", encoding="ascii") close_file = True else: # Presume fileobj acts like a fileobj fd = fileobj close_file = False # FIXME: We should add a check here that the encoding of the file object # is actually ascii once the 'encoding' attribute of IOFormat objects # starts functioning in implementation (currently it doesn't do # anything). if isinstance(atoms, list): if len(atoms) > 1: raise ValueError( "Can only write one configuration to a lammps data file!") atoms = atoms[0] if hasattr(fd, "name"): fd.write("{0} (written by ASE) \n\n".format(fd.name)) else: fd.write("(written by ASE) \n\n") symbols = atoms.get_chemical_symbols() n_atoms = len(symbols) fd.write("{0} \t atoms \n".format(n_atoms)) if specorder is None: # This way it is assured that LAMMPS atom types are always # assigned predictably according to the alphabetic order species = sorted(set(symbols)) else: # To index elements in the LAMMPS data file # (indices must correspond to order in the potential file) species = specorder n_atom_types = len(species) fd.write("{0} atom types\n".format(n_atom_types)) if prismobj is None: p = Prism(atoms.get_cell()) else: p = prismobj # Get cell parameters and convert from ASE units to LAMMPS units xhi, yhi, zhi, xy, xz, yz = convert(p.get_lammps_prism(), "distance", "ASE", units) fd.write("0.0 {0:23.17g} xlo xhi\n".format(xhi)) fd.write("0.0 {0:23.17g} ylo yhi\n".format(yhi)) fd.write("0.0 {0:23.17g} zlo zhi\n".format(zhi)) if force_skew or p.is_skewed(): fd.write("{0:23.17g} {1:23.17g} {2:23.17g} xy xz yz\n".format( xy, xz, yz)) fd.write("\n\n") fd.write("Atoms \n\n") pos = p.vector_to_lammps(atoms.get_positions(), wrap=True) if atom_style == 'atomic': for i, r in enumerate(pos): # Convert position from ASE units to LAMMPS units r = convert(r, "distance", "ASE", units) s = species.index(symbols[i]) + 1 fd.write("{0:>6} {1:>3} {2:23.17g} {3:23.17g} {4:23.17g}\n".format( *(i + 1, s) + tuple(r))) elif atom_style == 'charge': charges = atoms.get_initial_charges() for i, (q, r) in enumerate(zip(charges, pos)): # Convert position and charge from ASE units to LAMMPS units r = convert(r, "distance", "ASE", units) q = convert(q, "charge", "ASE", units) s = species.index(symbols[i]) + 1 fd.write("{0:>6} {1:>3} {2:>5} {3:23.17g} {4:23.17g} {5:23.17g}\n". format(*(i + 1, s, q) + tuple(r))) elif atom_style == 'full': charges = atoms.get_initial_charges() # The label 'mol-id' has apparenlty been introduced in read earlier, # but so far not implemented here. Wouldn't a 'underscored' label # be better, i.e. 'mol_id' or 'molecule_id'? if atoms.has('mol-id'): molecules = atoms.get_array('mol-id') if not np.issubdtype(molecules.dtype, np.integer): raise TypeError( ("If 'atoms' object has 'mol-id' array, then" " mol-id dtype must be subtype of np.integer, and" " not {:s}.").format(str(molecules.dtype))) if (len(molecules) != len(atoms)) or (molecules.ndim != 1): raise TypeError(("If 'atoms' object has 'mol-id' array, then" " each atom must have exactly one mol-id.")) else: # Assigning each atom to a distinct molecule id would seem # preferableabove assigning all atoms to a single molecule id per # default, as done within ase <= v 3.19.1. I.e., # molecules = np.arange(start=1, stop=len(atoms)+1, step=1, dtype=int) # However, according to LAMMPS default behavior, molecules = np.zeros(len(atoms)) # which is what happens if one creates new atoms within LAMMPS # without explicitly taking care of the molecule id. # Quote from docs at https://lammps.sandia.gov/doc/read_data.html: # The molecule ID is a 2nd identifier attached to an atom. # Normally, it is a number from 1 to N, identifying which # molecule the atom belongs to. It can be 0 if it is a # non-bonded atom or if you don't care to keep track of molecule # assignments. for i, (m, q, r) in enumerate(zip(molecules, charges, pos)): # Convert position and charge from ASE units to LAMMPS units r = convert(r, "distance", "ASE", units) q = convert(q, "charge", "ASE", units) s = species.index(symbols[i]) + 1 fd.write("{0:>6} {1:>3} {2:>3} {3:>5} {4:23.17g} {5:23.17g} " "{6:23.17g}\n".format(*(i + 1, m, s, q) + tuple(r))) else: raise NotImplementedError if velocities and atoms.get_velocities() is not None: fd.write("\n\nVelocities \n\n") vel = p.vector_to_lammps(atoms.get_velocities()) for i, v in enumerate(vel): # Convert velocity from ASE units to LAMMPS units v = convert(v, "velocity", "ASE", units) fd.write("{0:>6} {1:23.17g} {2:23.17g} {3:23.17g}\n".format( *(i + 1, ) + tuple(v))) fd.flush() if close_file: fd.close()
def read_lammps_trj(self, lammps_trj=None, set_atoms=False): """Method which reads a LAMMPS dump file.""" import pandas as pd from io import StringIO if lammps_trj is None: lammps_trj = self.label + '.lammpstrj' f = paropen(lammps_trj, 'r') for line in f: # Read the file into memory if line.startswith('ITEM: TIMESTEP'): _step_number = int(next(f).strip()) elif line.startswith('ITEM: NUMBER OF ATOMS'): n_atoms = int(next(f).strip()) elif line.startswith('ITEM: BOX BOUNDS'): _box_str = [next(f).rstrip().split(' ') for x in range(3)] # box_df = pd.DataFrame( # box_str, columns=['lo', 'hi', 'tilt'], dtype=float) elif line.startswith('ITEM: ATOMS'): # atoms_str = [next(f).rstrip().split(' ') # for x in range(n_atoms)] atoms_str = ''.join([next(f) for x in range(n_atoms)]) atoms_df = pd.read_csv(StringIO(line[12:] + atoms_str), delim_whitespace=True, index_col=0) atoms_df.sort_index(inplace=True) #atoms_df.sort_values(by='id', inplace=True) # Create appropriate atoms object # Determine cell tilt for triclinic case # if not box_df.tilt.isnull().values.any(): # # Assuming default order # xy = box_df.tilt[0] # xz = box_df.tilt[1] # yz = box_df.tilt[2] # xhilo = (box_df.hi[0] - box_df.lo[0]) - xy - xz # yhilo = (box_df.hi[1] - box_df.lo[1]) - yz # zhilo = (box_df.hi[2] - box_df.lo[2]) if self.atoms: cell_atoms = self.atoms.get_cell() # BEWARE: reconstructing the rotation from the LAMMPS # output trajectory file fails in case of shrink # wrapping for a non-periodic direction # -> hence rather obtain rotation from prism object # used to generate the LAMMPS input # rotation_lammps2ase = np.dot( # np.linalg.inv(np.array(cell)), cell_atoms) rotation_lammps2ase = np.linalg.inv(self.prism.R) type_atoms = self.atoms.get_atomic_numbers() cols = atoms_df.columns positions_atoms = np.dot( atoms_df.to_numpy() [:, cols.get_loc('x'):cols.get_loc('z') + 1], rotation_lammps2ase) velocities_atoms = np.dot( atoms_df.to_numpy() [:, cols.get_loc('vx'):cols.get_loc('vz') + 1], rotation_lammps2ase) forces_atoms = np.dot( atoms_df.to_numpy() [:, cols.get_loc('fx'):cols.get_loc('fz') + 1], rotation_lammps2ase) if set_atoms: # assume periodic boundary conditions here (as in # write_lammps) self.atoms = Atoms(type_atoms, positions=positions_atoms, cell=cell_atoms) self.atoms.set_velocities(velocities_atoms * (Ang / (fs * 1000.))) self.forces = forces_atoms if self.trajectory_out is not None: tmp_atoms = Atoms(type_atoms, positions=positions_atoms, cell=cell_atoms) tmp_atoms.set_velocities(velocities_atoms) self.trajectory_out.write(tmp_atoms) f.close()
def write_latex_array(self, fname='vib_latex_array.tex.table', caption='', nb_column=5, hline=False, method='standard', direction='central', intensity_unit_ir='(D/A)2/amu', intensity_unit_ram='au', label='tab_vib', log=stdout, freq_pol=0.0): """ Write the summary into a latex table that can be easily incorporate into a latex file. """ hnu = self.get_energies(method, direction) s = 0.01 * units._e / units._c / units._hplanck iu_ir, iu_string_ir = self.intensity_prefactor(intensity_unit_ir) iu_ram, iu_string_ram = self.intensity_prefactor(intensity_unit_ram) freq_idx = (np.abs(self.freq_pol-freq_pol)).argmin() if intensity_unit_ir == '(D/A)2/amu': iu_format_ir = '%9.4f ' elif intensity_unit_ir == 'km/mol': iu_string_ir = ' ' + iu_string_ir iu_format_ir = ' %7.1f ' elif intensity_unit_ir == 'au': iu_format_ir = '%.6e ' elif intensity_unit_ir == 'A^4 amu^-1': iu_format_ir = '%9.4f ' if intensity_unit_ram == '(D/A)2/amu': iu_format_ram = '%9.4f' elif intensity_unit_ram == 'km/mol': iu_string_ram = ' ' + iu_string_ram iu_format_ram = ' %7.1f' elif intensity_unit_ram == 'au': iu_format_ram = '%.6e ' elif intensity_unit_ram == 'A^4 amu^-1': iu_format_ram = '%9.4f ' if isinstance(log, basestring): log = paropen(log, 'a') if hline: column = "|" else: column = "" for i in range(nb_column + 1): if hline: column = column + "c|" else: column = column + "c" f = open(fname, 'w') f.write("\begin{table}[h] \n") f.write(" \caption{" + caption + "} \n") f.write(" \begin{center}\n") f.write(" \begin{tabular}{" + column + "} \n") if hline: f.write(" \hline \n") f.write(' Mode & Frequency (meV) & Frequency ($cm^{-1}$) & Intensity IR (' + iu_string_ir + ') & Intensity Raman (' + iu_string_ram + ') \n') if hline: f.write(" \hline \n") for n, e in enumerate(hnu): if e.imag != 0: c = ' + i' e = e.imag else: c = ' ' e = e.real f.write((' %3d & %6.1f %s & %7.1f %s & ' + iu_format_ir + ' & ' + iu_format_ram + ' \n') % (n, 1000 * e, c, s * e, c, iu_ir * self.intensities_ir[n], iu_ram * self.intensities_ram[n, freq_idx].real)) if hline: f.write(r" \hline \n") f.write(" \end{tabular} \n") f.write(" \end{center} \n") f.write(" \label{" + label + "} \n") f.write("\end{table}\n") f.close()
def write_lammps_in(self, lammps_in=None, lammps_trj=None, lammps_data=None): """Write a LAMMPS in_ file with run parameters and settings.""" def write_var(f, parameter, default=None): if parameter in self.parameters: value = self.parameters[parameter] if isinstance(value, list): for v in value: f.write("{:14} {} \n".format(parameter, v).encode('utf-8')) else: f.write("{:14} {} \n".format(parameter, value).encode('utf-8')) elif default: # f.write("# Default values for {} used.\n".format(parameter).encode('utf-8')) f.write("{:14} {} \n".format(parameter, default).encode('utf-8')) else: # f.write('# !!!Parameter {} not found!\n'.format(parameter).encode('utf-8')) pass def write_box_and_atoms(f): if self.keep_tmp_files: f.write('## Original ase cell\n'.encode('utf-8')) f.write(''.join([ '# {0:.16} {1:.16} {2:.16}\n'.format(*x) for x in self.atoms.get_cell() ]).encode('utf-8')) write_var(f, 'lattice', 'sc 1.0') xhi, yhi, zhi, xy, xz, yz = self.prism.get_lammps_prism_str() if self.always_triclinic or self.prism.is_skewed(): write_var( f, 'region', 'asecell prism 0.0 {0} 0.0 {1} 0.0 {2} {3} {4} {5} side in units box' .format(xhi, yhi, zhi, xy, xz, yz)) else: write_var( f, 'region', 'asecell block 0.0 {0} 0.0 {1} 0.0 {2} side in units box'. format(xhi, yhi, zhi)) symbols = self.atoms.get_chemical_symbols() if self.specorder is None: # By default, atom types in alphabetic order species = sorted(set(symbols)) else: # By request, specific atom type ordering species = self.specorder n_atom_types = len(species) species_i = dict([(s, i + 1) for i, s in enumerate(species)]) write_var(f, 'create_box', '{0} asecell'.format(n_atom_types)) f.write('\n# By default, atom types in alphabetic order\n'.encode( 'utf-8')) for s, pos in zip(symbols, self.atoms.get_positions()): if self.keep_tmp_files: f.write('# atom pos in ase cell: {0:.16} {1:.16} {2:.16}' '\n'.format(*tuple(pos)).encode('utf-8')) write_var( f, 'create_atoms', '{0} single {1} {2} {3} units box\n'.format( *((species_i[s], ) + self.prism.pos_to_lammps_fold_str(pos)))) if isinstance(lammps_in, basestring): f = paropen(lammps_in, 'wb') close_in_file = True else: # Expect lammps_in to be a file-like object f = lammps_in close_in_file = False if self.keep_tmp_files: f.write('# (written by ASE)\n'.encode('utf-8')) # Start f.write(('clear\n').format(lammps_trj, lammps_data).encode('utf-8')) # Writing commands by category: https://lammps.sandia.gov/doc/Commands_category.html # This is the general structure of how commands flow # TODO: customization within each section with a flag # Initialization/Settings f.write('\n # Initialization/Settings \n'.encode('utf-8')) write_var(f, 'newton') write_var(f, 'package') write_var(f, 'units') write_var(f, 'neighbor') write_var(f, 'neigh_modify') # Atoms Settings f.write('\n # Atoms \n'.encode('utf-8')) write_var(f, 'atom_style', 'metal') write_var(f, 'atom_modify') write_var( f, 'boundary', '{0} {1} {2}'.format(*tuple('sp'[x] for x in self.atoms.get_pbc()))) # If not using data file, write the simulation box and the atoms f.write('\n # Basic Simulation Box and Atoms \n'.encode('utf-8')) if self.no_data_file: write_box_and_atoms(f) else: write_var(f, 'read_data', lammps_data) # Additional Setup Simulation Box and Atoms Setup f.write( '\n # Additional Setup Simulation Box and Atoms Setup \n'.encode( 'utf-8')) write_var(f, 'region') write_var(f, 'group') write_var(f, 'mass') write_var(f, 'velocity') write_var(f, 'replicate') # Interaction Setup f.write('\n # Interactions Setup \n'.encode('utf-8')) write_var(f, 'pair_style') write_var(f, 'pair_coeff') write_var(f, 'pair_modify') write_var(f, 'kspace_style') write_var(f, 'bond_style') write_var(f, 'bond_coeff') write_var(f, 'angle_style') write_var(f, 'angle_coeff') # Simulation Run Setup f.write('\n # Simulation Run Setup \n'.encode('utf-8')) write_var(f, 'fix', 'fix_nve all nve') write_var( f, 'dump', 'dump_all all custom {1} "{0}" id type x y z vx vy vz fx fy fz'. format(lammps_trj, self.dump_period)) write_var(f, 'thermo_style', 'custom {0}'.format(' '.join(self._custom_thermo_args))) write_var(f, 'thermo_modify', 'flush yes') write_var(f, 'thermo', '1') write_var(f, 'timestep', '1') write_var(f, 'restart') write_var(f, 'min_style') write_var(f, 'min_modify') write_var(f, 'minimize') write_var(f, 'run') f.write('print "{0}" \n'.format(CALCULATION_END_MARK).encode('utf-8')) # Force LAMMPS to flush log #### f.write('log /dev/stdout\n'.encode('utf-8')) f.flush() if close_in_file: f.close()
def summary(self, method='standard', direction='central', freq_pol = 0.0, intensity_unit_ir='(D/A)2/amu', intensity_unit_ram='au', log=stdout, inter = True): hnu = self.get_energies(method, direction, inter=inter) s = 0.01 * units._e / units._c / units._hplanck iu_ir, iu_string_ir = self.intensity_prefactor(intensity_unit_ir) iu_ram, iu_string_ram = self.intensity_prefactor(intensity_unit_ram) arr = [] freq_idx = (np.abs(self.freq_pol-freq_pol)).argmin() print("index: ", freq_idx) if intensity_unit_ir == '(D/A)2/amu': iu_format_ir = '%9.4f ' elif intensity_unit_ir == 'km/mol': iu_string_ir = ' ' + iu_string_ir iu_format_ir = ' %7.1f ' elif intensity_unit_ir == 'au': iu_format_ir = '%.6e ' elif intensity_unit_ir == 'A^4 amu^-1': iu_format_ir = '%9.4f ' if intensity_unit_ram == '(D/A)2/amu': iu_format_ram = '%9.4f' elif intensity_unit_ram == 'km/mol': iu_string_ram = ' ' + iu_string_ram iu_format_ram = ' %7.1f' elif intensity_unit_ram == 'au': iu_format_ram = '%.6e ' elif intensity_unit_ram == 'A^4 amu^-1': iu_format_ram = '%9.4f ' if isinstance(log, basestring): log = paropen(log, 'a') parprint('---------------------------------------------------------------------------------------------------------------------------', file=log) parprint(' Mode Frequency Intensity IR Intensity Raman (real) Intensity Raman (imag) Raman Ehanced', file=log) parprint(' # meV cm^-1 ' + iu_string_ir + ' ' + iu_string_ram + ' ' + iu_string_ram + ' ' + iu_string_ram, file=log) parprint('---------------------------------------------------------------------------------------------------------------------------', file=log) for n, e in enumerate(hnu): if e.imag != 0: c = 'i' e = e.imag else: c = ' ' e = e.real arr.append([n, 1000 * e, s * e, iu_ir * self.intensities_ir[n], iu_ram * self.intensities_ram[n, freq_idx].real, iu_ram * self.intensities_ram[n, freq_idx].imag]) parprint(('%3d %6.1f%s %7.1f%s ' + iu_format_ir + iu_format_ram + iu_format_ram + iu_format_ram) % (n, 1000 * e, c, s * e, c, iu_ir * self.intensities_ir[n], iu_ram * self.intensities_ram[n, freq_idx].real, iu_ram * self.intensities_ram[n, freq_idx].imag, iu_ram * self.intensities_ram_enh[n, freq_idx].real), file=log) parprint( '-----------------------------------------------------------------------------------------', file=log) parprint('Zero-point energy: %.3f eV' % self.get_zero_point_energy(), file=log) parprint('Static dipole moment: %.3f D' % self.dipole_zero, file=log) parprint('Maximum force on atom in `equilibrium`: %.4f eV/Å' % self.force_zero, file=log) parprint(file=log) np.savetxt('ram-summary.txt', np.array(arr))
def write_gromacs(fileobj, images): """Write gromacs geometry files (.gro). Writes: * atom positions, * velocities (if present, otherwise 0) * simulation cell (if present) """ if isinstance(fileobj, basestring): fileobj = paropen(fileobj, 'w') if not isinstance(images, (list, tuple)): images = [images] natoms = len(images[-1]) try: gromacs_residuenames = images[-1].get_array('residuenames') except: gromacs_residuenames = [] for idum in range(natoms): gromacs_residuenames.append('1DUM') try: gromacs_atomtypes = images[-1].get_array('atomtypes') except: gromacs_atomtypes = images[-1].get_chemical_symbols() try: residuenumbers = images[-1].get_array('residuenumbers') except (KeyError): residuenumbers = np.ones(natoms, int) pos = images[-1].get_positions() pos = pos / 10.0 try: vel = images[-1].get_velocities() vel = vel * 1000.0 * units.fs / units.nm except: vel = pos vel = pos * 0.0 # No "#" in the first line to prevent read error in VMD fileobj.write('A Gromacs structure file written by ASE \n') fileobj.write('%5d\n' % len(images[-1])) count = 1 # gromac line see http://manual.gromacs.org/documentation/current/user-guide/file-formats.html#gro # 1WATER OW1 1 0.126 1.624 1.679 0.1227 -0.0580 0.0434 for resnb, resname, atomtype, xyz, vxyz in zip\ (residuenumbers, gromacs_residuenames, gromacs_atomtypes, pos, vel): # THIS SHOULD BE THE CORRECT, PYTHON FORMATTING, EQUIVALENT TO THE # C FORMATTING GIVEN IN THE GROMACS DOCUMENTATION: # >>> %5d%-5s%5s%5d%8.3f%8.3f%8.3f%8.4f%8.4f%8.4f <<< line = ("{0:>5d}{1:<5s}{2:>5s}{3:>5d}{4:>8.3f}{5:>8.3f}{6:>8.3f}" "{7:>8.4f}{8:>8.4f}{9:>8.4f}\n".format(resnb, resname, atomtype, count, xyz[0], xyz[1], xyz[2], vxyz[0], vxyz[1], vxyz[2])) fileobj.write(line) count += 1 # write box geometry if images[-1].get_pbc().any(): mycell = images[-1].get_cell() # gromacs manual (manual.gromacs.org/online/gro.html) says: # v1(x) v2(y) v3(z) v1(y) v1(z) v2(x) v2(z) v3(x) v3(y) # # cell[0,0] cell[1,0] cell[2,0] v1(x) v2(y) v3(z) fv0[0 1 2] # cell[0,1] cell[1,1] cell[2,1] v1(y) v1(z) v2(x) fv1[0 1 2] # cell[0,2] cell[1,2] cell[2,2] v2(z) v3(x) v3(y) fv2[0 1 2] fileobj.write('%10.5f%10.5f%10.5f' \ % (mycell[0, 0] * 0.1, \ mycell[1, 1] * 0.1, \ mycell[2, 2] * 0.1)) fileobj.write('%10.5f%10.5f%10.5f' \ % (mycell[1, 0] * 0.1, \ mycell[2, 0] * 0.1, \ mycell[0, 1] * 0.1)) fileobj.write('%10.5f%10.5f%10.5f\n' \ % (mycell[2, 1] * 0.1, \ mycell[0, 2] * 0.1, \ mycell[1, 2] * 0.1)) else: # When we do not have a cell, the cell is specified as an empty line fileobj.write("\n")
def write_cif(fileobj, images, cif_format='default', wrap=True, labels=None, loop_keys={}) -> None: """Write *images* to CIF file. wrap: bool Wrap atoms into unit cell. labels: list Use this list (shaped list[i_frame][i_atom] = string) for the '_atom_site_label' section instead of automatically generating it from the element symbol. loop_keys: dict Add the information from this dictionary to the `loop_` section. Keys are printed to the `loop_` section preceeded by ' _'. dict[key] should contain the data printed for each atom, so it needs to have the setup `dict[key][i_frame][i_atom] = string`. The strings are printed as they are, so take care of formating. Information can be re-read using the `store_tags` option of the cif reader. """ if isinstance(fileobj, str): fileobj = paropen(fileobj, 'wb') if hasattr(images, 'get_positions'): images = [images] for i_frame, atoms in enumerate(images): write_enc(fileobj, 'data_image%d\n' % i_frame) a, b, c, alpha, beta, gamma = atoms.get_cell_lengths_and_angles() if cif_format == 'mp': comp_name = atoms.get_chemical_formula(mode='reduce') sf = split_chem_form(comp_name) formula_sum = '' ii = 0 while ii < len(sf): formula_sum = formula_sum + ' ' + sf[ii] + sf[ii + 1] ii = ii + 2 formula_sum = str(formula_sum) write_enc(fileobj, '_chemical_formula_structural %s\n' % atoms.get_chemical_formula(mode='reduce')) write_enc(fileobj, '_chemical_formula_sum "%s"\n' % formula_sum) # Do this only if there's three non-zero lattice vectors if atoms.number_of_lattice_vectors == 3: write_enc(fileobj, '_cell_length_a %g\n' % a) write_enc(fileobj, '_cell_length_b %g\n' % b) write_enc(fileobj, '_cell_length_c %g\n' % c) write_enc(fileobj, '_cell_angle_alpha %g\n' % alpha) write_enc(fileobj, '_cell_angle_beta %g\n' % beta) write_enc(fileobj, '_cell_angle_gamma %g\n' % gamma) write_enc(fileobj, '\n') write_enc(fileobj, '_symmetry_space_group_name_H-M %s\n' % '"P 1"') write_enc(fileobj, '_symmetry_int_tables_number %d\n' % 1) write_enc(fileobj, '\n') write_enc(fileobj, 'loop_\n') write_enc(fileobj, ' _symmetry_equiv_pos_as_xyz\n') write_enc(fileobj, " 'x, y, z'\n") write_enc(fileobj, '\n') write_enc(fileobj, 'loop_\n') # Is it a periodic system? coord_type = 'fract' if atoms.pbc.all() else 'Cartn' if cif_format == 'mp': write_enc(fileobj, ' _atom_site_type_symbol\n') write_enc(fileobj, ' _atom_site_label\n') write_enc(fileobj, ' _atom_site_symmetry_multiplicity\n') write_enc(fileobj, ' _atom_site_{0}_x\n'.format(coord_type)) write_enc(fileobj, ' _atom_site_{0}_y\n'.format(coord_type)) write_enc(fileobj, ' _atom_site_{0}_z\n'.format(coord_type)) write_enc(fileobj, ' _atom_site_occupancy\n') else: write_enc(fileobj, ' _atom_site_label\n') write_enc(fileobj, ' _atom_site_occupancy\n') write_enc(fileobj, ' _atom_site_{0}_x\n'.format(coord_type)) write_enc(fileobj, ' _atom_site_{0}_y\n'.format(coord_type)) write_enc(fileobj, ' _atom_site_{0}_z\n'.format(coord_type)) write_enc(fileobj, ' _atom_site_thermal_displace_type\n') write_enc(fileobj, ' _atom_site_B_iso_or_equiv\n') write_enc(fileobj, ' _atom_site_type_symbol\n') if coord_type == 'fract': coords = atoms.get_scaled_positions(wrap).tolist() else: coords = atoms.get_positions(wrap).tolist() symbols = atoms.get_chemical_symbols() occupancies = [1 for i in range(len(symbols))] # try to fetch occupancies // spacegroup_kinds - occupancy mapping try: occ_info = atoms.info['occupancy'] kinds = atoms.arrays['spacegroup_kinds'] for i, kind in enumerate(kinds): occupancies[i] = occ_info[kind][symbols[i]] # extend the positions array in case of mixed occupancy for sym, occ in occ_info[kind].items(): if sym != symbols[i]: symbols.append(sym) coords.append(coords[i]) occupancies.append(occ) except KeyError: pass #can only do it now since length of atoms is not always equal to the number of entries #do not move this up! extra_data = ["" for i in range(len(symbols))] for key in loop_keys: extra_data = ["{} {}".format(extra_data[i],loop_keys[key][i_frame][i]) for i in range(len(symbols))] write_enc(fileobj, " _{}\n".format(key)) if labels: included_labels = labels[i_frame] else: no: Dict[str, int] = {} included_labels = [] for symbol in symbols: if symbol in no: no[symbol] += 1 else: no[symbol] = 1 included_labels.append('%s%d' % (symbol, no[symbol])) assert len(symbols) == len(coords) == len(occupancies) == len(included_labels) == len(extra_data) for symbol, pos, occ, label, ext in zip(symbols, coords, occupancies, included_labels, extra_data): if cif_format == 'mp': write_enc(fileobj, ' %-2s %4s %4s %7.5f %7.5f %7.5f %6.1f%s\n' % (symbol, label, 1, pos[0], pos[1], pos[2], occ, ext)) else: write_enc(fileobj, ' %-8s %6.4f %7.5f %7.5f %7.5f %4s %6.3f %-2s%s\n' % (label, occ, pos[0], pos[1], pos[2], 'Biso', 1.0, symbol, ext))
def read_lammps_trj(self, lammps_trj=None, set_atoms=False): """Method which reads a LAMMPS dump file.""" if lammps_trj is None: lammps_trj = self.label + '.lammpstrj' f = paropen(lammps_trj, 'r') while True: line = f.readline() if not line: break # TODO: extend to proper dealing with multiple steps in one # trajectory file if 'ITEM: TIMESTEP' in line: n_atoms = 0 lo = [] hi = [] tilt = [] id = [] type = [] positions = [] velocities = [] forces = [] if 'ITEM: NUMBER OF ATOMS' in line: line = f.readline() n_atoms = int(line.split()[0]) if 'ITEM: BOX BOUNDS' in line: # save labels behind "ITEM: BOX BOUNDS" in triclinic case # (>=lammps-7Jul09) tilt_items = line.split()[3:] for i in range(3): line = f.readline() fields = line.split() lo.append(float(fields[0])) hi.append(float(fields[1])) if len(fields) >= 3: tilt.append(float(fields[2])) if 'ITEM: ATOMS' in line: # (reliably) identify values by labels behind "ITEM: ATOMS" # - requires >=lammps-7Jul09 # create corresponding index dictionary before iterating over # atoms to (hopefully) speed up lookups... atom_attributes = {} for (i, x) in enumerate(line.split()[2:]): atom_attributes[x] = i for n in range(n_atoms): line = f.readline() fields = line.split() id.append(int(fields[atom_attributes['id']])) type.append(int(fields[atom_attributes['type']])) positions.append([ float(fields[atom_attributes[x]]) for x in ['x', 'y', 'z'] ]) velocities.append([ float(fields[atom_attributes[x]]) for x in ['vx', 'vy', 'vz'] ]) forces.append([ float(fields[atom_attributes[x]]) for x in ['fx', 'fy', 'fz'] ]) # Re-order items according to their 'id' since running in # parallel can give arbitrary ordering. type = [x for _, x in sorted(zip(id, type))] positions = [x for _, x in sorted(zip(id, positions))] velocities = [x for _, x in sorted(zip(id, velocities))] forces = [x for _, x in sorted(zip(id, forces))] # determine cell tilt (triclinic case!) if len(tilt) >= 3: # for >=lammps-7Jul09 use labels behind "ITEM: BOX BOUNDS" # to assign tilt (vector) elements ... if len(tilt_items) >= 3: xy = tilt[tilt_items.index('xy')] xz = tilt[tilt_items.index('xz')] yz = tilt[tilt_items.index('yz')] # ... otherwise assume default order in 3rd column # (if the latter was present) else: xy = tilt[0] xz = tilt[1] yz = tilt[2] else: xy = xz = yz = 0 xhilo = (hi[0] - lo[0]) - xy - xz yhilo = (hi[1] - lo[1]) - yz zhilo = (hi[2] - lo[2]) # The simulation box bounds are included in each snapshot and # if the box is triclinic (non-orthogonal), then the tilt # factors are also printed; see the region prism command for # a description of tilt factors. # For triclinic boxes the box bounds themselves (first 2 # quantities on each line) are a true "bounding box" around # the simulation domain, which means they include the effect of # any tilt. # [ http://lammps.sandia.gov/doc/dump.html , lammps-7Jul09 ] # # This *should* extract the lattice vectors that LAMMPS uses # from the true "bounding box" printed in the dump file. # It might fail in some cases (negative tilts?!) due to the # MIN / MAX construction of these box corners: # # void Domain::set_global_box() # [...] # if (triclinic) { # [...] # boxlo_bound[0] = MIN(boxlo[0],boxlo[0]+xy); # boxlo_bound[0] = MIN(boxlo_bound[0],boxlo_bound[0]+xz); # boxlo_bound[1] = MIN(boxlo[1],boxlo[1]+yz); # boxlo_bound[2] = boxlo[2]; # # boxhi_bound[0] = MAX(boxhi[0],boxhi[0]+xy); # boxhi_bound[0] = MAX(boxhi_bound[0],boxhi_bound[0]+xz); # boxhi_bound[1] = MAX(boxhi[1],boxhi[1]+yz); # boxhi_bound[2] = boxhi[2]; # } # [ lammps-7Jul09/src/domain.cpp ] # cell = [[xhilo, 0, 0], [xy, yhilo, 0], [xz, yz, zhilo]] # These have been put into the correct order cell_atoms = np.array(cell) type_atoms = np.array(type) if self.atoms: cell_atoms = self.atoms.get_cell() # BEWARE: reconstructing the rotation from the LAMMPS # output trajectory file fails in case of shrink # wrapping for a non-periodic direction # -> hence rather obtain rotation from prism object # used to generate the LAMMPS input # rotation_lammps2ase = np.dot( # np.linalg.inv(np.array(cell)), cell_atoms) rotation_lammps2ase = np.linalg.inv(self.prism.R) type_atoms = self.atoms.get_atomic_numbers() positions_atoms = np.dot(positions, rotation_lammps2ase) velocities_atoms = np.dot(velocities, rotation_lammps2ase) forces_atoms = np.dot(forces, rotation_lammps2ase) if set_atoms: # assume periodic boundary conditions here (as in # write_lammps) self.atoms = Atoms(type_atoms, positions=positions_atoms, cell=cell_atoms) self.atoms.set_velocities(velocities_atoms * (Ang / (fs * 1000.))) self.forces = forces_atoms if self.trajectory_out is not None: tmp_atoms = Atoms(type_atoms, positions=positions_atoms, cell=cell_atoms) tmp_atoms.set_velocities(velocities_atoms) self.trajectory_out.write(tmp_atoms) f.close()
def __init__(self, logname, descriptions=1, verbosity=1): self.f = paropen(logname, 'w') unittest.TextTestRunner.__init__(self, self.f, descriptions, verbosity)
def write_reactant_con(fileobj, images): """Writes structure to EON reactant.con file Multiple snapshots are not allowed.""" if isinstance(fileobj, str): f = paropen(fileobj, 'w') else: f = fileobj if isinstance(images, Atoms): atoms = images elif len(images) == 1: atoms = images[0] else: raise ValueError('Can only write one configuration to EON ' 'reactant.con file') out = [] out.append(atoms.info.get('comment', 'Generated by ASE')) out.append('0.0000 TIME') # ?? a, b, c, alpha, beta, gamma = cell_to_cellpar(atoms.cell) out.append('%-10.6f %-10.6f %-10.6f' % (a, b, c)) out.append('%-10.6f %-10.6f %-10.6f' % (gamma, alpha, beta)) out.append('0 0') # ?? out.append('0 0 0') # ?? symbols = atoms.get_chemical_symbols() massdict = dict(zip(symbols, atoms.get_masses())) atomtypes = sorted(massdict.keys()) atommasses = [massdict[at] for at in atomtypes] natoms = [symbols.count(at) for at in atomtypes] ntypes = len(atomtypes) out.append(str(ntypes)) out.append(' '.join([str(n) for n in natoms])) out.append(' '.join([str(n) for n in atommasses])) for n in range(ntypes): fixed = np.array([False] * len(atoms)) out.append(atomtypes[n]) out.append('Coordinates of Component %d' % (n + 1)) indices = [i for i, at in enumerate(symbols) if at == atomtypes[n]] a = atoms[indices] coords = a.positions for c in a.constraints: if not isinstance(c, FixAtoms): warn( 'Only FixAtoms constraints are supported by con files. ' 'Dropping %r', c) continue if c.index.dtype.kind == 'b': fixed = np.array(c.index, dtype=int) else: fixed = np.zeros((natoms[n], ), dtype=int) for i in c.index: fixed[i] = 1 for i, (xyz, fix) in enumerate(zip(coords, fixed)): out.append('%10.5f %10.5f %10.5f %d %d' % (tuple(xyz) + (fix, i))) f.write('\n'.join(out)) if isinstance(fileobj, str): f.close()