def test_md_water32_full(): dump = False ff = get_ff_water32(True, True, True, True) pos = ff.system.pos.copy() grad = np.zeros(pos.shape) h = 1.0 * femtosecond mass = np.array([periodic[n].mass for n in ff.system.numbers]).reshape( (-1, 1)) # init ff.update_pos(pos) epot = ff.compute(grad) temp = 300 vel = np.random.normal(0, 1, pos.shape) * np.sqrt( (2 * boltzmann * temp) / mass) velh = vel + (-0.5 * h) * grad / mass # prop cqs = [] if dump: symbols = [system.get_ffatype(i) for i in xrange(system.natom)] xyz_writer = XYZWriter('traj.xyz', symbols) for i in xrange(100): pos += velh * h ff.update_pos(pos) grad[:] = 0.0 epot = ff.compute(grad) if dump: xyz_writer.dump('i = %i energy = %.10f' % (i, epot), pos) tmp = (-0.5 * h) * grad / mass vel = velh + tmp ekin = 0.5 * (mass * vel * vel).sum() cqs.append(ekin + epot) velh = vel + tmp cqs = np.array(cqs) assert cqs.std() < 5e-3
def write_to_file(self, filename): """Write the molecular geometry to a file. The file format is inferred from the extensions. Currently supported formats are: ``*.xyz``, ``*.cml`` Argument: | ``filename`` -- a filename """ # TODO: give all file format writers the same API if filename.endswith('.cml'): from molmod.io import dump_cml dump_cml(filename, [self]) elif filename.endswith('.xyz'): from molmod.io import XYZWriter symbols = [] for n in self.numbers: atom = periodic[n] if atom is None: symbols.append("X") else: symbols.append(atom.symbol) xyz_writer = XYZWriter(filename, symbols) xyz_writer.dump(self.title, self.coordinates) del xyz_writer else: raise ValueError("Could not determine file format for %s." % filename)
def to_file(self, fn): """Write the system to a file **Arguments:** fn The file to write to. Supported formats are: chk Internal human-readable checkpoint format. This format includes all the information of a system object. All data are stored in atomic units. h5 Internal binary checkpoint format. This format includes all the information of a system object. All data are stored in atomic units. xyz A simple file with atomic positions and elements. Coordinates are written in Angstroms. """ if fn.endswith('.chk'): from molmod.io import dump_chk dump_chk( fn, { 'numbers': self.numbers, 'pos': self.pos, 'ffatypes': self.ffatypes, 'ffatype_ids': self.ffatype_ids, 'scopes': self.scopes, 'scope_ids': self.scope_ids, 'bonds': self.bonds, 'rvecs': self.cell.rvecs, 'charges': self.charges, 'radii': self.radii, 'valence_charges': self.valence_charges, 'dipoles': self.dipoles, 'radii2': self.radii2, 'masses': self.masses, }) elif fn.endswith('.h5'): with h5.File(fn, 'w') as f: self.to_hdf5(f) elif fn.endswith('.xyz'): from molmod.io import XYZWriter from molmod.periodic import periodic xyz_writer = XYZWriter(fn, [periodic[n].symbol for n in self.numbers]) xyz_writer.dump(str(self), self.pos) else: raise NotImplementedError( 'The extension of %s does not correspond to any known format.' % fn) if log.do_high: with log.section('SYS'): log('Wrote system to %s.' % fn)
def dump_modes_xyz(nma, indexes=0, prefix="mode", amplitude=5.0*angstrom, frames=36): """Write XYZ trajectory file(s) that vizualize internal mode(s) Arguments: | nma -- an object that specifies the normal modes, several formats are supported: (i) a Tamkin NMA object, (ii) a 3-tuple with reference coordinates, mass-unweighted mode(s) and atom numbers or (iii) a 4-tuple with reference coordinates, mass- weighted mode(s), atom numbers and a masses3 vector. the latter is a vector with 3*N elements containing the masses of the atoms in groups of three. Optional arguments: | indexes -- the index or a list of indexes of modes that must be written to trajectory files [default=0] | prefix -- a prefix used for the output files. the generated trajectory filenames have the format prefix.index.xyz [default="mode"] | amplitude -- the amplitude of the normal mode vibration in atomic untis [default=5*angstrom] | frames -- the number of frames written to the trajectory file [default=36] """ if isinstance(nma, NMA): coordinates = nma.coordinates modes = nma.modes numbers = nma.numbers masses3 = nma.masses3 elif hasattr(nma, "__len__") and len(nma)==3: coordinates, modes, numbers = nma masses3 = None elif hasattr(nma, "__len__") and len(nma)==4: coordinates, modes, numbers, masses3 = nma else: raise TypeError("Could not understand first argument. Check documentation.") if not hasattr(indexes, "__len__"): indexes = [indexes] if len(modes.shape) == 1: modes = modes.reshape((-1,1)) symbols = [periodic[n].symbol for n in numbers] for index in indexes: filename = "%s.%i.xyz" % (prefix, index) mode = modes[:,index] if masses3 is not None: mode /= np.sqrt(masses3) mode /= np.linalg.norm(mode) xyz_writer = XYZWriter(filename, symbols) for frame in xrange(frames): factor = amplitude*np.sin(2*np.pi*float(frame)/frames) xyz_writer.dump("frame %i" % frame, coordinates + factor*mode.reshape((-1,3))) del xyz_writer
def __call__(self, iterative): from molmod import angstrom if self.xyz_writer is None: from molmod.periodic import periodic from molmod.io import XYZWriter numbers = iterative.ff.system.numbers if self.select is None: symbols = [periodic[n].symbol for n in numbers] else: symbols = [periodic[numbers[i]].symbol for i in self.select] self.xyz_writer = XYZWriter(self.fn_xyz, symbols) rvecs = iterative.ff.system.cell.rvecs.copy() rvecs_string = " ".join([str(x[0]/angstrom) for x in rvecs.reshape((-1,1))]) title = '%7i E_pot = %.10f %s' % (iterative.counter, iterative.epot, rvecs_string) if self.select is None: pos = iterative.ff.system.pos else: pos = iterative.ff.system.pos[self.select] self.xyz_writer.dump(title, pos)