def __init__( self, atoms, timestep, temperature, externalstress, ttime, pfactor, mask=None, trajectory=None, logfile=None, loginterval=1, ): MolecularDynamics.__init__(self, atoms, timestep, trajectory, logfile, loginterval) # self.atoms = atoms # self.timestep = timestep self.zero_center_of_mass_momentum(verbose=1) self.temperature = temperature self.set_stress(externalstress) self.set_mask(mask) self.eta = zeros((3, 3), float) self.zeta = 0.0 self.zeta_integrated = 0.0 self.initialized = 0 self.ttime = ttime self.pfactor_given = pfactor self._calculateconstants() self.timeelapsed = 0.0 self.frac_traceless = 1
def __init__(self, atoms, timestep=0.1*units.fs, logfile=None, trajectory=None, loginterval=1, offset=(0.1, 0, 0)): MolecularDynamics.__init__(self, atoms, timestep, logfile, trajectory, loginterval) self._offset = np.array(offset)
def __init__(self, atoms, timestep, temperature, friction, fixcm=True, trajectory=None, logfile=None, loginterval=1, communicator=world): MolecularDynamics.__init__(self, atoms, timestep, trajectory, logfile, loginterval) self.temp = temperature self.frict = friction self.fixcm = fixcm # will the center of mass be held fixed? self.communicator = communicator self.updatevars()
def __init__(self, atoms, timestep, temperature, taut, fixcm=True, trajectory=None, logfile=None, loginterval=1, communicator=world): MolecularDynamics.__init__(self, atoms, timestep, trajectory, logfile, loginterval) self.taut = taut self.temperature = temperature self.fixcm = fixcm # will the center of mass be held fixed? self.communicator = communicator
def attach(self, function, interval=1, *args, **kwargs): """Attach callback function or trajectory. At every *interval* steps, call *function* with arguments *args* and keyword arguments *kwargs*. If *function* is a trajectory object, its write() method is attached, but if *function* is a BundleTrajectory (or another trajectory supporting set_extra_data(), said method is first used to instruct the trajectory to also save internal data from the NPT dynamics object. """ if hasattr(function, "set_extra_data"): # We are attaching a BundleTrajectory or similar function.set_extra_data("npt_init", WeakMethodWrapper(self, "get_init_data"), once=True) function.set_extra_data("npt_dynamics", WeakMethodWrapper(self, "get_data")) MolecularDynamics.attach(self, function, interval, *args, **kwargs)
def __init__(self, atoms, dt, trajectory=None, logfile=None, loginterval=1): MolecularDynamics.__init__(self, atoms, dt, trajectory, logfile, loginterval) if not atoms.has('momenta'): atoms.set_momenta(np.zeros((len(atoms), 3), float)) self.calculator = atoms.get_calculator() self.asap_md = asap3._asap.VelocityVerlet(atoms, self.calculator, dt) # Identify FixAtoms constraint if atoms.constraints: assert len(atoms.constraints) == 1 constraint = atoms.constraints[0] assert isinstance(constraint, asap3.constraints.FixAtoms) constraint.prepare_for_asap(atoms) mask = constraint.index assert mask.shape == (len(atoms),) and mask.dtype == bool mult = np.logical_not(mask).astype(float) self.atoms.arrays["FixAtoms_mult_double"] = mult
def attach_atoms(self, atoms): """Assign atoms to a restored dynamics object. This function must be called to set the atoms immediately after the dynamics object has been read from a trajectory. """ try: self.atoms except AttributeError: pass else: raise RuntimeError("Cannot call attach_atoms on a dynamics " "which already has atoms.") MolecularDynamics.__init__(self, atoms, self.dt) limit = 1e-6 h = self._getbox() if max(abs((h - self.h).ravel())) > limit: raise RuntimeError("The unit cell of the atoms does not match the unit cell stored in the file.") self.inv_h = linalg.inv(self.h) #self._make_special_q_arrays() self.q = np.dot(self.atoms.get_positions(), self.inv_h) - 0.5 self._calculate_q_past_and_future() self.initialized = 1
def __init__(self, atoms, timestep, temperature, ttime, trajectory=None, logfile=None, loginterval=1, **kwargs): MolecularDynamics.__init__(self, atoms, timestep, trajectory, logfile, loginterval) # Initialize simulation parameters # Q is chosen to be 6 N kT self.dt = timestep self.Natom = atoms.get_number_of_atoms() self.T = temperature self.targeEkin = 0.5 * (3.0 * self.Natom) * self.T self.ttime = ttime # * units.fs self.Q = 3.0 * self.Natom * self.T * (self.ttime * self.dt)**2 self.zeta = 0.0
def attach_atoms(self, atoms): """Assign atoms to a restored dynamics object. This function must be called to set the atoms immediately after the dynamics object has been read from a trajectory. """ try: self.atoms except AttributeError: pass else: raise RuntimeError("Cannot call attach_atoms on a dynamics which already has atoms.") MolecularDynamics.__init__(self, atoms, self.dt) ####self.atoms = atoms limit = 1e-6 h = self._getbox() if max(abs((h - self.h).ravel())) > limit: raise RuntimeError("The unit cell of the atoms does not match the unit cell stored in the file.") self.inv_h = linalg.inv(self.h) #self._make_special_q_arrays() self.q = dot(self.atoms.get_positions(), self.inv_h) - 0.5 self._calculate_q_past_and_future() self.initialized = 1
def __init__(self, atoms, timestep, temperature, externalstress, ttime, pfactor, mask=None, trajectory=None, logfile=None, loginterval=1, append_trajectory=False): MolecularDynamics.__init__(self, atoms, timestep, trajectory, logfile, loginterval, append_trajectory=append_trajectory) # self.atoms = atoms # self.timestep = timestep self.zero_center_of_mass_momentum(verbose=1) self.temperature = temperature self.set_stress(externalstress) self.set_mask(mask) self.eta = np.zeros((3, 3), float) self.zeta = 0.0 self.zeta_integrated = 0.0 self.initialized = 0 self.ttime = ttime self.pfactor_given = pfactor self._calculateconstants() self.timeelapsed = 0.0 self.frac_traceless = 1
def __init__(self, atoms, timestep=None, trajectory=None, logfile=None, loginterval=1, dt=None, append_trajectory=False): # FloK: rename dt -> timestep and make sure nobody is affected if dt is not None: import warnings warnings.warn('dt variable is deprecated; please use timestep.', DeprecationWarning) timestep = dt if timestep is None: raise TypeError('Missing timestep argument') MolecularDynamics.__init__(self, atoms, timestep, trajectory, logfile, loginterval, append_trajectory=append_trajectory)
def __init__(self, atoms, dt, trajectory=None, logfile=None, loginterval=1): MolecularDynamics.__init__(self, atoms, dt, trajectory, logfile, loginterval)
def __init__(self, atoms, timestep, temperature=None, externalstress=None, ttime=None, pfactor=None, *, temperature_K=None, mask=None, trajectory=None, logfile=None, loginterval=1, append_trajectory=False): '''Constant pressure/stress and temperature dynamics. Combined Nose-Hoover and Parrinello-Rahman dynamics, creating an NPT (or N,stress,T) ensemble. The method is the one proposed by Melchionna et al. [1] and later modified by Melchionna [2]. The differential equations are integrated using a centered difference method [3]. See also NPTdynamics.tex The dynamics object is called with the following parameters: atoms: Atoms object The list of atoms. timestep: float The timestep in units matching eV, Å, u. temperature: float (deprecated) The desired temperature in eV. temperature_K: float The desired temperature in K. externalstress: float or nparray The external stress in eV/A^3. Either a symmetric 3x3 tensor, a 6-vector representing the same, or a scalar representing the pressure. Note that the stress is positive in tension whereas the pressure is positive in compression: giving a scalar p is equivalent to giving the tensor (-p, -p, -p, 0, 0, 0). ttime: float Characteristic timescale of the thermostat, in ASE internal units Set to None to disable the thermostat. pfactor: float A constant in the barostat differential equation. If a characteristic barostat timescale of ptime is desired, set pfactor to ptime^2 * B (where ptime is in units matching eV, Å, u; and B is the Bulk Modulus, given in eV/Å^3). Set to None to disable the barostat. Typical metallic bulk moduli are of the order of 100 GPa or 0.6 eV/A^3. mask: None or 3-tuple or 3x3 nparray (optional) Optional argument. A tuple of three integers (0 or 1), indicating if the system can change size along the three Cartesian axes. Set to (1,1,1) or None to allow a fully flexible computational box. Set to (1,1,0) to disallow elongations along the z-axis etc. mask may also be specified as a symmetric 3x3 array indicating which strain values may change. Useful parameter values: * The same timestep can be used as in Verlet dynamics, i.e. 5 fs is fine for bulk copper. * The ttime and pfactor are quite critical[4], too small values may cause instabilites and/or wrong fluctuations in T / p. Too large values cause an oscillation which is slow to die. Good values for the characteristic times seem to be 25 fs for ttime, and 75 fs for ptime (used to calculate pfactor), at least for bulk copper with 15000-200000 atoms. But this is not well tested, it is IMPORTANT to monitor the temperature and stress/pressure fluctuations. References: 1) S. Melchionna, G. Ciccotti and B. L. Holian, Molecular Physics 78, p. 533 (1993). 2) S. Melchionna, Physical Review E 61, p. 6165 (2000). 3) B. L. Holian, A. J. De Groot, W. G. Hoover, and C. G. Hoover, Physical Review A 41, p. 4552 (1990). 4) F. D. Di Tolla and M. Ronchetti, Physical Review E 48, p. 1726 (1993). ''' MolecularDynamics.__init__(self, atoms, timestep, trajectory, logfile, loginterval, append_trajectory=append_trajectory) # self.atoms = atoms # self.timestep = timestep if externalstress is None: raise TypeError("Missing 'externalstress' argument.") if ttime is None: raise TypeError("Missing 'ttime' argument.") if pfactor is None: raise TypeError("Missing 'pfactor' argument.") self.zero_center_of_mass_momentum(verbose=1) self.temperature = units.kB * self._process_temperature( temperature, temperature_K, 'eV') self.set_stress(externalstress) self.set_mask(mask) self.eta = np.zeros((3, 3), float) self.zeta = 0.0 self.zeta_integrated = 0.0 self.initialized = 0 self.ttime = ttime self.pfactor_given = pfactor self._calculateconstants() self.timeelapsed = 0.0 self.frac_traceless = 1
def __init__(self, atoms, timestep, temperature=None, friction=None, fixcm=True, *, temperature_K=None, trajectory=None, logfile=None, loginterval=1, communicator=world, rng=None, append_trajectory=False): """ Parameters: atoms: Atoms object The list of atoms. timestep: float The time step in ASE time units. temperature: float (deprecated) The desired temperature, in electron volt. temperature_K: float The desired temperature, in Kelvin. friction: float A friction coefficient, typically 1e-4 to 1e-2. fixcm: bool (optional) If True, the position and momentum of the center of mass is kept unperturbed. Default: True. rng: RNG object (optional) Random number generator, by default numpy.random. Must have a standard_normal method matching the signature of numpy.random.standard_normal. logfile: file object or str (optional) If *logfile* is a string, a file with that name will be opened. Use '-' for stdout. trajectory: Trajectory object or str (optional) Attach trajectory object. If *trajectory* is a string a Trajectory will be constructed. Use *None* (the default) for no trajectory. communicator: MPI communicator (optional) Communicator used to distribute random numbers to all tasks. Default: ase.parallel.world. Set to None to disable communication. append_trajectory: boolean (optional) Defaults to False, which causes the trajectory file to be overwriten each time the dynamics is restarted from scratch. If True, the new structures are appended to the trajectory file instead. The temperature and friction are normally scalars, but in principle one quantity per atom could be specified by giving an array. RATTLE constraints can be used with these propagators, see: E. V.-Eijnden, and G. Ciccotti, Chem. Phys. Lett. 429, 310 (2006) The propagator is Equation 23 (Eq. 39 if RATTLE constraints are used) of the above reference. That reference also contains another propagator in Eq. 21/34; but that propagator is not quasi-symplectic and gives a systematic offset in the temperature at large time steps. """ if friction is None: raise TypeError("Missing 'friction' argument.") self.fr = friction self.temp = units.kB * self._process_temperature( temperature, temperature_K, 'eV') self.fixcm = fixcm # will the center of mass be held fixed? self.communicator = communicator if rng is None: self.rng = np.random else: self.rng = rng MolecularDynamics.__init__(self, atoms, timestep, trajectory, logfile, loginterval, append_trajectory=append_trajectory) self.updatevars()
def __init__(self, atoms, timestep, temperature, lattice_friction, simulation_number, fixcm=True, trajectory=None, logfile=None, loginterval=1, communicator=world, rng=np.random): """ The number of POSCAR file with initial conditions, also how many lattice atoms are frozen""" self.simulation_number = str(simulation_number) self.frozen_lattice = 8. """ How often should the height of molecules be checked, on what height to freeze """ self.freeze_interval = 50 self.freeze_height = 17.0 self.freeze_counter = 0 """ Load timestep and C and O masses in atomic units""" self.timestep = timestep self.C_mass = 12. self.O_mass = 16. """ Read temperatures from T_el_ph.dat into 1D arrays and generate interpolated functions""" temperature_file = np.loadtxt(temperature) temp_t = temperature_file[:, 0] * units.fs temp_el = temperature_file[:, 1] * units.kB temp_ph = temperature_file[:, 2] * units.kB self.interpolated_el_temp = interpolate.interp1d(temp_t, temp_el, kind='cubic') self.interpolated_ph_temp = interpolate.interp1d(temp_t, temp_ph, kind='cubic') """ Parameters for fitted density function """ self.a = 0.203631 self.b = 2.43572093 self.c = 1.71554638 self.d = 3.7611108 self.cutoff = 100. """Make empty arrays for the coefficients """ # find journal reference self.natoms = atoms.get_number_of_atoms() self.c1 = self.c2 = self.c3 = self.c4 = self.c5 = np.zeros(self.natoms) """ Get indices of adsorbate and surface atoms """ self.symbols = np.asarray(atoms.get_chemical_symbols(), dtype=str) self.C_indices = np.flatnonzero(self.symbols == 'C') self.O_indices = np.flatnonzero(self.symbols == 'O') self.lattice_indices = np.flatnonzero(self.symbols == 'Pd') self.adsorbate_indices = np.concatenate( (self.C_indices, self.O_indices)) self.adsorbate_number = len(self.adsorbate_indices) self.lattice_number = len(self.lattice_indices) """ Make empty arrays for atom temperatures and atom frictions. """ self.T = np.zeros(self.natoms) self.friction = np.zeros(self.natoms) """ Set friction for surface atoms immediately since it is constant during the simulation """ np.put(self.friction, self.lattice_indices, lattice_friction) """ Get atomic masses """ self.mass = atoms.get_masses() """ Friction conversion factor from a.u. to ase units """ self.conversion_factor = 0.02267902937 / units.fs self.fixcm = fixcm # will the center of mass be held fixed? self.communicator = communicator self.rng = rng MolecularDynamics.__init__(self, atoms, timestep, trajectory, logfile, loginterval) self.updatevars()
def __init__(self, atoms, timestep, temperature=None, taut=None, fixcm=True, *, temperature_K=None, trajectory=None, logfile=None, loginterval=1, communicator=world, append_trajectory=False): """Berendsen (constant N, V, T) molecular dynamics. Parameters: atoms: Atoms object The list of atoms. timestep: float The time step in ASE time units. temperature: float The desired temperature, in Kelvin. temperature_K: float Alias for *temperature* taut: float Time constant for Berendsen temperature coupling in ASE time units. fixcm: bool (optional) If True, the position and momentum of the center of mass is kept unperturbed. Default: True. trajectory: Trajectory object or str (optional) Attach trajectory object. If *trajectory* is a string a Trajectory will be constructed. Use *None* for no trajectory. logfile: file object or str (optional) If *logfile* is a string, a file with that name will be opened. Use '-' for stdout. loginterval: int (optional) Only write a log line for every *loginterval* time steps. Default: 1 append_trajectory: boolean (optional) Defaults to False, which causes the trajectory file to be overwriten each time the dynamics is restarted from scratch. If True, the new structures are appended to the trajectory file instead. """ MolecularDynamics.__init__(self, atoms, timestep, trajectory, logfile, loginterval, append_trajectory=append_trajectory) if taut is None: raise TypeError("Missing 'taut' argument.") self.taut = taut self.temperature = self._process_temperature(temperature, temperature_K, 'K') self.fix_com = fixcm # will the center of mass be held fixed? self.communicator = communicator
def __init__(self, atoms, timestep, temperature_K, andersen_prob, fixcm=True, trajectory=None, logfile=None, loginterval=1, communicator=world, rng=random, append_trajectory=False): """" Parameters: atoms: Atoms object The list of atoms. timestep: float The time step in ASE time units. temperature_K: float The desired temperature, in Kelvin. andersen_prob: float A random collision probability, typically 1e-4 to 1e-1. With this probability atoms get assigned random velocity components. fixcm: bool (optional) If True, the position and momentum of the center of mass is kept unperturbed. Default: True. rng: RNG object (optional) Random number generator, by default numpy.random. Must have a random_sample method matching the signature of numpy.random.random_sample. logfile: file object or str (optional) If *logfile* is a string, a file with that name will be opened. Use '-' for stdout. trajectory: Trajectory object or str (optional) Attach trajectory object. If *trajectory* is a string a Trajectory will be constructed. Use *None* (the default) for no trajectory. communicator: MPI communicator (optional) Communicator used to distribute random numbers to all tasks. Default: ase.parallel.world. Set to None to disable communication. append_trajectory: bool (optional) Defaults to False, which causes the trajectory file to be overwritten each time the dynamics is restarted from scratch. If True, the new structures are appended to the trajectory file instead. The temperature is imposed by stochastic collisions with a heat bath that acts on velocity components of randomly chosen particles. The algorithm randomly decorrelates velocities, so dynamical properties like diffusion or viscosity cannot be properly measured. H. C. Andersen, J. Chem. Phys. 72 (4), 2384–2393 (1980) """ self.temp = units.kB * temperature_K self.andersen_prob = andersen_prob self.fix_com = fixcm self.rng = rng if communicator is None: communicator = DummyMPI() self.communicator = communicator MolecularDynamics.__init__(self, atoms, timestep, trajectory, logfile, loginterval, append_trajectory=append_trajectory)
def todict(self): d = MolecularDynamics.todict(self) d.update({'temperature': self.temp, 'friction': self.fr, 'fix-cm': self.fixcm}) return d
def todict(self): d = MolecularDynamics.todict(self) d.update({'temperature_K': self.temp / units.kB, 'friction': self.fr, 'fixcm': self.fix_com}) return d